Reference: Lightning Balances

Overview

The Lightning Network operates fundamentally differently from traditional Bitcoin blockchain transactions. Understanding these differences is crucial for properly managing Lightning wallets.

Liquidity Network

On the Bitcoin blockchain, bitcoin balances exist in on-chain addresses. However, on the Lightning Network, Lightning bitcoin exist in payment channels between nodes within the liquidity network - an L2 built on top of the Bitcoin blockchain. Your ability to send or receive payments depends on the liquidity available within these channels.

This results in the following two types of liquidity:

  • Inbound liquidity - The capacity others have to send payments to you.
  • Outbound liquidity - The capacity you have to send payments to others

Both directions of liquidity exist simultaneously in the same channel.

Millisatoshi Precision

Lightning Network uses millisatoshis (msats) as its base unit, which is 1/1000th of a satoshi. This enables micro-payments that would be impractical on the Bitcoin blockchain. While the smallest unit of bitcoin is 1 satoshi (0.00000001 BTC), Lightning can handle payments as small as 0.001 satoshis.

State vs. Settlement

Lightning balances represent your current state in payment channels - not confirmed blockchain transactions. Channels can open and close on the Bitcoin blockchain, but the individual Lightning payments occur off-chain with near-instant finality.

Lightning Balance Fields

When you retrieve a Lightning wallet balance from BitGo, you see several fields that represent different aspects of your Lightning liquidity:

Inbound Balance Fields

"inboundBalance": "0",
"inboundPendingBalance": "0",
"inboundUnsettledBalance": "0"
  • inboundBalance - The total amount (in millisatoshis) you can receive through your Lightning channels. This represents your receiving capacity across all open channels.

  • inboundPendingBalance - The amount (in millisatoshis) currently being added to your inbound liquidity. For example, channels that are in the process of opening and will impact your receiving capacity.

  • inboundUnsettledBalance - The amount (in millisatoshis) from incoming payments you received, but haven't yet fully settled in the channel state.

Outbound Balance Fields

"outboundBalance": "0",
"outboundPendingBalance": "0",
"outboundUnsettledBalance": "0",
"outboundLockedBalance": "0",
"outboundReservedBalance": "0",
"outboundSpendableBalance": "0"
  • outboundBalance - The total amount (in millisatoshis) of off-chain funds that belong to you across all your open Lightning channels. This represents the off-chain assets you control. This value equals outboundReservedBalance + outboundSpendableBalance.

  • outboundPendingBalance - The amount (in millisatoshis) that's in the process of being added to your outbound liquidity. For example, in-progress deposits to channels that are still pending on-chain confirmation.

  • outboundUnsettledBalance - The amount (in millisatoshis) from outgoing payments that were sent, but not yet fully settled in the channel state.

  • outboundLockedBalance - The amount (in millisatoshis) locked from pending force closed channels. This represents your local balance that is temporarily locked during the force closure process.

  • outboundReservedBalance - The total outbound reserved balance (in millisatoshis) across your Lightning channels. This represents the portion of your local balance that is reserved and cannot be spent, typically held as a channel reserve requirement.

  • outboundSpendableBalance - The total outbound spendable balance (in millisatoshis) across your Lightning channels. This represents the portion of your local balance that you can actually spend in payments, excluding any reserved and locked amounts.

On-Chain Balance Fields

"balanceString": "0",
"confirmedBalanceString": "0",
"spendableBalanceString": "0"

These fields represent your on-chain bitcoin balance, separate from your Lightning channel liquidity:

  • balanceString - Your total on-chain bitcoin balance (in satoshis) in the wallet. This is the traditional balance on the Bitcoin blockchain - not Lightning channel funds.

  • confirmedBalanceString - The portion of your on-chain balance that has received sufficient blockchain confirmations and is considered fully settled (in satoshis).

  • spendableBalanceString - The amount of on-chain Bitcoin you can immediately withdraw (in satoshis). This can differ from the confirmed balance if there are any restrictions or reserved amounts.

Important - These on-chain balances are distinct from your Lightning channel balances (inboundBalance and outboundBalance). The on-chain balance represents bitcoin held in regular blockchain addresses, while Lightning balances represent funds locked in payment channels.

Total Balance Owned

Your total balance across the Lightning wallet is the sum of your on-chain Bitcoin and your Lightning channel funds:

Total Balance = balanceString + outboundBalance

Why this Calculation?

  • balanceString - Your on-chain bitcoin that you control.
  • outboundBalance - Your Lightning channel funds that you control. The outboundSpendableBalance and outboundReservedBalance represent how this balance is distributed (spendable vs reserved). You currently can't control all other outbound balances (outboundPendingBalance, outboundUnsettledBalance, outboundLockedBalance).

What About Inbound Balance?

The inboundBalance represents your capacity to receive payments, not assets you currently own. Inbound liquidity is capacity provided by your channel partners on their side of the channels. Only your outboundBalance represents Lightning assets you actually control.

Example:

{
  "confirmedBalanceString": "500_000",    // 0.005 BTC on-chain
  "outboundBalance": "1_000_000_000",     // 0.01 BTC in Lightning channels
  "inboundBalance": "2_000_000_000"       // 0.02 BTC receiving capacity (not yours)
}

In this example:

  • Total funds you own - 1,500,000 satoshis (0.015 BTC)
    • 500,000 sats on-chain
    • 1,000,000,000 milisats which is equal to 1,000,000 sats in Lightning channels
  • Receiving capacity - 2,000,000,000 milisats which is equal to 2,000,000 satoshis (not part of your balance)

Key Considerations

  • Bidirectional liquidity - Unlike traditional Bitcoin wallets, you must consider both your ability to send (outbound) and receive (inbound) funds.
  • Channel capacity - Your total channel capacity is the sum of inbound and outbound balance for each channel.
  • Rebalancing - You may need to rebalance channels to maintain optimal inbound and outbound liquidity for your use case.
  • Channel fees - Opening and closing channels involves on-chain Bitcoin transactions with associated fees.

Get Lightning Balance from BitGo

Endpoint: Get Wallet By ID

export BITGO_EXPRESS_HOST="<YOUR_LOCALHOST>"
export WALLET_ID="<YOUR_WALLET_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"

curl -X GET \
  https://$BITGO_EXPRESS_HOST/api/v2/wallet/$WALLET_ID \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $ACCESS_TOKEN" 
  const { BitGo } = require('bitgo');
  const accessToken = '<YOUR_ACCESS_TOKEN>';

  // Initialize the SDK
  const bitgo = new BitGo({
    accessToken: accessToken,
    env: 'test',
    customRootURI: 'https://app.bitgo-test.com',
  });

  // Enter your Lightning wallet
  const walletId = '<YOUR_WALLET_ID>'
  const existingWallet = await bitgo.coin('tlnbtc').wallets().get({ id: walletId });
  console.dir(existingWallet);

Step Result

In this example:

  • You can receive up to 500,000,000 mili-satoshis (500,000 satoshis) (0.005 BTC) off-chain.
  • Total off-chain funds belonging to you: 1,000,000,000 mili-satoshis (1,000,000 satoshis) (0.01 BTC).
  • Total off-chain reserved: 100,000,000 mili-satoshis (100,000 satoshis) (0.001 BTC).
  • Total off-chain spendable: 900,000,000 mili-satoshis (900,000 satoshis) (0.009 BTC).
  • Total on-chain funds belonging to you and available for withdrawal: 15,000,000 satoshis (0.15 BTC).
{
  ...
  offchain: {
    inboundBalance: '500_000_000',
    inboundPendingBalance: '0',
    inboundUnsettledBalance: '0',
    outboundBalance: '1_000_000_000',
    outboundPendingBalance: '0',
    outboundUnsettledBalance: '0',
    outboundLockedBalance: '0',
    outboundReservedBalance: '100_000_000',
    outboundSpendableBalance: '900_000_000'
  },
  balanceString: '15_000_000',
  confirmedBalanceString: '15_000_000',
  spendableBalanceString: '15_000_000',
  ...
}

See Also