# Wallet Balance

`swapper.Utils` exposes fee-aware balance helpers for both smart chain wallets and Bitcoin wallets.

These helpers are meant for swap UIs and "Max" buttons. Unlike a raw RPC balance, they estimate how much can actually be used in a swap without leaving too little for network fees. This is especially important for the exact-input flows described in [Creating Quotes](https://docs.atomiq.exchange/sdk-guide/quick-start/creating-quotes.md) and [Executing Swaps](https://docs.atomiq.exchange/sdk-guide/quick-start/executing-swaps.md).

* use [`getSpendableBalance()`](https://docs.atomiq.exchange/sdk-reference/api/atomiq-sdk/src/classes/SwapperUtils#getspendablebalance) for smart chain wallet balances.
* use [`getBitcoinSpendableBalance()`](https://docs.atomiq.exchange/sdk-reference/api/atomiq-sdk/src/classes/SwapperUtils#getbitcoinspendablebalance) for Bitcoin on-chain wallet balances.

The returned balances use the [`TokenAmount`](https://docs.atomiq.exchange/sdk-reference/api/atomiq-sdk/src/type-aliases/TokenAmount) object type which makes it easy to show the balance in human-readable format, get the raw token amount or estimate the USD value of the amount.

* Smart chain
* Bitcoin

Use [`SwapperUtils.getSpendableBalance()`](https://docs.atomiq.exchange/sdk-reference/api/atomiq-sdk/src/classes/SwapperUtils#getspendablebalance) to get the spendable balance of a smart chain (i.e. Solana, Starknet, etc.) wallet, as is the case in the [Smart Chain → BTC/Lightning](https://docs.atomiq.exchange/sdk-guide/swaps/smart-chain-to-btc.md) flow. For native tokens such as `SOL`, `STRK` or the native token of an EVM chain, the SDK automatically deducts the estimated fee required to initiate the swap. The returned amount is therefore safe to use as a "Max" amount for exact-input swaps.

```
const strkBalance = await swapper.Utils.getSpendableBalance(

  starknetSigner,

  Tokens.STARKNET.STRK,

  {

    feeMultiplier: 1.1 // Optionally keep an extra 10% fee buffer

  }

);



console.log("Spendable balance:", strkBalance.toString());
```

For non-native tokens such as `WBTC`, transaction fees are paid in the native token of the chain, so the token balance itself is usually fully spendable. You can use the [`hasEnoughForTxFees()`](https://docs.atomiq.exchange/sdk-reference/api/atomiq-sdk/src/classes/IToBTCSwap#hasenoughfortxfees) function to check if the source wallet has enough native token balance to cover the transaction fees for initiating the swap.

```
// Check if a ToBTCSwap or ToBTCLNSwap can be initiated

const {enoughBalance, balance, required} = await swap.hasEnoughForTxFees();

if (!enoughBalance) {

  console.log(`The source wallet has insufficient balance to execute the swap, required: ${required.toString()}, balance: ${balance.toString()}`);

}
```

warning

A large non-native token balance does not guarantee that the swap can be initiated. The wallet still needs enough native gas token balance. This matters even more in the legacy Solana flows, where even the destination side requires SOL for deposits or transaction fees. See [Bitcoin → Solana](https://docs.atomiq.exchange/sdk-guide/swaps/solana/btc-to-solana.md) and [Lightning → Solana](https://docs.atomiq.exchange/sdk-guide/swaps/solana/lightning-to-solana.md).

Use [`SwapperUtils.getBitcoinSpendableBalance()`](https://docs.atomiq.exchange/sdk-reference/api/atomiq-sdk/src/classes/SwapperUtils#getbitcoinspendablebalance) for Bitcoin on-chain source balances. This helper estimates the maximum sendable BTC amount after miner fees and takes the destination smart chain into account.

Swap destination chain matters for spendable balance estimation because [Bitcoin → Smart Chain](https://docs.atomiq.exchange/sdk-guide/swaps/btc-to-smart-chain.md) on Starknet/EVM uses the newer UTXO-controlled vault flow, while [Bitcoin → Solana](https://docs.atomiq.exchange/sdk-guide/swaps/solana/btc-to-solana.md) uses the legacy Solana flow with a different Bitcoin transaction footprint.

```
const {balance, feeRate} = await swapper.Utils.getBitcoinSpendableBalance(

  bitcoinWalletAddress,

  "STARKNET", // Swap destination chain

  {

    gasDrop: true, // When swapping with the "gas drop" feature, the Bitcoin transaction gets slightly larger

    minFeeRate: 2  // Optionally enforce a minimum sats/vB floor

  }

);



console.log("Spendable balance for BTC → STARKNET swaps:", balance.toString());

console.log("Using bitcoin fee rate:", feeRate, "sats/vB");
```

info

The `wallet` argument can be either a plain Bitcoin address string or a wallet object implementing [IBitcoinWallet](https://docs.atomiq.exchange/sdk-reference/api/atomiq-sdk/src/interfaces/IBitcoinWallet) or [MinimalBitcoinWalletInterface](https://docs.atomiq.exchange/sdk-reference/api/atomiq-sdk/src/type-aliases/MinimalBitcoinWalletInterface).

tip

If the user requests a gas drop in the [Bitcoin → Smart Chain](https://docs.atomiq.exchange/sdk-guide/swaps/btc-to-smart-chain.md#gas-drop) flow, be sure to pass `gasDrop: true` to `getBitcoinSpendableBalance()`, since requesting gas drop slightly increases the size of the Bicoin transaction.

## Swaps Using Max Balance

Spendable balance helpers are most useful for estimating maximum amount of a swap source token that can be used for `EXACT_IN`-mode swaps. To create a swap spending the full balance of a wallet you can use the following:

* Smart chain
* Bitcoin

```
import {SwapAmountType} from "@atomiqlabs/sdk";



// Get the spendable balance of the signer

const maxSpendable = await swapper.Utils.getSpendableBalance(

  starknetSigner,

  Tokens.STARKNET.STRK

);



// Create an EXACT_IN swap spending the full wallet balance

const swap = await swapper.swap(

  Tokens.STARKNET.STRK,

  Tokens.BITCOIN.BTC,

  maxSpendable.amount,

  SwapAmountType.EXACT_IN,

  starknetSigner.getAddress(),

  btcAddress

);
```

```
import {SwapAmountType} from "@atomiqlabs/sdk";



// Get the spendable balance of the signer

const {balance, feeRate} = await swapper.Utils.getBitcoinSpendableBalance(

  bitcoinWalletAddress,

  "STARKNET", // Use the proper swap destination chain

  {

    gasDrop: true // We also want to request a gas drop so set this to true

  }

);



// Create an EXACT_IN swap spending the full wallet balance

const swap = await swapper.swap(

  Tokens.BITCOIN.BTC,

  Tokens.STARKNET.WBTC,

  balance.amount,

  SwapAmountType.EXACT_IN,

  undefined,

  starknetSigner.getAddress(),

  {

    gasAmount: 1_000_000_000_000_000_000n // Also request a gas drop

  }

);
```

In the case of non-legacy **Bitcoin → Smart chain** swaps (*not* applicable to legacy **Bitcoin → Solana**) the LPs require a certain minimum fee rate to be used for the bitcoin transaction, this fee rate can be higher than the fee that was initially used to estimate balance, hence you might need to re-fetch the bitcoin balance using this new minimal fee rate:

```
if (swap.minimumBtcFeeRate > feeRate) {

  // Re-compute the maximum spendable spendable balance with the fee minimum

  const {balance, feeRate} = await swapper.Utils.getBitcoinSpendableBalance(

    bitcoinWalletAddress,

    "STARKNET", // Use the proper swap destination chain

    {

      gasDrop: true, // We also want to request a gas drop so set this to true

      minFeeRate: swap.minimumBtcFeeRate // Pass in the minimum fee rate from the created swap quote

    }

  );

  

  ... // Now get the quote using this adjusted amount

}
```

info

In your UI you can hook the `getBitcoinSpendableBalance()` and `getSpendableBalance` functions to recompute on state changes, i.e. if the source/destination chain types change or gas drop request is toggled.

## API Reference

* [SwapperUtils](https://docs.atomiq.exchange/sdk-reference/api/atomiq-sdk/src/classes/SwapperUtils) - Utility class exposed as `swapper.Utils`
* [getSpendableBalance](https://docs.atomiq.exchange/sdk-reference/api/atomiq-sdk/src/classes/SwapperUtils#getspendablebalance) - Get spendable smart chain balance
* [getBitcoinSpendableBalance](https://docs.atomiq.exchange/sdk-reference/api/atomiq-sdk/src/classes/SwapperUtils#getbitcoinspendablebalance) - Get spendable Bitcoin balance for a route
* [getNativeToken](https://docs.atomiq.exchange/sdk-reference/api/atomiq-sdk/src/classes/SwapperUtils#getnativetoken) - Get the native token object for a chain
* [IBitcoinWallet](https://docs.atomiq.exchange/sdk-reference/api/atomiq-sdk/src/interfaces/IBitcoinWallet) - Bitcoin wallet interface usable by the balance helper
