Skip to main content

Overview

Boarding moves Bitcoin from an onchain wallet into Ark, creating VTXOs that can be used for fast, cheap offchain payments. The process requires:
  1. An onchain wallet implementing the Board trait
  2. Sufficient onchain funds to cover the amount plus fees
  3. Waiting for confirmations before the VTXO becomes spendable

Board Amount

board_amount

Board a specific amount from your onchain wallet into Ark.
pub async fn board_amount(
    &self,
    onchain: &mut dyn onchain::Board,
    amount: Amount,
) -> anyhow::Result<PendingBoard>
onchain
&mut dyn onchain::Board
required
Onchain wallet to spend from
amount
Amount
required
Amount to board into Ark (must meet server’s minimum)
Returns
Result<PendingBoard>
pub struct PendingBoard {
    pub vtxos: Vec<VtxoId>,
    pub movement_id: MovementId,
    pub funding_tx: Transaction,
}
Information about the pending board operation
Example:
use bark::onchain::OnchainWallet;
use bitcoin::Amount;

let mut onchain_wallet = OnchainWallet::load_or_create(
    network, seed, db.clone()
).await?;

// Board 100,000 sats into Ark
let pending = wallet.board_amount(
    &mut onchain_wallet,
    Amount::from_sat(100_000)
).await?;

println!("Board tx: {}", pending.funding_tx.compute_txid());
println!("VTXO IDs: {:?}", pending.vtxos);

// Sync to register once confirmed
wallet.sync_pending_boards().await?;
The actual onchain cost will be slightly higher due to transaction fees.

Board All

board_all

Board all available funds from your onchain wallet.
pub async fn board_all(
    &self,
    onchain: &mut dyn onchain::Board,
) -> anyhow::Result<PendingBoard>
onchain
&mut dyn onchain::Board
required
Onchain wallet to drain
Example:
// Board entire onchain balance
let pending = wallet.board_all(&mut onchain_wallet).await?;

Pending Boards

pending_boards

Query all boards waiting for confirmation.
pub async fn pending_boards(&self) -> anyhow::Result<Vec<PendingBoard>>
Example:
let pending = wallet.pending_boards().await?;
for board in pending {
    println!("Pending board: {} VTXOs", board.vtxos.len());
}

pending_board_vtxos

Get VTXOs from pending boards (locked until registered).
pub async fn pending_board_vtxos(&self) -> anyhow::Result<Vec<WalletVtxo>>
Returns
Vec<WalletVtxo>
VTXOs that are locked pending board registration

Syncing Boards

sync_pending_boards

Attempt to register all confirmed boards with the Ark server.
pub async fn sync_pending_boards(&self) -> anyhow::Result<()>
This method:
  • Checks confirmation status of pending board transactions
  • Registers boards with sufficient confirmations
  • Updates VTXO state to Spendable once registered
  • Handles expired boards by initiating exits
Example:
// Board funds
let pending = wallet.board_amount(&mut onchain, Amount::from_sat(50_000)).await?;

// Wait for confirmations (in practice, call periodically)
tokio::time::sleep(Duration::from_secs(600)).await;

// Register with server
wallet.sync_pending_boards().await?;

// VTXOs are now spendable
let balance = wallet.balance().await?;
println!("Spendable: {}", balance.spendable);
Boards require a minimum number of confirmations (specified by ArkInfo::required_board_confirmations) before they can be registered.

Board Lifecycle


Fees

Boarding involves two fee components:
  1. Onchain Transaction Fee: Paid to Bitcoin miners
  2. Ark Board Fee: Paid to the Ark server (deducted from VTXO amount)
// The VTXO amount will be:
let vtxo_amount = board_amount - ark_fee;

// Total onchain cost:
let total_cost = board_amount + onchain_tx_fee;
The board fee is calculated by the server and can be retrieved from ArkInfo::fees.

Error Handling

Boarding will fail if:
  • Amount is below server’s min_board_amount
  • Insufficient onchain funds
  • Onchain transaction broadcast fails
  • Server rejects the board request
Common Errors:
match wallet.board_amount(&mut onchain, amount).await {
    Ok(pending) => println!("Board initiated"),
    Err(e) if e.to_string().contains("min_board_amount") => {
        println!("Amount too small");
    }
    Err(e) if e.to_string().contains("Insufficient") => {
        println!("Not enough onchain funds");
    }
    Err(e) => eprintln!("Board failed: {}", e),
}

Best Practices

Recommended workflow:
  1. Check ArkInfo::min_board_amount before boarding
  2. Ensure onchain wallet has sufficient balance
  3. Call sync_pending_boards() periodically to register boards
  4. Use pending_board_vtxos() to track locked funds
let ark_info = wallet.ark_info().await?.unwrap();
let min_amount = ark_info.min_board_amount;

if amount >= min_amount {
    let pending = wallet.board_amount(&mut onchain, amount).await?;
    
    // Store board info for later registration
    // ...
}

Build docs developers (and LLMs) love