Expand description

Bark: Ark on bitcoin
Fast, low-cost, self-custodial payments on bitcoin.
Docs ·
Issues ·
Website ·
Blog ·
YouTube
Bark is an implementation of the Ark protocol on bitcoin, led by Second.
§A tour of Bark
Integrating the Ark-protocol offers
- 🏃♂️ Smooth boarding: No channels to open, no on-chain setup required—create a wallet and start transacting
- 🤌 Simplified UX: Send and receive without managing channels, liquidity, or routing
- 🌐 Universal payments: Send Ark, Lightning, and on-chain payments from a single off-chain balance
- 🔌 Easier integration: Client-server architecture reduces complexity compared to P2P protocols
- 💸 Lower costs: Instant payments at a fraction of on-chain fees
- 🔒 Self-custodial: Users maintain full control of their funds at all times
This guide puts focus on how to use the Rust-API and assumes some basic familiarity with the Ark protocol. We refer to the protocol docs for an introduction.
§Creating an Ark wallet
The user experience of setting up an Ark wallet is pretty similar to setting up an onchain wallet. You need to provide a bip39::Mnemonic which can be used to recover funds. Typically, most apps request the user to write down the mnemonic or ensure they use another method for a secure back-up.
The user can select an Ark server and a onchain::ChainSource as part of the configuration. The example below configures
You will also need a place to store all ark::Vtxos on the users device. We have implemented SqliteClient which is a sane default on most devices. However, it is possible to implement a BarkPersister if you have other requirements.
The code-snippet below shows how you can create a Wallet.
use std::path::PathBuf;
use std::sync::Arc;
use tokio::fs;
use bark::{Config, onchain, SqliteClient, Wallet};
const MNEMONIC_FILE : &str = "mnemonic";
const DB_FILE: &str = "db.sqlite";
#[tokio::main]
async fn main() {
// Pick the bitcoin network that will be used
let network = bitcoin::Network::Signet;
// Configure the wallet
let config = Config {
server_address: String::from("https://ark.signet.2nd.dev"),
esplora_address: Some(String::from("https://esplora.signet.2nd.dev")),
..Config::network_default(network)
};
// Create a sqlite database
let datadir = PathBuf::from("./bark");
let db = Arc::new(SqliteClient::open(datadir.join(DB_FILE)).unwrap());
// Generate and seed and store it somewhere
let mnemonic = bip39::Mnemonic::generate(12).expect("12 is valid");
fs::write(datadir.join(MNEMONIC_FILE), mnemonic.to_string().as_bytes()).await.unwrap();
let wallet = Wallet::create(
&mnemonic,
network,
config,
db,
false
).await.unwrap();
}§Opening an existing Ark wallet
The Wallet can be opened again by providing the bip39::Mnemonic and the BarkPersister again. Note, that SqliteClient implements the BarkPersister-trait.
const MNEMONIC_FILE : &str = "mnemonic";
const DB_FILE: &str = "db.sqlite";
#[tokio::main]
async fn main() {
let datadir = PathBuf::from("./bark");
let config = Config {
server_address: String::from("https://ark.signet.2nd.dev"),
esplora_address: Some(String::from("https://esplora.signet.2nd.dev")),
..Config::network_default(bitcoin::Network::Signet)
};
let db = Arc::new(SqliteClient::open(datadir.join(DB_FILE)).unwrap());
let mnemonic_str = fs::read_to_string(datadir.join(DB_FILE)).await.unwrap();
let mnemonic = bip39::Mnemonic::from_str(&mnemonic_str).unwrap();
let wallet = Wallet::open(&mnemonic, db, config).await.unwrap();
}§Receiving coins
For the time being we haven’t implemented an Ark address type (yet). You can send funds directly to a public key.
If you are on signet and your Ark server is https://ark.signet.2nd.dev, you can request some sats from our faucet.
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let wallet = get_wallet().await;
let address: ark::Address = wallet.new_address().await?;
Ok(())
}§Inspecting the wallet
An Ark wallet contains ark::Vtxos. These are just like normal utxos in a bitcoin wallet. They just haven’t been confirmed on chain (yet). However, the user remains in full control of the funds and can perform a unilateral exit at any time.
The snippet below shows how you can inspect your WalletVtxos.
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let mut wallet = get_wallet().await;
// The vtxo's command doesn't sync your wallet
// Make sure your app is synced before inspecting the wallet
wallet.sync().await;
let vtxos: Vec<bark::WalletVtxo> = wallet.vtxos().unwrap();
Ok(())
}Use Wallet::balance if you are only interested in the balance.
§Participating in a round
You can participate in a round to refresh your coins. Typically, you want to refresh coins which are soon to expire or you might want to aggregate multiple small vtxos to keep the cost of exit under control.
As a wallet developer you can implement your own refresh strategy. This gives you full control over which ark::Vtxos are refreshed and which aren’t.
This example uses RefreshStrategy::must_refresh which is a sane default that selects all ark::Vtxos that must be refreshed.
use bark::vtxo::selection::RefreshStrategy;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let wallet = get_wallet().await;
// Select all vtxos that refresh soon
let tip = wallet.chain.tip().await?;
let fee_rate = wallet.chain.fee_rates().await.fast;
let strategy = RefreshStrategy::must_refresh(&wallet, tip, fee_rate);
let vtxos = wallet.spendable_vtxos_with(&strategy)?
.into_iter().map(|v| v.vtxo).collect::<Vec<_>>();
wallet.refresh_vtxos(vtxos).await?;
Ok(())
}Re-exports§
pub extern crate ark;pub extern crate bip39;pub extern crate lightning_invoice;pub extern crate lnurl as lnurllib;pub use self::persist::sqlite::SqliteClient;pub use self::vtxo::state::WalletVtxo;
Modules§
- daemon
- exit
- Unilateral exit management
- lightning
- movement
- onchain
- Onchain wallet integration interfaces.
- persist
- Persistence abstractions for Bark wallets.
- round
- Round State Machine
- subsystem
- Contains subsystem-related constants and types for Bark.
- vtxo
Structs§
- Balance
- The different balances of a Bark wallet.
- Config
- Configuration of the Bark wallet.
- Lightning
Receive Balance - The detailled balance of a Lightning receive.
- Offboard
- Describes a completed transition of funds from offchain to onchain collaboratively with the Ark server.
- Offchain
Balance - Represents an offchain balance structure consisting of available funds, pending amounts in unconfirmed rounds, and pending exits.
- Utxo
Info - Vtxo
Seed - Struct representing an extended private key derived from a wallet’s seed, used to derive child VTXO keypairs
- Wallet
- The central entry point for using this library as an Ark wallet.
- Wallet
Properties - Read-only properties of the Bark wallet.
Enums§
- Bark
Network - Networks bark can be used on