BOLT11 Deposits and Withdrawals

Deposits and Withdrawals using the BOLT11 standard on the Lightning Network including generating and sending to invoices.

Note: “BTC” is the symbol used as Lightning Network does not have its own asset on the Zero Hash platform. The [destination_address] field will differentiate between the Bitcoin Network and a Lightning Network invoice based on the format of the address that is input.

Note: CERT uses Testnet for non-UMA Lightning Network transactions. REGTEST is currently used for UMA and will migrate to Testnet in the future. Adhere to these networks when testing CERT unless otherwise indicated such as with the testdeposit.


Network Fee Models and Withdrawing to Lightning Invoices

There are typically 2 Zero Hash configurations platforms choose for handling network fees:

  • Additive: When sending 0.5 BTC, the network fees will be added to the quantity so the platform/participant will be deducted 0.5BTC + fees and the recipient will receive the specified quantity 0.5 BTC. This setup works very well for defined Lightning Network invoices.
  • Netted: When sending 0.5 BTC, the network fees will be deducted from the quantity so the platform/participant will be deducted 0.5 BTC and the recipient will receive 0.5 BTC - fees. This setup can result in dynamic amounts being deducted which can make paying a defined Lightning Network invoice quantity more difficult.

When sending to BOLT11 invoices external to Zero Hash, the invoices should be generated by the default manner which is a “0 Amount” or undefined amount. This way, regardless of the network fee model your platform employs, the invoice will be accepted.

If the receiving invoice was generated with a fixed amount (i.e. 1000 satoshis), then only the additive model will send the exact amount. If using the netted model, due to dynamic fees it is possible but more complex to estimate the additional amount that needs to be added to make the invoice match the exact amount. There is a validation in-place that will return an error if the netted amount does not equal the destination invoice when an amount is defined.


Estimate Network Fee for a Withdrawal

To estimate the cost to send BTC to an invoice, call GET /withdrawals/estimate_network_fee

Request:

curl --request GET  
     --url '<https://api.cert.zerohash.com/withdrawals/estimate_network_fee?underlying=BTC"&quoted_currency=USD&contract_call=true'>  
     --header 'X-SCX-SIGNED: [WEB] auto-generated on fly'  
     --header 'X-SCX-TIMESTAMP: [WEB] auto-generated on fly'  
     --header 'accept: application/json'

Response:

{  
  "message": {  
    "underlying": "BTC",  
    "quoted_currency": "USD",  
    "network_fee_asset": "BTC",  
    "network_fee_quantity": "0.00012345",  
    "total_notional": "2.867469544894346440"  
  }  
}

Per the note above, BTC will be the symbol that is used. Inputting a Lightning Network invoice will signal that the intended network is the Lightning Network vs an L1 Bitcoin Network address.

Two different estimate calls can be made to compare the cost of a withdrawal between networks. For example, the first call would provide an L1 address and the second one a Lightning Network address. A platform’s logic can then decide which network to use or present the options to an end customer via the UI.


Lightning Network BTC Withdrawals (BOLT11)

To send BTC to a Lightning Network invoice, first lock a network fee and return a quote ID by calling GET /withdrawals/locked_network_fee

To execute a locked quote, then call POST /withdrawals/execute. The destination address should be an invoice address to identify the transaction as one that should be sent on the Lightning Network.


Lightning Network Convert_Withdraw (BOLT11)

Convert_withdraw can be used to convert fiat to BTC then withdraw to a Lightning invoice.

Convert_withdraw can be specified to use ByTotal or ByQuantity. For Lightning Network invoices, only ByQuantity is allowed due to invoice amounts being fixed.

Otherwise, usage of convert_withdraw for Lightning Network will follow this guide.

  • Get RFQ quote using POST /convert_withdraw/rfq
  • Execute the Quote by calling POST /convert_withdraw/execute

For Lightning Network withdrawals, the destination address must be a BOLT11 Lightning Invoice format.


Transaction Limits and Controls (BOLT11 / LNURL)

Transaction limits are being implemented on August 21, 2024 for Lightning Network transactions. The limits will vary depending on the direction of the transaction.


TransactionControl DescriptionControl
WithdrawalsAggregate Transaction Daily Maximum Amount$2,500 daily limit
WithdrawalsMinimum Transaction1 satoshi
DepositsInvoice Maximum Amount$1,000 USD per invoice
DepositsInvoice Daily Maximum$1,000 USD per day
DepositsLifetime volume triggering Enhanced Due DiligenceTier 1:
At $10k cumulative deposit volume, require additional EDD information to be sent.

Tier 2:
At $100k deposit volume in rolling 30 days, participant will trigger manual review

Lightning Network Deposits (BOLT11)

To receive a deposit, first use the endpoint POST /deposits/bolt11 to generate an invoice.

{
    "amount": "0.000001",
    "account_label": "",
    "participant_code": "",
    "platform_code": ""
}

Note that invoices can be generated with a set amount or with a “0” amount which does not have a defined value. If generating a 0 amount invoice, note that any amount in excess of the limits in the prior section will be rejected.

encoded_invoice (String)  
         The invoice you want to be paid (as defined by the BOLT11 standard)  

expiration_time (String)  
         Max time for the invoice be paid before it expires

There is an optional boolean parameter test_mode that can be used only in CERT to denote that the transaction will only be used for simulation purposes. More details regarding this functionality are in the section below.

Testing BOLT11 Deposits in CERT

To test the above deposit flow, you can use the POST /deposits/bolt11/test_payment to simulate a CERT deposit. This endpoint accepts a test invoice and simulates the transaction.

Note: The generated invoice will not be able to be paid using an external service and will only be available for sandbox testing within Zero Hash's CERT environment. For that reason, this transaction will not show up in other Zero Hash system calls such as GET /deposits as it is only intended to show if a transaction would be accepted.