API
Monitoring
Balances

⚖️ Balances

Keep your nodes balances in check!

Overview

Amboss provides a balance reporting service where users can push balances to an Amboss endpoint and we will keep track of their overall node balances.

With balances, Amboss can provide:

  • Notifications for balances
  • Data visualizations of historical balances
  • Additional liquidity services

API

In the Amboss API, a query is available where you can push your balances to.

Query

💡

This query does not require authentication but does need a signature from your node.

mutation PushNodeBalances($input: ChannelBalancePushInput!) {
  pushNodeBalances(input: $input)
}

The query has some required and optional fields in the input object.

Required Inputs

  • timestamp: an ISO formatted date of when the query is run.
  • signature: The signature of the payload from the node.

Optional Inputs

These are all optional, but at least one is required for the endpoint to work.

  • onchainBalance
  • pendingChannelBalance
  • channels: Does not work if channelBalance is specified
  • channelBalance: Does not work if channels is specified
Examples
  • If you wanted to push only your onchain balances you would provide: onchainBalance
  • If you wanted to push only your general channel balances you would provide: channelBalance
  • If you wanted to push your complete channel list with their balances you would provide: channels

Inputs

timestamp

The timestamp should be the current UTC time in ISO format. You can see an example of this time format here (opens in a new tab).

💡
UTC time in ISO format example: 2022-07-04T13:31:55+0000

signature

You must sign a specific payload with your node and provide the signature. See the Signing the Payload section for more details.

onchainBalance

With the onchainBalance field you can provide the following information:

{
    confirmed: string, // Your confirmed onchain balance in sats
    pending: string // Your pending onchain balance in sats
}

pendingChannelBalance

With the pendingChannelBalance field you can provide the following information:

{
    local: string, // Your pending local Lightning balance in sats
    total: string // Your total pending Lightning balance in sats
}

channelBalance

Only if channels is not specified.

With the channelBalance field you can provide the following information:

{
    local: string, // Your local Lightning balance in sats
    total: string // Your total Lightning balance in sats
}

channels

Only if channelBalance is not specified.

With the channels field you can provide an array of the following information:

{
    chan_id: string, // The short or long channel id
    balance: string // The local balance you have in this channel
    capacity: string // The capacity of this channel
}
💡
The channels field is expecting an array.

Signing the Payload

The query expects a signature from your node of the payload in a specific format depending on which are the fields you are pushing.

To get the payload you need to sign follow these steps in order and replace the [...] with the values you are providing:

InitialString = timestamp in UTC format
 
if (you provide onchainBalance) {
    Add `[onchainBalance.confirmed][onchainBalance.pending]` to the InitialString.
}
 
if (you provide pendingChannelBalance) {
    Add `[pendingChannelBalance.local][pendingChannelBalance.total]` to the InitialString.
}
 
if (you provide channelBalance) {
    Add `[channelBalance.local][channelBalance.total]` to the InitialString.
}
 
if (you provide channels) {
    1. Sort the channels by the `chan_id` in descending order.
    2. Create the following string from the ordered channel list:
        `[chan01.chan_id][chan01.balance][chan01.capacity][chan02.chan_id][chan02.balance]...`
    3. Create a SHA256 hash of the previous string
    4. Add `[SHA256HashOfChannels]` to the InitialString.
}
💡

You can try this (opens in a new tab) SHA256 tool to hash the string.

Signing

Once you have the final InitialString you can sign this with your node and provide the signature inside the payload signature field.

Examples

Result 1

If you create the payload string correctly this is an example of what it should look like if you are providing onchainBalance, pendingChannelBalance and channels:

// Query Payload
{
    timestamp: "2022-07-04T13:31:55+0000",
    onchainBalance: {
        confirmed: "10000000",
        pending: "50000"
    },
    pendingChannelBalance: {
        local: "20000",
        total: "2000000"
    },
    channels: [
        {
            chan_id: "620857x937x0"
            balance: "69000"
            capacity: "10000000"
        },
        {
            chan_id: "633778x1065x0"
            balance: "420000"
            capacity: "5000000"
        }
    ]
}
 
// Payload string with placeholders
[timestamp][onchainBalance.confirmed][onchainBalance.pending][pendingChannelBalance.local][pendingChannelBalance.total][SHA256HashOfChannels]
 
// Channels string that would be hashed
"633778x1065x04200005000000620857x937x06900010000000"
 
// Hashed channels string
"31a9b7cf64a4e53fb0f824b96605aacdc57841e89862007ea6b777e55823430e"
 
// Payload string with values that needs signing
"2022-07-04T13:31:55+0000100000005000020000200000031a9b7cf64a4e53fb0f824b96605aacdc57841e89862007ea6b777e55823430e"
Result 2

If you create the payload string correctly this is an example of what it should look like if you are providing onchainBalance, pendingChannelBalance and channelBalance:

// Query Payload
{
    timestamp: "2022-07-04T13:31:55+0000",
    onchainBalance: {
        confirmed: "10000000",
        pending: "50000"
    },
    pendingChannelBalance: {
        local: "20000",
        total: "2000000"
    },
    channelBalance: {
        local: "15000000",
        total: "500000000"
    }
}
 
// Payload string with placeholders
"[timestamp][onchainBalance.confirmed][onchainBalance.pending][pendingChannelBalance.local][pendingChannelBalance.total][channelBalance.local][channelBalance.total]"
 
// Payload string with values that needs signing
"2022-07-04T13:31:55+0000100000005000020000200000015000000500000000"

End Result

Once you have finished the payload, this is what the query would look like:

Query in JSON format

{
  "query": "mutation PushNodeBalances($input: ChannelBalancePushInput!) { pushNodeBalances(input: $input)}",
  "variables": {
    "timestamp": "2022-07-04T13:31:55+0000",
    "signature": "[SIGNED PAYLOAD FROM YOUR NODE]",
    "onchainBalance": {
      "confirmed": "10000000",
      "pending": "50000"
    },
    "pendingChannelBalance": {
      "local": "20000",
      "total": "2000000"
    },
    "channelBalance": {
      "local": "15000000",
      "total": "500000000"
    }
  }
}