Comment on page
Using Flow 2.0
Learn more to use our Flow 2.0 LSP to effortlessly manage liquidity.
Because our LSP uses Zero Conf channels, most nodes require some additional set up. Find your node implimentation below to learn how to properly prepare your node for Zero Conf channels.
First, run your LND node with two additional flags for zero-conf compatibility:
protocol.option-scid-alias=true
protocol.zero-conf=true
If you're running LND on Voltage, you can enable these options on the Settings page.
Clone our zero-conf LND daemon at the zero-conf-lnd repository. (Requires the Rust toolchain installed to compile)
Create a
config.yml
file that points that looks like this:lnd:
macaroon_location: "~/.lnd/data/chain/bitcoin/mainnet/admin.macaroon"
cert_location: "~/.lnd/tls.cert"
host: "127.0.0.1"
port: 9735
channel_acceptance:
- pubkey: "025804d4431ad05b06a1a1ee41f22fefeb8ce800b0be3a92ff3b9f594a263da34e"
confs: 0
Build the daemon and run it with the following command:
./zero-conf-lnd config.yml
Your node should now be able to accept zero-conf channels from us, as long as the daemon is running.
Run a testnet CLN node with the following flags included:
--plugin=/path/to/cln-plugin/zeroconf-selective.py \
--zeroconf-allow=025804d4431ad05b06a1a1ee41f22fefeb8ce800b0be3a92ff3b9f594a263da34e
Your node should now be able to accept zero-conf channels from us.
Our service works with LDK, but since each LDK use case is different it will take more manual integration to get it working.
You can try out the LSP using our dashboard here:
Testnet: https://testnet-lsp.voltageapi.com
Response
{
"connection_methods": [
{
"address": "44.228.24.253",
"port": 9735,
"type": "ipv4"
},
{
"address": "jmoarfvtn3sdvqedmbl4t7jwveozbmpsjadiqakvluzomwey3zslrbad.onion",
"port": 9735,
"type": "torv3"
}
],
"pubkey": "025804d4431ad05b06a1a1ee41f22fefeb8ce800b0be3a92ff3b9f594a263da34e"
}
Request
{
"amount_msat":100000000,
"pubkey":"027e6e...274e"
}
Response
{
"amount_msat": 2500000 #Fee amount in msats, charged in the wrapped invoice
"id": "81cece1f-07b0-4d78-ab92-9a1968e78d30" #ID to reference this fee rate when requesting a wrapped invoice
}
Request
{
"bolt11":"lntb1...", #Original Lightning invoice from the client
"host":"1.2.3.4", #Optional Host connection information for the client. Not needed if client peers to the LSP first.
"port": 9735 #Optional Port connection information for the client. Not needed if client peers to the LSP first.
"fee_id": "81ec...d30" #Optional fee rate received from the /fee endpoint. If not present, the LSP calculates the fee in the wrapped invoice.
}
Response
{
"jit_bolt11": "lntb5..." #Wrapped Bolt11 invoice which can be sent to the sender for payment
}
You can use our UI to manually submit invoices for wrapping, but if you'd like to integrate Flow v2 into your service or wallet, you'll probably want to do this automatically.
The API has a single endpoint,
/api/v1/proposal
, which accepts a POST request with a JSON body of the invoice (required), and your node's host and port (optional)NOTE: When making the initial invoice to receive a payment which needs a channel opened, we recommend a minimum invoice amount of 50,000 sats.
Curl example
curl --header "Content-Type: application/json" \
--request POST \
--data '{"bolt11":"lntb1...","host":"abc...123.onion", "port": 9735}' \
https://testnet-lsp.voltageapi.com/api/v1/proposal
{
"jit_bolt11": "lntb5..."
}
Javascript example
await fetch(`https://testnet-lsp.voltageapi.com/api/v1/proposal`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
bolt11: "lntb1...",
host: "abc...123.onion",
port: 9735
})
});
If your node is already connected to our node you don't need to pass your host and port information. This is especially useful for mobile wallets that might not have a public IP.
Here's the testnet connection info you need to peer to our node:
Testnet LSP node pubkey
025804d4431ad05b06a1a1ee41f22fefeb8ce800b0be3a92ff3b9f594a263da34e
Testnet IPV4
44.228.24.253:9735
Testnet TORV3
jmoarfvtn3sdvqedmbl4t7jwveozbmpsjadiqakvluzomwey3zslrbad.onion:9735
By default, the sender would be the one paying all fees because we add on the Voltage fee to the amount we receive in the original invoice. However, you can pay the service fee yourself (or split it between you and the user) but generating an invoice that is the amount due minus the Voltage fee.
For example, lets assume the receiver is expecting a payment of 100,000 sats and the Voltage fee is 5,000 sats. By default, the wrapped invoice generated from LSP would be for 105,000 sats which would mean the sender is paying for the channel open cost. Instead, we don't want the sender to pay the fee, so the receiver would generate an invoice for 95,000 sats. This would mean the Voltage LSP would return a wrapped invoice of 100,000 sats. This way the sender is paying the expected amount and the receiver pays the service fee.
You can use the Fee API (
/api/v1/fee)
to estimate what the fee is for a given payment from the LSP in order to generate the proper amount in the invoice:curl --header "Content-Type: application/json" \
--request POST \
--data '{"amount_msat":100000000,"pubkey":"027e6e...274e"}' \
https://testnet-lsp.voltageapi.com/api/v1/fee
{
"amount_msat": 2500000,
"id": "81cece1f-07b0-4d78-ab92-9a1968e78d30"
}
The returned value would be the LSP fees in millisatoshis. This API also returns an ID for the fee rate. You can pass in this ID to the
/proposals
endpoint to ensure this exact fee is used by the LSP. Fee rates expire after 10 minutes.Flow 2.0 has a dynamic fee structure. When requesting a fee rate, we look at the current mempool to estimate the onchain fee of the channel open. We use this fee in combination with the Voltage fee to present the final rate. Our LSP currently charges the follow fees:
Onchain Fee: Estimated directly from the mempool.
Base Fee: 1000 sats
Payment PPM: 500
Last modified 5d ago