Skip to content

Instantly share code, notes, and snippets.

@vladimirfomene
Last active October 25, 2023 08:00
Show Gist options
  • Save vladimirfomene/6c947cf7ec598d8b2fbf6956a9a071d2 to your computer and use it in GitHub Desktop.
Save vladimirfomene/6c947cf7ec598d8b2fbf6956a9a071d2 to your computer and use it in GitHub Desktop.

Splice Backend API Documentation

This documentation outlines the API endpoints for onboarding, on/off ramps and cross border payment across currencies.

Generate a New Wallet

  • Endpoint: POST api/wallets

For a new wallet, a phone number with country code is required. With this information, a new walletID with a fiat and bitcoin balance and also a lightning address. Every new wallet will be allocated some KES/Naira and BTC. This is to ease testing.

  • Request
{
  "phoneNumber": "<tel number with country code>",
  "withdrawalFee": "<agent needs to set withdrawal fee in frontend>",
  "preferredFiatCurrency": "NGN or KES"
}
  • Response:
{
  "walletId": "<uuid>",
  "lightingAddress": "<phoneNumber>@splice.africa",
  "withdrawalFee": 5,
  "balances": [
    {
      "amount": 100000.0,
      "currency": "KES"
    },
    {
      "amount": 5.0,
      "currency": "BTC"
    }
  ]
}

Retrieve Wallet Information

  • Endpoint: GET api/wallets/{walletID}
  • Response:
{
  "walletId": "1234567890abcdef",
  "lightingAddress": "<phonenumber>@splice.africa",
  "withdrawalFee": 5,
  "balances": [
    {
      "amount": 100000.0,
      "currency": "KES"
    },
    {
      "amount": 5.0,
      "currency": "BTC"
    }
  ]
}

Sending/Receiving money cross border

  1. Precious (Nigeria) Initiates the Payment:
  • Precious asks Sabina (Kenya) to provide the Lightning Network address of the merchant or agent from whom she will withdraw the money.
  1. Precious Visits a Local Merchant/Agent:
  • Precious goes to a local merchant or agent in Nigeria.
  1. Precious Requests a Payment to Sabina:
  • Precious tells the local merchant/agent that he wants to send a specific amount in Kenyan Shillings (KES) to Sabina.
  1. Merchant/Agent Requests an Invoice:
  • The local merchant/agent requests an invoice from the backend system.
  1. Backend System Processes the Invoice Request:
  • The backend system receives the invoice request and retrieves the requested amount (to be received) from the payload. It adds Sabina's merchant withdrawal fee and network fee to the amount. The backend generates an invoice, often referred to as a "Tapd address," for the total calculated amount.
  1. Naira Equivalent Calculation:
  • The backend calculates the equivalent amount in Nigerian Naira (NGN) that Precious's agent will need to pay for the transaction using the KES/NGN exchange rate.
  1. Display the Amount on the Frontend:
  • The backend displays the calculated NGN amount on the frontend for Precious's agent to see.
  1. Precious's Agent Makes the Payment:
  • Precious's agent makes the payment in NGN to the local merchant/agent.
  1. Backend Deducts NGN from Agent's Balance:
  • The backend deducts the calculated NGN amount from Precious' agent's balance.
  1. Sabina's Agent Receives KES:
  • The backend credits Sabina's agent with the equivalent amount in KES.
  1. Payment of the Tapd Invoice/Address:
  • The backend also pays the Tapd invoice/address using the Lightning Network.
  1. Proof of Payment:
  • Precious's agent receives a proof of payment, which can be shared with Sabina.
  1. Sabina Claims the Payment:
  • Sabina shows the proof of payment to her local agent in Kenya. Sabina's agent, upon verifying the proof of payment, allows Sabina to receive the held payment.

In this process, it's crucial to use "hodl invoices," which are invoices that require the recipient to perform an action (e.g., provide a preimage) before the payment is complete. This ensures that Sabina's agent can claim the payment only when they are provided with the proof of payment.


Send & Receive with Currency Conversion

1. Invoice Request

Precious' agent request an invoice belonging Sabina's agent

  • Endpoint: POST api/invoices
  • Request:
{
  "destionationAddress": "<phonenumber>@splice.africa",
  "amount": <float>,
  "currency": "KES"
}
  • Response:
{
  "destinationAddress": "<phonenumber>@splice.africa",
  "amount": 100,
  "currency": "NGN",
  "tapdAddress": "<tapd address/invoice>",
}

2. Pay Invoice

Precious' agent pays invoice belonging to Sabina's agent.

  • Endpoint: POST api/invoices/send
  • Request:
{
  "sourceAddress": "<Precious' agent lightning address>",
  "amount": 100,
  "currency": "NGN",
  "destinationAddress": "<Sabina's agent lightning address>",
  "tapdAddress": "<tapd address/invoice>",
}
  • Response:
{
  "proofOfPayment": "transaction id",
  "amount": 100,
  "currency": "NGN",
  "destinationAddress": "<Sabina's agent lightning address>",
}

3. Claiming Payment

Sabina's agent check Sabina's proof of payment before payment release.

  • Endpoint: GET api/proof/<txid>
  • Response:
{
 "succeeded": true
}

On/Off Ramps

On Ramp

Vlad approaches a merchant/agent with the intention of purchasing Bitcoin (BTC) for a specified amount in Kenyan Shillings (KES). The merchant/agent inputs the KES/BTC exchange rate and the KES amount into the frontend and then requests the backend to calculate the BTC equivalent after deducting network fees. Subsequently, the merchant/agent presents this information to Vlad. If Vlad agrees to the terms, he generates an invoice, which he provides to the agent. Following this, the agent proceeds to make a payment to Vlad's Bitcoin account. As a result, the agent's KES account is debited, while Vlad's BTC account is credited. Notably, in this real-time transaction, there is no requirement for proof of payment.

1. Get exchange rate for bitcoin.

Agent can get exchange rate from the frontend.

  • Endpoint: GET api/rate/<source (e.g kes)>/<destination (e.g btc)>
  • Response:
{
   "rate": 0.001
}

2. Calculate bitcoin amount

Agent will show amount in btc Vlad will get on purchase.

  • Endpoint: POST api/on/calculate
  • Request:
{
  "rate": 0.01,
  "amount": 1000,
  "source": "KES",
  "destination": "BTC"
}
  • Response:
{
 "amount": 0.1,
 "currency": "BTC"
}

3. Vlad generates invoice

  • Endpoint: POST api/on/invoices
  • Request:
{
  "amount": 0.1,
  "currency": "BTC"
}
  • Response:
{
 "destionationAddress": "<Tapd address>",
}

4. Agent Sends BTC

  • Endpoint: POST api/on/invoices/pay
  • Request:
{
  "lightningAddress": "<user's lightning address>",
  "amount": 0.01,
  "currency": "BTC",
  "destionationAddress": "<Tapd address>",
}
  • Response:
{
 "paymentId": "<payment id>",
 "Status": "Payment successful",
}

Off Ramp

Simon approaches a merchant/agent with the intention of selling a specified amount of Bitcoin (BTC) for Kenyan Shillings (KES). The merchant/agent enters the BTC/KES exchange rate and the BTC amount into the frontend and subsequently requests the backend to calculate the KES equivalent after deducting network fees. The merchant then presents this information to Simon. If Simon agrees to the terms, the merchant/agent generates an invoice and requests Simon to make the payment. Simon proceeds to pay the invoice, resulting in a credit to the merchant/agent's account. Once the merchant/agent receives the Bitcoins, they provide Simon with the equivalent amount in KES. Notably, in this real-time transaction, there is no requirement for proof of payment.

( Similar to on ramp steps difference is the agent generating invoice)

@crukundo
Copy link

crukundo commented Oct 19, 2023

Suggestion here on On ramps:
Instead of "As a result, the agent's KES account is debited ..." perhaps it should say that "Vlad hands cash to the agent/merchant, while Vlad's lightning wallet is credited ..."

@vladimirfomene
Copy link
Author

Suggestion here on On ramps: Instead of "As a result, the agent's KES account is debited ..." perhaps it should say that "Vlad hands cash to the agent/merchant, while Vlad's lightning wallet is credited ..."

Right right

@vladimirfomene
Copy link
Author

It won't be great to use hodl invoices. As it will keep many inflight htlcs on the network. There is an htlc limit per channel. We should wait for asyc payments. LDK is working on an implementation of this by the way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment