# MCP server for agents Source: https://second.tech/docs/agents Give your coding agent access to indexed, searchable Bark documentation via MCP. Setup instructions for Claude Code, Codex, and Cursor. Add Second's MCP server to your coding agent with this address: ```text MCP server theme={"theme":{"light":"github-light","dark":"github-dark"}} https://second.tech/docs/mcp ``` ## Connect your tool **Claude Code** Run the following command in your terminal: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} claude mcp add --transport http second-docs https://second.tech/docs/mcp ``` This adds the server for your current project. To make it available across all your projects, use the `--scope user` flag: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} claude mcp add --transport http second-docs --scope user https://second.tech/docs/mcp ``` To share it with your team via version control, use `--scope project` which writes a `.mcp.json` file to your project root: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} claude mcp add --transport http second-docs --scope project https://second.tech/docs/mcp ``` Once added, type `/mcp` inside Claude Code to verify the server is connected. **Codex** Run the following command in your terminal: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} codex mcp add second-docs --url https://second.tech/docs/mcp ``` This adds the server to your global Codex configuration at `~/.codex/config.toml`. You can also add it manually by editing the config file directly: ```toml theme={"theme":{"light":"github-light","dark":"github-dark"}} [mcp_servers.second-docs] url = "https://second.tech/docs/mcp" ``` For project-level configuration, create `.codex/config.toml` in your project root with the same content. Once added, type `/mcp` inside Codex to verify the server is connected. **Cursor** Open your MCP configuration file. For global access, edit `~/.cursor/mcp.json`. For project-level access, create `.cursor/mcp.json` in your project root. Add the following: ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "mcpServers": { "second-docs": { "url": "https://second.tech/docs/mcp" } } } ``` Restart Cursor after saving the file. You can also add it through the settings UI: open **Settings**, search for **MCP**, select **Add new MCP server**, and enter the URL above. # Connect a wallet Source: https://second.tech/docs/ark-server/connect-wallet Connect a Bark wallet to your test Ark server. Create a wallet, fund it, board the Ark, and start making transactions. An Ark server is not that interesting until it has some wallets transacting on it! Here we'll set up an Ark wallet, fund it, then get it to board the Ark. **1. Create a Bark wallet and connect to your server** **Manual (signet)** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} bark create --signet \ --ark http://localhost:3535 \ --bitcoind http://localhost:38332 \ --bitcoind-cookie ~/.bitcoin/signet/.cookie ``` **Docker Compose (regtest)** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} docker compose -f contrib/docker/docker-compose.yml run --rm bark \ bark create ``` **2. Fund the wallet** Request an on-chain address from Bark: **Manual (signet)** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} bark onchain address ``` Send signet coins to this address using the [Second faucet](https://signet.2nd.dev). **Docker Compose (regtest)** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} export BARK_ADDRESS=$(docker compose -f contrib/docker/docker-compose.yml run --rm bark \ bark onchain address) docker compose -f contrib/docker/docker-compose.yml run --rm bitcoind \ bitcoin-cli -regtest -rpcuser=second -rpcpassword=ark \ -rpcconnect=bitcoind sendtoaddress $BARK_ADDRESS 0.1 ``` **3. Board the Ark** Board the bitcoin onto Ark: **Manual (signet)** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} bark board --all ``` Wait for the transaction to confirm. Signet produces blocks roughly every 5 minutes. **Docker Compose (regtest)** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} docker compose -f contrib/docker/docker-compose.yml run --rm bark \ bark board --all ``` Generate some blocks to confirm the board: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} docker compose -f contrib/docker/docker-compose.yml run --rm bitcoind \ bitcoin-cli -regtest -rpcuser=second -rpcpassword=ark \ -rpcconnect=bitcoind -generate 6 ``` **4. Verify** Check your wallet balance: **Manual (signet)** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} bark balance ``` **Docker Compose (regtest)** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} docker compose -f contrib/docker/docker-compose.yml run --rm bark \ bark balance ``` ## The Ark's your oyster You now have a fully operational Ark server running with a wallet connected and holding some VTXOs. This should be a perfect environment to explore the Ark ecosystem from an Ark server perspective. Some things you might want to try: * Out-of-round payments * In-round refreshes * Offboards * Exits If you run into any issues or have questions, don't hesitate to post to our [git repo](https://gitlab.com/ark-bitcoin/bark) or [community](https://community.second.tech). # Set up an Ark server with Docker Compose Source: https://second.tech/docs/ark-server/docker-compose Run an Ark server with Docker Compose. All-in-one containerized setup with PostgreSQL, Bitcoin Core, captaind, and optionally Core Lightning on regtest. All dependencies are included and configured automatically. The optional Core Lightning service ships with [Boltz's hold plugin](https://github.com/BoltzExchange/hold). > [!NOTE] > > This path runs on **regtest**, a local-only test network. If you'd prefer to run on signet with each component installed individually, see the [manual setup guide](/docs/ark-server/manual-setup) instead. The Compose file handles boot-time dependencies and initializations using `depends_on` and health checks. ## Start the server **1. Clone the repository** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} git clone https://gitlab.com/ark-bitcoin/bark cd bark ``` **2. Start all services** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} docker compose -f contrib/docker/docker-compose.yml up ``` **3. Verify services are running** Once everything is up, you can run commands against the containers: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} # bark docker compose -f contrib/docker/docker-compose.yml run --rm bark bark ark-info # bitcoin-cli docker compose -f contrib/docker/docker-compose.yml run --rm bitcoind \ bitcoin-cli -regtest -rpcuser=second -rpcpassword=ark \ -rpcconnect=bitcoind getblockchaininfo # captaind docker compose -f contrib/docker/docker-compose.yml run --rm captaind \ captaind --config /root/captaind/captaind.toml get-mnemonic # Core Lightning docker compose -f contrib/docker/docker-compose.yml exec cln \ lightning-cli --regtest getinfo ``` > **Shared volumes** > > * `captaind` — persistent data for `captaind` > * `postgres` — PostgreSQL database files > * `bark` — data for `bark` > * `bitcoind` — Bitcoin Core blockchain and wallet data > * `cln` — Core Lightning node data ## Fund the server Generate some regtest blocks and send bitcoin to the server: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} # Get the server's funding address export CAPTAIND_ADDRESS=$(docker compose -f contrib/docker/docker-compose.yml run --rm captaind \ captaind --config /root/captaind/captaind.toml rpc wallet | jq -r '.rounds.address') # Generate blocks docker compose -f contrib/docker/docker-compose.yml run --rm bitcoind \ bitcoin-cli -regtest -rpcuser=second -rpcpassword=ark \ -rpcconnect=bitcoind -generate 106 # Send bitcoin to the server docker compose -f contrib/docker/docker-compose.yml run --rm bitcoind \ bitcoin-cli -regtest -rpcuser=second -rpcpassword=ark \ -rpcconnect=bitcoind sendtoaddress $CAPTAIND_ADDRESS 1 ``` # Run an Ark server Source: https://second.tech/docs/ark-server/index Run your own Ark server for testing: install each component by hand on signet, or start the whole stack on regtest with Docker Compose. This guide shows you how to run an Ark server for testing. Operating an Ark server can be significantly more involved than running a Lightning node or ecash mint. We do still hope you'll try and run the server for fun, learning, or setting up a local developer environment! This guide assumes you have [installed Bark](/docs/getting-started/bark-cli) and know how to use it. ## Choose your setup path > **[Manual setup (signet)](/docs/ark-server/manual-setup)** > > Install each dependency individually, download or compile `captaind`, and launch on **signet**. Best for understanding how each component works. > **[Docker Compose (regtest)](/docs/ark-server/docker-compose)** > > Install everything in containers, start all services with one command, and launch on **regtest**. Best for getting up and running quickly. # Set up an Ark server manually Source: https://second.tech/docs/ark-server/manual-setup Manually install PostgreSQL, Bitcoin Core, and captaind. Configure and launch an Ark server on signet for testing. This guide walks through installing each dependency, building or downloading `captaind`, and launching an Ark server on **signet**. > [!NOTE] > > This path runs on **signet**, bitcoin's public test network. If you'd prefer a fully containerized local setup on regtest, see the [Docker Compose guide](/docs/ark-server/docker-compose) instead. ## Install dependencies ### PostgreSQL **Docker (recommended)** Run PostgreSQL in a Docker container: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} docker run \ --name my_postgres \ -e POSTGRES_USER=postgres \ -e POSTGRES_PASSWORD=postgres \ -e POSTGRES_DB=bark-server-db \ -p 5432:5432 \ -d postgres ``` **Package managers** **macOS** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} brew install postgresql brew services start postgresql ``` **Debian/Ubuntu** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} sudo apt update sudo apt install postgresql sudo systemctl start postgresql ``` **Fedora/CentOS/RHEL** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} sudo dnf install postgresql-server sudo postgresql-setup --initdb sudo systemctl start postgresql ``` **Manual installation** Download PostgreSQL from the [official download page](https://www.postgresql.org/download/) and follow the platform-specific instructions. Verify PostgreSQL is running: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} psql -h localhost -U postgres -c "SELECT version();" ``` ### Bitcoin Core Bitcoin Core v30.0+ is strongly recommended. Download from the [official download page](https://bitcoincore.org/en/download/) and follow the installation instructions for your operating system. For Linux, unpack the archive and add `bitcoind` and `bitcoin-cli` to your path. Verify the installation: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} bitcoind --version ``` ### Optional dependencies > **Just and jq** > > **Just** is a command runner that simplifies running common tasks. > > **macOS** > > ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} > brew install just > ``` > > **Debian/Ubuntu/Fedora** > > ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} > cargo install --locked just > ``` > > Verify: > > ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} > just --version > ``` > > **jq** is a command-line tool for processing JSON data. > > **Package managers** > > **macOS** > > ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} > brew install jq > ``` > > **Debian/Ubuntu** > > ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} > sudo apt update > sudo apt install jq > ``` > > **Fedora/CentOS/RHEL** > > ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} > sudo dnf install jq > ``` > > **Manual installation** > > Download the binaries from the [GitHub releases page](https://github.com/jqlang/jq/releases). > > Verify: > > ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} > jq --version > ``` ## Install captaind > [!NOTE] > > Currently, only Unix-based systems (Linux, macOS) are supported. **Download binary** Download the latest `captaind` binary from the [releases page](https://gitlab.com/ark-bitcoin/bark/-/releases). Verify the installation: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} captaind --version ``` **Compile from source** **1. Clone the repository** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} git clone https://gitlab.com/ark-bitcoin/bark cd bark ``` **2. Install build dependencies** You will need a Rust compiler. Find installation instructions on the [rustup website](https://rustup.rs). On Ubuntu/Debian, install the additional build dependencies: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} sudo apt update sudo apt install build-essential clang cmake pkg-config protobuf-compiler libpq-dev libsodium-dev libsqlite3-dev libssl-dev ``` **3. Build and install** Build and install to your path: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} cargo install --locked --path ./server ``` Or build without installing: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} cargo build --bin captaind ``` **4. Verify the installation** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} captaind --version ``` ## Configure and launch **1. Start your signet node** Launch a signet bitcoin node: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} bitcoind --signet --daemon ``` If your `bitcoin.conf` file is empty, this will launch a signet node. By default the node will: * Create a cookie in `~/.bitcoin/signet/.cookie` * Listen for RPC connections on port `38332` Verify the node is running: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} bitcoin-cli -signet \ -rpcconnect=localhost \ -rpcport=38332 \ -rpccookiefile=$HOME/.bitcoin/signet/.cookie \ getblockcount ``` **2. Start PostgreSQL** Make sure PostgreSQL is running as described in the [Install dependencies](#postgresql) section above. **3. Create a config file** Create a `config.toml` file that specifies the configuration of your Ark server: ```toml theme={"theme":{"light":"github-light","dark":"github-dark"}} data_dir = "./bark-server" network = "signet" [rpc] public_address = "127.0.0.1:3535" admin_address = "127.0.0.1:3536" [postgres] host = "localhost" port = 5432 name = "bark-server-db" user = "postgres" password = "postgres" [bitcoind] url = "http://127.0.0.1:38332" cookie = "/home//.bitcoin/signet/.cookie" ``` **4. Run the Ark server** Once you've got the dependencies running and set up your configuration, launch the server: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} captaind create --config captaind start --config ``` ## Fund the server Retrieve the server's funding address: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} captaind rpc wallet | jq -r '.rounds.address' ``` Send signet coins to this address using the [Second faucet](https://signet.2nd.dev). Once the transaction confirms, verify the bitcoin arrived: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} bitcoin-cli -signet getreceivedbyaddress
``` # Backups Source: https://second.tech/docs/backups Design patterns for backing up Bark-based wallets: seed phrase backups and the mailbox restore, and continuous wallet database backups for the SDK and Barkd. There are two ways to back up a Bark-based wallet. 1. **[Record the mnemonic (seed phrase)](#seed-phrase-backups):** This alone is enough to recover a wallet's balance, with the Ark server's cooperation. It can't restore payment history or the state of any in-progress exits, and it's also the key that decrypts encrypted continuous backups. 2. **[Maintain a continuous backup of the wallet database](#continuous-backups):** A backup the user fully controls. It restores a wallet in full, payment history and in-progress exits included, without any support from the server. ## Seed phrase backups Every Bark wallet posts a record of its VTXOs to a mailbox on the Ark server that only its mnemonic can unlock. A wallet restored from the mnemonic alone derives its keys, pulls the VTXO record back, verifies every VTXO, then rebuilds the spendable off-chain balance. A chain scan then recovers the on-chain balance. The seed phrase alone is a safety net, but it isn't a complete backup. * The backup depends on the server to cooperate and respond with the required data. * It restores the balance, not the payment history or the state of an in-progress exit. ### Revealing the seed phrase **Bark SDK** The SDK does not hold the mnemonic for you by default. You'll need to ensure your app generates it, stores it, and reveals it when required. **1. Generate the phrase** Call `generateMnemonic` and pass the result in when you create the wallet. **2. Store it securely** Write the phrase to your app's secure storage. **3. Offer a reveal screen** Show the words on demand from a settings screen, behind your app's own authentication. **Barkd** By default, `barkd` generates the mnemonic and keeps it in its data directory upon wallet creation. You can reveal it through the REST API. **1. Enable the endpoint** Start `barkd` with the `--expose-mnemonic` flag. Without it, the mnemonic endpoint returns 404. **2. Fetch the phrase** Call `GET /api/v1/wallet/mnemonic` to show the words on demand. > [!WARNING] > > Keep the mnemonic endpoint behind your deployment's authentication. Anyone with access to the mnemonic can obtain full control of the wallet. ## Continuous backups To ensure users don't have to rely on the Ark server for backups, your app should keep backups of the wallet database that update after every wallet state change, in addition to recording the mnemonic. An up-to-date wallet database backup includes all the off-chain transactions that make up a user's VTXOs. Therefore it will restore the wallet in full: the whole balance, the payment history, and any in-progress exits, all without the Ark server's involvement. Any good backup solution follows three rules. * **Back up on every state change, not on a schedule:** Wallet state changes with every board, send, receive, refresh, offboard, and exit. Anything a backup misses can only be recovered through the seed phrase mailbox. * **Store backups somewhere that outlives the host device:** A copy kept on the wallet's own device disappears with it. * **Encrypt backups with a key derived from the mnemonic:** The seed holder can always decrypt, so a restore needs nothing but the phrase, and the backup grants no access that the seed doesn't already grant. How you make continuous backups depends on what you're building on. **Bark SDK** The SDK persists wallet data through the storage your app provides, so backing it up is your app's responsibility. #### Mobile and desktop apps Wallet data typically lives in the app sandbox. Backups should go to storage that the user controls, such as their platform-native cloud drive, after each state change. [Noah](https://github.com/smolcars/noah), a full-stack React Native wallet, has a mature example of mobile backups for Bark. #### Web apps In the browser, the SDK stores wallet data in IndexedDB. IndexedDB is scoped to the site origin and can be evicted by the browser, so it's even more important to ship every change to another secure location and to make sure the user has recorded their mnemonic. **Barkd** `barkd` stores the wallet database (`db.sqlite`) and the mnemonic in the data directory, which defaults to `$HOME/.bark` on all operating systems. You can override it with the `--datadir` flag or the `BARKD_DATADIR` environment variable. The mnemonic file is stored in plain text, so restrict access to the directory and to anything that backs it up. Some options for backing the wallet database up on every state change: * **[Litestream](https://litestream.io/):** A streaming replicator that keeps a live, off-machine copy of the wallet database. The wallet database isn't formally tested in the WAL journal mode Litestream requires, so treat the approach as experimental. * **[bark-backupd](https://gitlab.com/ark-bitcoin/labs/bark-backupd):** Second's experimental backup daemon, currently under active development. Run it alongside `barkd` to take a snapshot of the wallet database on every change, encrypt each snapshot with a key derived from the mnemonic, and ship it to your chosen targets: * A USB drive * Nextcloud * Google Drive * Anything S3-compatible > [!WARNING] > > Test `bark-backupd restore` before you rely on bark-backupd. # Back up your wallet Source: https://second.tech/docs/bark-pay/backups Write down your Bark Pay wallet's seed phrase and keep the Barkd and Bark Pay volumes backed up, so you can recover your bitcoin and your charge history. Back up your wallet before you receive any bitcoin. The volumes bring back the whole wallet and your charge history. The seed phrase is your fallback if you lose them. ## Write down the seed phrase Read the 12 words from the Barkd container and copy them somewhere safe and offline: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} docker compose -f docker/docker-compose.prod.yml exec barkd-mainnet cat /data/barkd/mnemonic ``` This is a one-time step. Repeat it for `barkd-signet` if you run [test mode](/docs/bark-pay/install#add-test-mode). > [!WARNING] > > Your backups contain the wallet's keys. Barkd stores the seed phrase in plain text in its volume, so anyone who can read that volume or its backups can spend the wallet's bitcoin. Restrict access to both. ## Back up the two volumes Add both volumes to the backup you already run for the server: | Volume | What it holds | | - | - | | `bark-pay_barkd_mainnet_data` | The Barkd data directory: seed phrase, wallet database, and access token. | | `bark-pay_barkpay_data` | The Bark Pay database (admin account, API keys, charges, events, webhooks, settings) and uploaded logos. | Back them up continuously, not on a schedule. A stale copy misses the bitcoin received since, which then only the seed phrase can bring back. The [Backups](/docs/backups) page explains the model for every Bark wallet. ## Restore from a backup **1. Restore both volumes on the new server** Recreate `bark-pay_barkd_mainnet_data` and `bark-pay_barkpay_data` with your backup tool. **2. Copy the bark-pay repository and your .env file** **3. Start the stack** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} docker compose -f docker/docker-compose.prod.yml up -d --build ``` Bark Pay reconnects to the same wallet and charge history. > [!NOTE] > > With the seed phrase alone, restore the balance in [Bark Wallet](/docs/bark-wallet/restore) on the same Ark server. Bark Wallet pulls back the VTXOs the Ark server still has a record of and scans the chain for on-chain payments. None of your charge history comes back. # Create and track charges Source: https://second.tech/docs/bark-pay/charges Create a charge from the Bark Pay dashboard, share its checkout link or payment details, and follow it from pending to paid, underpaid, expired, or cancelled. A charge is a request for a fixed amount, payable once. The **Charges** page lists every charge of the current mode. ## Create a charge Use this to bill a customer by hand. **1. Go to Charges and select Create charge** **2. Enter the amount** Enter the amount in sats. To price the charge in fiat, select the arrows next to **sats**, enter the amount, and select **USD** or **EUR** in the **Currency** field. The sats amount locks at creation. **3. Add a reference and a description** **Reference** is for you, for example your order number. Bark Pay shows **Description** to the customer at checkout. Both are optional. **4. Leave Rails on Automatic** Bark Pay then offers every payment method that fits the amount. Select **Lightning**, **On-chain**, or **Ark** to restrict the charge instead. **5. Select Create charge at the bottom of the drawer** The charge detail opens with its payment details and checkout link. ![Screenshot of the Create charge drawer, with the Amount, Reference, Description, and Rails fields filled in and the Create charge button](https://mintcdn.com/second-0659a37d/w3x3inV3jE1Buo4A/images/bark-pay/create-charge.png?fit=max\&auto=format\&n=w3x3inV3jE1Buo4A\&q=85\&s=14fb34fee2d034ca47823089524af47b) Automatic rails offer every payment method that fits the amount The charge expires after the **Invoice TTL** set in [Settings](/docs/bark-pay/settings#charge-defaults), 15 minutes by default. Lightning starts at 1 sat, and Ark and on-chain at 546 sats. The Ark server's maximum VTXO size also caps Lightning and Ark from above. On **Automatic**, Bark Pay offers only the methods the amount fits. If you restrict the rails yourself, Bark Pay refuses the charge and names the limit. ## Share the payment details Two ways to get paid: * **Checkout link:** Select **Open checkout** to preview the [hosted checkout page](/docs/bark-pay/checkout), or copy its URL and send it to your customer. * **Payment rails:** Select the **Lightning**, **Ark**, or **On-chain** tab to show that method's QR code and copy its invoice or address, for example to display at a counter. ![Screenshot of the charge detail sheet, with the amount, the details rows, the checkout link, and the payment rails tabs showing the Ark address QR code](https://mintcdn.com/second-0659a37d/w3x3inV3jE1Buo4A/images/bark-pay/charge-detail.png?fit=max\&auto=format\&n=w3x3inV3jE1Buo4A\&q=85\&s=8657473536d8eb6a7c16fcc604786f8f) The charge detail carries the checkout link and one QR code per payment method ## Follow a charge's status While any charge on the page is pending, underpaid, or expired, the list refreshes itself every ten seconds. Filter it with the **All statuses** dropdown, and select a row to reopen its payment details: | Status | Meaning | | - | - | | Pending | Created, no payment received yet. | | Paid | The full amount arrived before expiry. | | Paid late | The full amount arrived after expiry, in one payment or as a top-up on an underpaid charge. | | Underpaid | Less than the amount arrived. The payment details stay open until expiry so your customer can top up, and a later top-up still counts. | | Overpaid | More than the amount arrived, including an extra payment on a charge that was already paid. | | Expired | The charge reached its expiry without receiving anything. Bark Pay closes its Lightning invoice, but an Ark or on-chain payment that arrives afterwards still settles it. | | Cancelled | Your server cancelled the charge through the API. Bark Pay records any bitcoin that arrives on it afterwards, but the status stays cancelled. | Lightning and Ark payments settle within seconds. An on-chain payment settles once its transaction has one confirmation, so expect a wait of about ten minutes on that method. > [!NOTE] > > The dashboard has no cancel button. To cancel a pending or underpaid charge, use the [cancel endpoint](/docs/bark-pay/integrate#cancel-a-charge) with a secret API key. > [!TIP] > > To accept a payment that lands a few sats off the amount, set an [amount tolerance](/docs/bark-pay/settings#rates). Payments within it count as paid instead of underpaid or overpaid. # Take payments at checkout Source: https://second.tech/docs/bark-pay/checkout Check what your customers see on the Bark Pay hosted checkout page, follow the paid and expired states, and put your own name and logo on the page. Every checkout link opens a page on your own Bark Pay domain. Your customer pays there, and the page confirms the payment on its own. ![Screenshot of the hosted checkout page for a 21,000 sats charge, with the Lightning, Ark, and On-chain tabs, a QR code, the Ark address, the Copy Ark address button, and the Pending status with a countdown](https://mintcdn.com/second-0659a37d/w3x3inV3jE1Buo4A/images/bark-pay/checkout.png?fit=max\&auto=format\&n=w3x3inV3jE1Buo4A\&q=85\&s=6de513fd5ba70d4633b027fe59a5c34a) The page opens on the Ark tab when the charge offers Ark. Your customer selects Lightning or On-chain to pay another way ## Follow a payment on the page Your customer scans the QR code with a wallet app, or selects **Copy Lightning invoice**, **Copy Ark address**, or **Copy On-chain address** and pastes it in. A charge with a single payment method shows no tabs. The page updates itself: | State | What the page shows | | - | - | | Underpaid | The remaining amount, with the payment details still on screen for a top-up. | | Paid | **Payment received** and a receipt. If the charge has a success URL, the page redirects there after a moment. | | Expired or cancelled | The page reads **This charge is no longer payable.** If the page was open when the charge ended, the QR code first blurs under an **Expired** label. If the charge has a cancel URL, a **Return** link takes your customer back. | ## Checkout branding Select **Branding** in the sidebar to change how every checkout page looks: * **Display name:** Replaces the `bark-pay` wordmark at the top of the page. * **Accent color:** The highlight color, as a hex value. Select it from the swatch or type it. * **Logo:** Upload a PNG, JPEG, or WebP up to 200 KB, or paste an image URL. Select **Save branding** to apply your changes, or **Preview** to open a sample checkout in a new tab first. ![Screenshot of the Checkout branding page, with the Display name, Accent color, and Logo fields and the Save branding and Preview buttons](https://mintcdn.com/second-0659a37d/w3x3inV3jE1Buo4A/images/bark-pay/branding.png?fit=max\&auto=format\&n=w3x3inV3jE1Buo4A\&q=85\&s=0689249cd19cdb4c598563fb8bfec22c) Branding applies to every hosted checkout page at once # Bark Pay Source: https://second.tech/docs/bark-pay/index Accept Lightning, Ark, and on-chain payments on your own server with Bark Pay, a self-custodial payment processor with a checkout page and a charges API. Create charges from the dashboard or straight from your app, and a webhook tells you the moment one is paid. Only you can move the bitcoin back out. ![Screenshot of the hosted checkout page for a 21,000 sats charge, with the Lightning, Ark, and On-chain tabs, an Ark QR code, and the Pending status with a countdown](https://mintcdn.com/second-0659a37d/w3x3inV3jE1Buo4A/images/bark-pay/checkout.png?fit=max\&auto=format\&n=w3x3inV3jE1Buo4A\&q=85\&s=6de513fd5ba70d4633b027fe59a5c34a) Your customers pay a charge over Lightning, Ark, or on-chain from one hosted page ## What Bark Pay manages for you * **One wallet you control:** Every live charge settles into the same Barkd wallet on your server. Only you can spend from it. Test mode uses a separate signet wallet. * **Every payment method:** A charge offers Lightning, Ark, and on-chain when the amount fits each one. Bark Pay notifies your app when it settles. * **Wallet maintenance:** Like any off-chain protocol, Ark wallets require ongoing maintenance. Barkd handles all of it in the background for you. ## Set up and run Bark Pay > **[Install Bark Pay](/docs/bark-pay/install)** > > Run the Docker Compose stack on your server, connect it to Barkd, and sign in. > **[Back up your wallet](/docs/bark-pay/backups)** > > Write down the seed phrase and keep the wallet volumes backed up. > **[Create and track charges](/docs/bark-pay/charges)** > > Create a charge from the dashboard, share its checkout link, and follow its status. > **[Take payments at checkout](/docs/bark-pay/checkout)** > > Check what your customers see on the hosted page, and put your branding on it. > **[Integrate Bark Pay with your app](/docs/bark-pay/integrate)** > > Create API keys, open checkout sessions from your server, and fulfill orders on webhooks. > **[Manage your Bark Pay wallet](/docs/bark-pay/wallet)** > > Read your balances, deposit bitcoin, and send manual payouts from the dashboard. > **[Configure Bark Pay](/docs/bark-pay/settings)** > > Set charge defaults, the amount tolerance, test mode, and your admin password. > **[Update or remove Bark Pay](/docs/bark-pay/update)** > > Pull a new version without losing data, or shut the stack down safely. # Install Bark Pay Source: https://second.tech/docs/bark-pay/install Run Bark Pay on your server with Docker Compose: configure the environment file, connect Barkd, start the stack, and sign in to the admin dashboard. Bark Pay creates its Bark wallet on mainnet the first time it starts, so plan to [back up the wallet](/docs/bark-pay/backups) right after. ## Before you start You need: * A server with [Docker Engine](https://docs.docker.com/engine/install/) and the Docker Compose plugin, on x86\_64 or arm64. * [Git](https://git-scm.com/downloads/). * A domain name pointing at the server. > **Deploying on Railway instead?** > > Follow the [Railway README](https://gitlab.com/ark-bitcoin/labs/bark-pay/-/tree/master/deploy/railway) in the repository, then continue with [Back up your wallet](/docs/bark-pay/backups). > [!NOTE] > > The values below connect Bark Pay to Second's mainnet Ark server, so charges move real bitcoin from the first sat. To try Bark Pay with test bitcoin first, [add test mode](#add-test-mode) once the stack runs. ## Configure and start the stack **1. Clone the repository** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} git clone https://gitlab.com/ark-bitcoin/labs/bark-pay.git cd bark-pay ``` **2. Create the environment file** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} cp .env.example .env ``` **3. Set the public URL, the admin account, and the Ark endpoints** Open `.env` and delete the leading `#` from the two `BARKD_MAINNET_` lines, so they take effect. Replace `pay.example.com`, the email, and the password with your own, and leave both `BARKD_MAINNET_` URLs as shown. Leave the `#` in front of `BARKD_MAINNET_ACCESS_TOKEN`. ```bash .env theme={"theme":{"light":"github-light","dark":"github-dark"}} BARKPAY_PUBLIC_URL=https://pay.example.com BARKPAY_ADMIN_EMAIL=you@example.com BARKPAY_ADMIN_PASSWORD=<12 or more characters> BARKD_MAINNET_ARK_SERVER=https://ark.second.tech BARKD_MAINNET_ESPLORA=https://mempool.second.tech/api ``` Bark Pay creates the admin account from these two values while no admin exists, and ignores them afterwards. The password needs 12 or more characters and can't contain a common word such as `password`, `admin`, or `barkpay`. Otherwise Bark Pay refuses to start. **4. Start Barkd** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} docker compose -f docker/docker-compose.prod.yml up -d --build barkd-mainnet ``` **5. Copy the Barkd access token into .env** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} docker compose -f docker/docker-compose.prod.yml exec barkd-mainnet barkd secret show ``` Paste the printed value into `.env` as `BARKD_MAINNET_ACCESS_TOKEN`. **6. Start Bark Pay** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} docker compose -f docker/docker-compose.prod.yml up -d --build ``` The first build takes a few minutes. **7. Check that Bark Pay is ready** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} curl -s http://127.0.0.1:8080/ready ``` The endpoint answers `{"status":"ready"}`. To follow the first start, run `docker compose -f docker/docker-compose.prod.yml logs -f bark-pay`. > [!NOTE] > > Bark Pay only starts with the access token in `.env`. If you start the whole stack before copying it, the `bark-pay` container restarts in a loop until you add the token and run the start command again. ## Serve Bark Pay over HTTPS Bark Pay listens on plain HTTP on port 8080. > [!WARNING] > > Put Bark Pay behind HTTPS before you sign in. Over plain HTTP, your password travels unencrypted. Anyone who captures it can sign in and send payouts from your wallet. **Your own reverse proxy** Point your proxy (nginx, Traefik, or a Cloudflare tunnel) at port 8080 on the server, terminate TLS there, and set `BARKPAY_TRUSTED_PROXY_HOPS=2` in `.env`. Then recreate the container: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} docker compose -f docker/docker-compose.prod.yml up -d bark-pay ``` **Bundled Caddy** Let the Caddy bundled in the image obtain a Let's Encrypt certificate itself: **1. Edit the Caddyfile** In `docker/Caddyfile`, replace `:{$PORT:8080}` with your domain and delete the `auto_https off` line. **2. Publish ports 80 and 443** In `docker/docker-compose.prod.yml`, replace the `ports` entry of the `bark-pay` service with `- "80:80"` and `- "443:443"`. **3. Rebuild** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} docker compose -f docker/docker-compose.prod.yml up -d --build ``` Leave `BARKPAY_TRUSTED_PROXY_HOPS=1` in `.env`. ## Sign in to the dashboard Open your domain in a browser and sign in with the email and password from `.env`. ![Screenshot of the Bark Pay Overview page, with the My Bark Wallet balance card, the Today's volume card, and the Recent charges table](https://mintcdn.com/second-0659a37d/w3x3inV3jE1Buo4A/images/bark-pay/overview.png?fit=max\&auto=format\&n=w3x3inV3jE1Buo4A\&q=85\&s=abfaced16950ec93d5efb2b30dcb7def) After sign-in, Overview shows the wallet balance and the latest charges ## Add test mode Test mode needs a second Barkd on signet: **1. Add a signet Barkd to the stack** In `docker/docker-compose.prod.yml`, copy the whole `barkd-mainnet` service under the name `barkd-signet`, point its volume at `barkd_signet_data`, and declare that volume next to the other two: ```yaml docker/docker-compose.prod.yml theme={"theme":{"light":"github-light","dark":"github-dark"}} volumes: barkpay_data: barkd_mainnet_data: barkd_signet_data: ``` **2. Configure the signet instance in .env** Delete the leading `#` from the `BARKD_SIGNET_` lines, and leave these values as they are: ```bash .env theme={"theme":{"light":"github-light","dark":"github-dark"}} BARKD_SIGNET_URL=http://barkd-signet:3000 BARKD_SIGNET_NETWORK=signet BARKD_SIGNET_ARK_SERVER=https://ark.signet.2nd.dev BARKD_SIGNET_ESPLORA=https://esplora.signet.2nd.dev ``` **3. Start the signet Barkd** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} docker compose -f docker/docker-compose.prod.yml up -d --build barkd-signet ``` **4. Copy its access token into .env** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} docker compose -f docker/docker-compose.prod.yml exec barkd-signet barkd secret show ``` Paste the printed value into `.env` as `BARKD_SIGNET_ACCESS_TOKEN`. **5. Restart Bark Pay** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} docker compose -f docker/docker-compose.prod.yml up -d bark-pay ``` Bark Pay creates the signet wallet on this start. Switch to **Test mode** in the sidebar footer to work against it. # Integrate Bark Pay with your app Source: https://second.tech/docs/bark-pay/integrate Connect your app to Bark Pay: create an API key, open a checkout session from your server, verify webhook signatures, and fulfill orders when a charge is paid. Build against test mode first, where `sk_test_` keys reach the signet wallet. The **Developers** > **Quickstart** page runs the three steps below against it. ## Create an API key **1. Switch to the mode you need** Use the switch in the sidebar footer. A key belongs to the mode you created it in: `sk_test_` keys reach the signet wallet, `sk_live_` keys reach the mainnet wallet. See [test mode](/docs/bark-pay/settings#switch-between-live-and-test-mode). **2. Go to Developers > API keys** **3. Select Create key** **4. Leave Type on Secret (sk\_)** **5. Enter a label (optional)** **6. Select Create key at the bottom of the drawer** Copy the key now. The dashboard shows it once, so store it like a password. ![Screenshot of the API key created drawer, with the full secret key in a copy field and the Done button](https://mintcdn.com/second-0659a37d/w3x3inV3jE1Buo4A/images/bark-pay/api-key-created.png?fit=max\&auto=format\&n=w3x3inV3jE1Buo4A\&q=85\&s=83e18d98833d5b11fb23451ac4cba868) The full key appears once, right after creation To retire a key, select **Revoke** on its row, then **Revoke key**. Every integration using it stops working immediately. ## Create a checkout session Send the key as a bearer token. In the snippets below, replace `pay.example.com` with your Bark Pay domain, `sk_test_...` with your secret key, and the `myshop.example` URLs with your own. The `Idempotency-Key` header makes a retried request return the same session instead of creating a second charge. Bark Pay stores every key and replays the first response, even after that session expires. Use a new key for each checkout attempt, for example the order ID plus an attempt number. ```bash curl theme={"theme":{"light":"github-light","dark":"github-dark"}} curl -X POST https://pay.example.com/v1/checkout/sessions \ -H "Authorization: Bearer sk_test_..." \ -H "Content-Type: application/json" \ -H "Idempotency-Key: order-1234-1" \ -d '{ "amountSat": 1000, "description": "Order #1234", "reference": "order-1234", "successUrl": "https://myshop.example/thanks", "cancelUrl": "https://myshop.example/cart" }' ``` ```js Node theme={"theme":{"light":"github-light","dark":"github-dark"}} const res = await fetch("https://pay.example.com/v1/checkout/sessions", { method: "POST", headers: { Authorization: "Bearer sk_test_...", "Content-Type": "application/json", "Idempotency-Key": `${orderId}-${attempt}`, // one key per checkout attempt }, body: JSON.stringify({ amountSat: 1000, description: "Order #1234", reference: orderId, successUrl: "https://myshop.example/thanks", cancelUrl: "https://myshop.example/cart", }), }); const session = await res.json(); // redirect the customer to session.url ``` Redirect your customer to `url` in the response: ```json Response theme={"theme":{"light":"github-light","dark":"github-dark"}} { "object": "checkout_session", "id": "cs_0123456789abcdef01234567", "chargeId": "ch_9f1c2b3a4d5e6f708192a3b4", "url": "https://pay.example.com/c/cs_0123456789abcdef01234567", "successUrl": "https://myshop.example/thanks", "cancelUrl": "https://myshop.example/cart", "customerEmail": null, "status": "open", "createdAt": 1789000000, "charge": { "object": "charge", "id": "ch_9f1c2b3a4d5e6f708192a3b4", "status": "pending", "amountSat": 1000, "...": "..." } } ``` The request body accepts these fields: | Field | Type | Description | | - | - | - | | `amountSat` | integer | Amount in sats. Provide either `amountSat`, or `amount` with `currency`. | | `amount` | number | Amount in fiat. Bark Pay converts it to sats at the current Kraken rate and locks that rate on the charge. | | `currency` | string | `usd`, `eur`, or `gbp`. Required with `amount`. | | `description` | string | Shown to your customer at checkout. Up to 500 characters. | | `reference` | string | Your own identifier, for example an order number. Up to 200 characters. Bark Pay returns it in webhooks. | | `rails` | string\[] | Restrict the payment methods: any of `lightning`, `ark`, `onchain`. Omit to offer every method that fits the amount. | | `expiresIn` | integer | Seconds before the charge expires. Defaults to the **Invoice TTL** in [Settings](/docs/bark-pay/settings#charge-defaults). At most 86,400. | | `successUrl` | string | Where the hosted page sends your customer after payment. Must be `http` or `https`. | | `cancelUrl` | string | Where the **Return** link on an expired or cancelled page points. Must be `http` or `https`. | | `customerEmail` | string | Stored on the session for your records. | | `metadata` | object | Free-form JSON, returned in the charge object and in webhooks. | > [!NOTE] > > To render your own checkout instead of the hosted page, call `POST /v1/charges` with the same fields except `successUrl`, `cancelUrl`, and `customerEmail`. The charge object carries a `rails` array with the Lightning invoice, Ark address, and on-chain address. It also carries a `clientSecret`, which your browser code sends as an `X-Client-Secret` header to poll `GET /v1/charges/{id}/status`. ## Listen for webhooks Fulfill orders from the `charge.paid` and `charge.overpaid` webhooks, never from your customer landing on your success URL. A customer can skip, replay, or forge that redirect. **1. Go to Developers > Webhooks** **2. Select Add endpoint** **3. Enter your endpoint URL** Bark Pay refuses to deliver to local and private addresses, so use a tunnel such as cloudflared or ngrok during development. **4. Tick the event types you need, or leave them all unticked to receive every event** **5. Select Create endpoint** Copy the signing secret now. The dashboard shows it once. To change it later, delete the endpoint and create a new one. ![Screenshot of the Add webhook endpoint drawer, with the Endpoint URL field, one checkbox per event type, and the Create endpoint button](https://mintcdn.com/second-0659a37d/w3x3inV3jE1Buo4A/images/bark-pay/webhook-create.png?fit=max\&auto=format\&n=w3x3inV3jE1Buo4A\&q=85\&s=b26afd9d3340eddd6ac506ed7b7fdac9) Tick nothing to receive every event type on the endpoint Each endpoint row carries four actions: * **Test:** Sends a signed `webhook.test` event. * **Deliveries:** Lists each event sent to the endpoint, with its status, number of attempts, and last response code. * **Disable:** Stops delivery without deleting the endpoint. Events that fire while it's disabled never reach it, even after you select **Enable**, so fetch them with `GET /v1/events`. * **Delete:** Removes the endpoint. ### Verify the signature Every delivery carries a `Bark-Signature` header. The scheme matches Stripe's, so a Stripe verifier works if you pass it this header's value. Verify the raw body before parsing it, replacing `whsec_...` with the signing secret you copied and `/webhooks/barkpay` with your own path: ```js server.js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { createHmac, timingSafeEqual } from "node:crypto"; import express from "express"; const SECRET = "whsec_..."; const app = express(); function verify(header, rawBody, toleranceSec = 300) { const parts = Object.fromEntries( header.split(",").map((p) => p.split("=", 2)) ); const t = Number(parts.t); if (!parts.v1 || Math.abs(Date.now() / 1000 - t) > toleranceSec) { return false; } const expected = createHmac("sha256", SECRET) .update(`${parts.t}.${rawBody}`) .digest("hex"); const a = Buffer.from(expected); const b = Buffer.from(parts.v1); return a.length === b.length && timingSafeEqual(a, b); } // raw body required: express.json() would break the HMAC app.post("/webhooks/barkpay", express.raw({ type: "*/*" }), (req, res) => { const raw = req.body.toString("utf8"); if (!verify(req.header("Bark-Signature") ?? "", raw)) { return res.status(400).send("bad signature"); } const event = JSON.parse(raw); // dedupe by event.id: retries and ordering are not guaranteed const charge = event.data.object; const paid = ["paid", "paid_late", "overpaid"].includes(charge.status); if ((event.type === "charge.paid" || event.type === "charge.overpaid") && paid) { // fulfill the order for charge.reference, once per charge.id } res.sendStatus(200); // non-2xx means Bark Pay retries with backoff }); ``` ### Handle each event type The body carries the event `id`, `type`, `livemode`, `created`, and `data.object`, the charge or checkout session as it was after the event: | Event | When Bark Pay sends it | | - | - | | `charge.created` | Bark Pay created a charge. | | `charge.paid` | The full amount arrived, before or after expiry. For an on-chain payment, Bark Pay sends it once the transaction has one confirmation. | | `charge.underpaid` | Less than the amount arrived. The payment methods stay open for a top-up until the charge expires. | | `charge.overpaid` | More than the amount arrived, including an extra payment on a paid charge. Any payment to a cancelled charge also sends it. The charge stays `cancelled`. | | `charge.expired` | The charge expired without receiving anything. | | `charge.cancelled` | Your server cancelled the charge through the API. | | `checkout.session.completed` | Your customer paid the session's charge in full while the session was open. | | `checkout.session.expired` | The session's charge expired, or your server cancelled it. | Charge events carry the charge's status in `data.object.status`. See [Follow a charge's status](/docs/bark-pay/charges#follow-a-charges-status) for what each one means. ### Recover from a failed delivery Answer with a 2xx status within 10 seconds. Bark Pay tries each delivery up to 12 times, backing off from 10 seconds to 2 hours, then gives up. Process events idempotently by `event.id`. If your endpoint was down, select **Resend** on the **Deliveries** sheet, or fetch what you missed with `GET /v1/events` and your secret key. ## Cancel a charge Cancel a pending or underpaid charge from your server. Replace `ch_...` with the charge ID: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} curl -X POST https://pay.example.com/v1/charges/ch_.../cancel \ -H "Authorization: Bearer sk_test_..." ``` The response is the charge with status `cancelled`. ## Read and list charges * `GET /v1/charges/{id}` returns one charge. * `GET /v1/charges` lists charges newest first, with `status`, `limit` (up to 100), and `starting_after` (a charge ID) as query parameters. The response has `data` and `hasMore`. Errors come back as `{ "error": { "type": "api_error", "code": "...", "message": "...", "param": "..." } }`. # Configure Bark Pay Source: https://second.tech/docs/bark-pay/settings Set the charge expiry and amount tolerance, switch the dashboard between live and test mode, review the audit log, and change your Bark Pay admin password. Configure Bark Pay on the **Rates** and **Settings** pages in the sidebar. A new **Invoice TTL** applies to charges created afterwards. A new amount tolerance applies to every payment that arrives afterwards, including payments to charges already open. ## Rates Select **Rates** in the sidebar, then set these on the **Rate source** card: * **Source:** Kraken. It's the only source, so the field is locked. * **Amount tolerance (bps):** How far a payment may differ from the charge amount and still count as paid. 100 bps is 1%, and the default of 0 requires the exact amount. Select **Save** to apply. ## Audit log Select **Audit log** in the sidebar to see one row per admin action: what was done, the object it touched, the IP address behind it, and when it happened. ## Settings ![Screenshot of the Settings page, with the Appearance card, the Charge defaults card holding the Invoice TTL field, and the Change password card](https://mintcdn.com/second-0659a37d/w3x3inV3jE1Buo4A/images/bark-pay/settings.png?fit=max\&auto=format\&n=w3x3inV3jE1Buo4A\&q=85\&s=4478f64825e29e911e30085ed78c02a9) Settings holds the charge defaults and your admin password ### Appearance Go to **Settings** > **Appearance** for the preferences your browser stores: * **Theme:** Light, Dark, or System. * **Bitcoin unit:** Satoshi, Bitcoin (BTC), or Bitcoin (₿). The same balance reads `12,345 sats`, `0.00012345 BTC`, or `₿12,345`. * **Display currency:** USD or EUR, for the fiat value on Overview and the default currency of new fiat-priced charges. ### Charge defaults Go to **Settings** > **Charge defaults** and set **Invoice TTL**, how long a new charge stays payable, in seconds. The default is 900, or 15 minutes, and the maximum is 86,400. Select **Save defaults** to apply. ### Change password **1. Go to Settings > Change password** **2. Enter your current password and a new one of at least 12 characters** Bark Pay rejects a new password that contains a common word such as `password`, `admin`, or `barkpay`. **3. Select Change password** Bark Pay signs out every session, including yours. To sign out without changing anything, select your email in the sidebar footer, then **Log out**. > [!NOTE] > > After five failed sign-in attempts, Bark Pay slows every further attempt on the account for 15 minutes. Each new failure restarts the wait. The right password still signs you in. ## Switch between live and test mode Switch from **Live mode** to **Test mode** in the sidebar footer to work against the signet wallet you [added during installation](/docs/bark-pay/install#add-test-mode). Each browser remembers its own mode. An amber banner reads **Test mode — showing signet / test data** while it's on, and charges, API keys, webhooks, and events all switch with it. Get free signet sats from [Second's faucet](https://signet.2nd.dev/). # Update or remove Bark Pay Source: https://second.tech/docs/bark-pay/update Pull a new Bark Pay version and rebuild the stack without losing your wallet or charges, or stop and remove Bark Pay after moving your bitcoin out. Run every command below from the repository you cloned during installation. ## Update Bark Pay **1. Pull the new version** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} git pull ``` **2. Rebuild and restart the stack** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} docker compose -f docker/docker-compose.prod.yml up -d --build ``` > [!NOTE] > > Some releases sign every admin out. Read the [changelog](https://gitlab.com/ark-bitcoin/labs/bark-pay/-/blob/master/CHANGELOG.md) before updating, and sign in again afterwards if needed. ## Stop Bark Pay ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} docker compose -f docker/docker-compose.prod.yml down ``` To start it again, run the same command as during [installation](/docs/bark-pay/install#configure-and-start-the-stack). ## Remove Bark Pay for good > [!WARNING] > > Removing the volumes deletes the Barkd wallet and its seed phrase. First move your bitcoin to a wallet you control with [manual payouts](/docs/bark-pay/wallet#manual-payout), including an On-chain payout for the on-chain rows. Then check that every row on the wallet card reads zero. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} docker compose -f docker/docker-compose.prod.yml down -v ``` # Manage your Bark Pay wallet Source: https://second.tech/docs/bark-pay/wallet Read the balances of your Bark Pay wallet, deposit bitcoin to it, and send manual payouts over Lightning, Ark, or on-chain from the Wallet page. Customer payments settle into the wallet of the charge's mode, live or test. You pay out from that same wallet. ![Screenshot of the Wallet page, with the My Bark Wallet card listing the balance rows and the Ark and on-chain deposit addresses, and the Manual payout form](https://mintcdn.com/second-0659a37d/w3x3inV3jE1Buo4A/images/bark-pay/wallet.png?fit=max\&auto=format\&n=w3x3inV3jE1Buo4A\&q=85\&s=8852dc9dfb3cbeb69b2153d918d2764b) One card per wallet: balances, deposit addresses, and the payout form ## Read your balances The wallet card, titled **My Bark Wallet** in live mode and **signet** in test mode, lists one row per state: | Balance | What it holds | | - | - | | Spendable | What you can pay out over Lightning or Ark. | | Pending board | Bitcoin from a [board](/docs/learn/board) waiting for on-chain confirmations. Bark Pay never boards on-chain payments on its own. | | Pending in round | Bitcoin in a [round](/docs/learn/rounds) that hasn't completed. | | Pending LN send | A Lightning payout that hasn't settled. | | Claimable LN receive | A Lightning payment Barkd has yet to claim. | | On-chain spendable | Bitcoin in Barkd's on-chain wallet that an On-chain payout can spend. | | On-chain pending | An on-chain payment that hasn't confirmed yet. | On-chain payments, to a charge or to the on-chain deposit address, land in Barkd's separate on-chain wallet, shown in the two on-chain rows. They leave it only through an [On-chain payout](#manual-payout). ## Deposit bitcoin The wallet card shows two deposit addresses. Copy the one that matches how you want to send: * **Ark deposit address:** For a payment from a wallet app on the same Ark server. It arrives in the spendable balance. * **On-chain deposit address:** For a regular on-chain payment. It lands in [Barkd's on-chain wallet](#read-your-balances). ## Manual payout Use **Manual payout** to move bitcoin out: to your own cold storage, to a supplier, or to refund a customer. > [!NOTE] > > The dashboard accepts at most ten payouts per minute from one IP address. **1. Select the rail** * **Lightning:** Pays a BOLT11 invoice, a BOLT12 offer, or a Lightning address. * **Ark:** Pays an Ark address on the same Ark server. * **On-chain:** Pays an on-chain address from Barkd's on-chain wallet. **2. Paste the destination** Paste a bare invoice, offer, or address, not a `bitcoin:` payment link. If it belongs to another rail, Bark Pay tells you which one to select. **3. Enter the amount in sats** A BOLT11 invoice with a fixed amount fills the field and locks it. A Lightning address always needs an amount, even though the field reads optional. **4. Select Review payout** The **Confirm payout** drawer summarizes the amount, rail, wallet, and destination. **5. Select Send payout** A **Payout sent.** toast confirms that Barkd accepted it. A Lightning payout stays under **Pending LN send** until it settles. > [!WARNING] > > A payout cannot be undone once sent. If Bark Pay reports that the send outcome is unknown, check whether the payout went through before you retry, so you don't pay twice. For a Lightning or Ark payout, reload the Wallet page and check the **Spendable** row. For an On-chain payout, look up the destination address in a block explorer. Sends to an Ark address are free. Lightning sends carry the Ark server's [fees](/docs/learn/fees), which scale with the amount and your VTXOs' remaining lifetime. On-chain sends pay the usual miner fee. See [Second's pricing](https://second.tech/pricing). # Get started with Dart Source: https://second.tech/docs/bark-sdk/dart Add Ark payments to your Dart or Flutter app. Create a wallet, generate addresses, and check your balance in minutes. Use this prompt to get started quickly. # Bark SDK: Dart Build Ark wallet apps in Dart or Flutter with the `bark_bitcoin` package. Ark is a bitcoin layer 2 protocol for instant, low-fee, self-custodial payments. ## Prerequisites * Dart SDK 3.10+ or Flutter 3.38.1+ * Rust, installed with rustup * `protoc` (the Protocol Buffers compiler) on the `PATH` ## Install (Dart) ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} dart pub add bark_bitcoin ``` ## Install (Flutter) ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} flutter pub add bark_bitcoin path_provider ``` ```xml theme={"theme":{"light":"github-light","dark":"github-dark"}} com.apple.security.network.client ``` ## Create a wallet In a Dart console app, save this program as `bin/main.dart`: ```dart theme={"theme":{"light":"github-light","dark":"github-dark"}} import 'dart:io'; import 'package:bark_bitcoin/bark_bitcoin.dart'; Future main() async { // Signet tests only: don't store a real mnemonic in an unencrypted file final mnemonicFile = File('bark-mnemonic'); final String mnemonic; if (mnemonicFile.existsSync()) { mnemonic = mnemonicFile.readAsStringSync(); } else { mnemonic = generateMnemonic(); mnemonicFile.writeAsStringSync(mnemonic); } // Configure the signet endpoints final config = Config( serverAddress: 'https://ark.signet.2nd.dev', esploraAddress: 'https://esplora.signet.2nd.dev', ); // Create the wallet in datadir, or reopen it on later launches final wallet = await Wallet.open( network: Network.signet, mnemonicOrSeed: mnemonic, config: config, args: WalletOpenArgs(datadir: 'bark-data'), ); } ``` In a Flutter app, run the same calls in an `openWallet()` function that builds the mnemonic file path and `datadir` from `getApplicationSupportDirectory()` (`path_provider` package) and returns the wallet. Store the wallet in a top-level `late final Wallet wallet` that `main()` assigns once, after `WidgetsFlutterBinding.ensureInitialized()` and before `runApp()`. Widgets use `wallet` directly. On Android, also override `provideFlutterEngine()` in `MainActivity` to return one `FlutterEngine` per process, cached in `FlutterEngineCache`. ## Get address and check balance Add these lines at the end of `main()`. In a Flutter app, add them to `main()` after `wallet = await openWallet();` and before `runApp()`, with `debugPrint()` instead of `print()`: ```dart theme={"theme":{"light":"github-light","dark":"github-dark"}} final address = await wallet.newAddress(); print('Ark address: $address'); await wallet.sync_(); final balance = await wallet.balance(); print('Spendable: ${balance.spendableSats} sats'); ``` Run it with `dart run bin/main.dart`, or with `flutter run` in a Flutter app. ## Signet test environment * Ark server: [https://ark.signet.2nd.dev](https://ark.signet.2nd.dev) * Esplora API: [https://esplora.signet.2nd.dev](https://esplora.signet.2nd.dev) * Faucet for test bitcoin: [https://signet.2nd.dev/](https://signet.2nd.dev/) * Network enum: `Network.signet` ## Rules * Open wallets with `Wallet.open(network: ..., mnemonicOrSeed: ..., config: ..., args: WalletOpenArgs(datadir: ...))`. All four named arguments are required. The call creates the wallet on first launch and reopens it afterwards. There is no `Wallet.create()`. * `Config` takes named parameters. Set `serverAddress` and `esploraAddress`. The constructor only requires `serverAddress`, but `Wallet.open()` throws without an Esplora URL. Leave out the `bitcoind*` fields. This SDK supports Esplora only. The network is the `network` argument of `Wallet.open()`, not a `Config` field. * `datadir` is a plain directory path. Bark creates the directory if it doesn't exist. * Reuse the same mnemonic on every launch. `Wallet.open()` throws if the mnemonic doesn't match the wallet stored in `datadir`. * The sync method is `sync_()`, with a trailing underscore. * Balance amounts are `int` values, in sats. * Most wallet methods return a `Future`. Always `await` them inside an `async` function. Dart has no top-level `await`. * In a Flutter app, build `datadir` and file paths from `getApplicationSupportDirectory()` (`path_provider` package), not from relative paths. Call `WidgetsFlutterBinding.ensureInitialized()` first. * In a Flutter app, open the wallet once in `main()`, before `runApp()`, and share that instance. Never open it in `build()`, `initState()`, or other widget code that can run more than once. A second `Wallet.open()` on the same `datadir` throws while the first wallet is open. * In a production Flutter app, call `sync_()` and `balance()` from a widget after `runApp()`, so the first screen doesn't wait for the sync. * On Android, override `provideFlutterEngine()` in the Flutter app's `MainActivity` to return one `FlutterEngine` per process, cached in `FlutterEngineCache`. Android can close the activity but keep the process, for example on Back. Without the cached engine, reopening the app runs `main()` again, and `Wallet.open()` throws. * In a Flutter app, declare the `INTERNET` permission in `android/app/src/main/AndroidManifest.xml`. Flutter's template declares it only in the debug and profile manifests. Without it, release builds can't reach the Ark server. On macOS, add the `com.apple.security.network.client` entitlement to both `macos/Runner/DebugProfile.entitlements` and `macos/Runner/Release.entitlements`. * The first build compiles the Rust core from source and can take about 15 minutes. Don't interrupt it. * The build needs `rustup`, and `protoc` on the `PATH`. Dart build hooks don't pass the `PROTOC` environment variable through. * Use `Network.signet` for testing. Mainnet is `Network.bitcoin`. Never use mainnet without user confirmation. * Never hardcode or log mnemonics in production code. * Correct terminology: Ark (not ARC), VTXO (not vtxo), on-chain (not onchain), off-chain (not offchain). * "Bark" (capitalized) in prose, "bark" (lowercase) for CLI commands and repository names. > [!TIP] > > These examples connect to **signet** so you can test for free. To go live, point the same configuration at Second's mainnet endpoints from [Connection details](/docs/connection-details) and select the mainnet network. ## Prerequisites * Dart SDK 3.10+, or Flutter 3.38.1+ * Rust, installed with [rustup](https://rustup.rs) * `protoc`, the Protocol Buffers compiler, on your `PATH` Install `protoc` for your platform: **macOS** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} brew install protobuf ``` **Debian and Ubuntu** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} sudo apt install protobuf-compiler ``` **Windows** Download `protoc--win64.zip` from the [protobuf releases](https://github.com/protocolbuffers/protobuf/releases) and extract it. Then add its `bin` folder to your `PATH`. ## Getting started **1. Install the SDK** In your project directory, run: **Dart** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} dart pub add bark_bitcoin ``` **Flutter** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} flutter pub add bark_bitcoin path_provider ``` On Android, give your app internet access in `android/app/src/main/AndroidManifest.xml`: ```xml theme={"theme":{"light":"github-light","dark":"github-dark"}} ``` On macOS, allow outgoing network connections in both `macos/Runner/DebugProfile.entitlements` and `macos/Runner/Release.entitlements`: ```xml theme={"theme":{"light":"github-light","dark":"github-dark"}} com.apple.security.network.client ``` **2. Create a wallet** Generate a BIP39 mnemonic, configure the signet endpoints, and open the wallet in a data directory. `Wallet.open()` creates the wallet on the first launch and reopens it on later ones. **Dart** Save this program as `bin/main.dart`: ```dart theme={"theme":{"light":"github-light","dark":"github-dark"}} import 'dart:io'; import 'package:bark_bitcoin/bark_bitcoin.dart'; Future main() async { // Signet tests only: don't store a real mnemonic in an unencrypted file final mnemonicFile = File('bark-mnemonic'); final String mnemonic; if (mnemonicFile.existsSync()) { mnemonic = mnemonicFile.readAsStringSync(); } else { mnemonic = generateMnemonic(); mnemonicFile.writeAsStringSync(mnemonic); } // Configure the signet endpoints final config = Config( serverAddress: 'https://ark.signet.2nd.dev', esploraAddress: 'https://esplora.signet.2nd.dev', ); // Create the wallet in datadir, or reopen it on later launches final wallet = await Wallet.open( network: Network.signet, mnemonicOrSeed: mnemonic, config: config, args: WalletOpenArgs(datadir: 'bark-data'), ); } ``` **Flutter** In `lib/main.dart`, replace the `import` line and `main()` with this code. `main()` opens the wallet once, before `runApp()`, and stores it in `wallet` for all your widgets to use: ```dart theme={"theme":{"light":"github-light","dark":"github-dark"}} import 'dart:io'; import 'package:bark_bitcoin/bark_bitcoin.dart'; import 'package:flutter/material.dart'; import 'package:path_provider/path_provider.dart'; // Opened once in main(), then shared by all your widgets late final Wallet wallet; Future main() async { WidgetsFlutterBinding.ensureInitialized(); wallet = await openWallet(); runApp(const MyApp()); } Future openWallet() async { final dir = (await getApplicationSupportDirectory()).path; // Signet tests only: don't store a real mnemonic in an unencrypted file final mnemonicFile = File('$dir/bark-mnemonic'); final String mnemonic; if (mnemonicFile.existsSync()) { mnemonic = mnemonicFile.readAsStringSync(); } else { mnemonic = generateMnemonic(); mnemonicFile.writeAsStringSync(mnemonic); } // Configure the signet endpoints final config = Config( serverAddress: 'https://ark.signet.2nd.dev', esploraAddress: 'https://esplora.signet.2nd.dev', ); // Create the wallet in datadir, or reopen it on later launches return Wallet.open( network: Network.signet, mnemonicOrSeed: mnemonic, config: config, args: WalletOpenArgs(datadir: '$dir/bark-data'), ); } ``` On Android, leave the `package` line of `android/app/src/main/kotlin/.../MainActivity.kt` and replace the rest with this code: ```kotlin theme={"theme":{"light":"github-light","dark":"github-dark"}} import android.content.Context import io.flutter.embedding.android.FlutterActivity import io.flutter.embedding.engine.FlutterEngine import io.flutter.embedding.engine.FlutterEngineCache class MainActivity : FlutterActivity() { // Cache one Flutter engine per process, so main() opens the wallet only once override fun provideFlutterEngine(context: Context): FlutterEngine = FlutterEngineCache.getInstance().get("main") ?: FlutterEngine(context.applicationContext).also { FlutterEngineCache.getInstance().put("main", it) } } ``` > [!WARNING] > > The sample code stores the mnemonic in an unencrypted file so that the next launch reopens the same wallet. That is acceptable for signet tests only. In a production app, store the mnemonic in your platform's secure storage. Also set up [continuous wallet data backups](/docs/backups), so users can restore their wallet without the Ark server's cooperation. **3. Get a receiving address** Generate an Ark address to receive bitcoin. Add these lines at the end of `main()` in Dart. In Flutter, add them to `main()`, after `wallet = await openWallet();` and before `runApp()`: **Dart** ```dart theme={"theme":{"light":"github-light","dark":"github-dark"}} final address = await wallet.newAddress(); print('Ark address: $address'); ``` Run the program from your project directory: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} dart run bin/main.dart ``` **Flutter** ```dart theme={"theme":{"light":"github-light","dark":"github-dark"}} final address = await wallet.newAddress(); debugPrint('Ark address: $address'); ``` Start a device or emulator, then run the app from your project directory: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} flutter run ``` The first run compiles Bark's Rust core, which can take about 15 minutes. Your terminal then shows the Ark address. Send some signet sats to this address using [the faucet](https://signet.2nd.dev/). **4. Check your balance** Bark syncs the wallet in the background while it's open. Call `sync_()` when you need an up-to-date balance right away. Add these lines after the previous ones: **Dart** ```dart theme={"theme":{"light":"github-light","dark":"github-dark"}} await wallet.sync_(); final balance = await wallet.balance(); print('Spendable: ${balance.spendableSats} sats'); ``` Run `dart run bin/main.dart` again. **Flutter** ```dart theme={"theme":{"light":"github-light","dark":"github-dark"}} await wallet.sync_(); final balance = await wallet.balance(); debugPrint('Spendable: ${balance.spendableSats} sats'); ``` Press `q` in the `flutter run` terminal to stop the app, then run `flutter run` again. In a production app, call `sync_()` and `balance()` from a widget after `runApp()`, so your first screen doesn't wait for the sync. Balance amounts are `int` values. The second run reopens the same wallet and prints your spendable balance in sats. ## Next steps > **[Source code](https://gitlab.com/ark-bitcoin/bark-ffi-bindings/-/tree/master/dart)** > > Dart bindings source on GitLab. > **[How Ark works](/docs/learn/intro)** > > Learn about the protocol powering your wallet. # Get started with Go Source: https://second.tech/docs/bark-sdk/go Add Ark payments to your Go application. Create a wallet, generate addresses, and check your balance in minutes. Use this prompt to get started quickly. # Bark SDK: Go Build Ark wallet apps in Go with the `gitlab.com/ark-bitcoin/bark-ffi-bindings/golang/bark` package. Ark is a bitcoin layer 2 protocol for instant, low-fee, self-custodial payments. ## Prerequisites * Go 1.19+ * cgo enabled, with a C compiler on `PATH`: GCC or Clang, or MinGW-w64 GCC on Windows * macOS 14+ (amd64, arm64), Linux (amd64, arm64) with glibc 2.34+, or Windows (amd64) ## Install ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} go get gitlab.com/ark-bitcoin/bark-ffi-bindings/golang/bark ``` On macOS, also set this variable in the terminal you build from: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} export CGO_LDFLAGS="-framework CoreFoundation" ``` ## Create a wallet ```go theme={"theme":{"light":"github-light","dark":"github-dark"}} package main import ( "errors" "fmt" "log" "os" "path/filepath" "gitlab.com/ark-bitcoin/bark-ffi-bindings/golang/bark" ) func main() { if err := run(); err != nil { log.Fatal(err) } } func run() error { home, err := os.UserHomeDir() if err != nil { return err } appDir := filepath.Join(home, ".bark-quickstart") if err := os.MkdirAll(appDir, 0o700); err != nil { return err } // Signet tests only: don't store a real mnemonic in an unencrypted file mnemonicPath := filepath.Join(appDir, "bark-mnemonic") saved, err := os.ReadFile(mnemonicPath) mnemonic := string(saved) if errors.Is(err, os.ErrNotExist) { mnemonic, err = bark.GenerateMnemonic() if err == nil { err = os.WriteFile(mnemonicPath, []byte(mnemonic), 0o600) } } if err != nil { return err } // Configure the signet endpoints esploraAddress := "https://esplora.signet.2nd.dev" config := bark.Config{ ServerAddress: "https://ark.signet.2nd.dev", EsploraAddress: &esploraAddress, } // Create the wallet in datadir, or reopen it on later launches datadir := filepath.Join(appDir, "bark") wallet, err := bark.WalletOpen(bark.NetworkSignet, mnemonic, config, bark.WalletOpenArgs{ Datadir: datadir, CreateIfNotExists: true, RunDaemon: true, }) if err != nil { return err } // Stop the background daemon and release datadir when run() returns defer wallet.Destroy() fmt.Println("Wallet data directory:", datadir) return nil } ``` ## Get address and check balance Add this code at the end of `run()`, before `return nil`: ```go theme={"theme":{"light":"github-light","dark":"github-dark"}} address, err := wallet.NewAddress() if err != nil { return err } fmt.Println("Ark address:", address) if err := wallet.Sync(); err != nil { return err } balance, err := wallet.Balance() if err != nil { return err } fmt.Printf("Spendable: %d sats\n", balance.SpendableSats) ``` ## Signet test environment * Ark server: [https://ark.signet.2nd.dev](https://ark.signet.2nd.dev) * Esplora API: [https://esplora.signet.2nd.dev](https://esplora.signet.2nd.dev) * Faucet for test bitcoin: [https://signet.2nd.dev/](https://signet.2nd.dev/) * Network constant: `bark.NetworkSignet` ## Rules * Enable cgo. Go turns cgo off when you cross-compile and, since Go 1.20, when it finds no C compiler. The build then fails with `undefined: BarkLogger`. To cross-compile, set `CGO_ENABLED=1` and `CC` to a C cross-compiler. * Open wallets with `bark.WalletOpen(network, mnemonic, config, bark.WalletOpenArgs{...})`. With `CreateIfNotExists: true`, it creates the wallet on first launch and reopens it afterwards. There is no `bark.WalletCreate()`. * Always set `CreateIfNotExists: true` and `RunDaemon: true` in `bark.WalletOpenArgs`. Go sets every `bool` field you leave out to `false`. Without `CreateIfNotExists`, `WalletOpen()` fails on a new data directory with "wallet does not exist". Without `RunDaemon`, nothing syncs the wallet or refreshes expiring VTXOs in the background, so you must call `Maintenance()` yourself. * In `bark.Config`, set `ServerAddress` and `EsploraAddress`. Optional fields are pointers (`*string`, `*uint16`, ...), so pass `&esploraAddress`. `WalletOpen()` fails without an Esplora address. Leave the `Bitcoind*` fields unset. This SDK supports Esplora only. The network is the first argument of `WalletOpen()`, not a `Config` field. * Bark creates `Datadir` if it doesn't exist. Only one open wallet can use a data directory at a time, across all processes. A second `WalletOpen()` on the same `Datadir` fails with "another process is already using datadir" until you call `Destroy()` on the first wallet and its daemon has stopped. * Reuse the same mnemonic on every launch. `WalletOpen()` fails with "incorrect mnemonic" if it doesn't match the wallet stored in `Datadir`. * Call `defer wallet.Destroy()` right after `WalletOpen()` succeeds. `Destroy()` stops the background daemon and releases the data directory once the daemon has stopped. * Balance amounts are `uint64` values in sats. * Use `bark.NetworkSignet` for testing. Mainnet is `bark.NetworkBitcoin`. Never use mainnet without user confirmation. * Never hardcode or log mnemonics in production code. * Correct terminology: Ark (not ARC), VTXO (not vtxo), on-chain (not onchain), off-chain (not offchain). * "Bark" (capitalized) in prose, "bark" (lowercase) for the package name and CLI commands. > [!TIP] > > These examples connect to **signet** so you can test for free. To go live, point the same configuration at Second's mainnet endpoints from [Connection details](/docs/connection-details) and select the mainnet network. ## Prerequisites * Go 1.19+ * A C compiler on your `PATH` for [cgo](https://pkg.go.dev/cmd/cgo): GCC or Clang, or [MinGW-w64](https://www.mingw-w64.org/) GCC on Windows * macOS 14+ (Intel or Apple silicon), Linux (x86-64 or ARM64) with glibc 2.34+, or Windows (x86-64) ## Getting started **1. Install the SDK** In your module's directory, run: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} go get gitlab.com/ark-bitcoin/bark-ffi-bindings/golang/bark ``` On macOS, also set this variable in the terminal you build from: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} export CGO_LDFLAGS="-framework CoreFoundation" ``` **2. Create a wallet** Generate a BIP39 mnemonic, configure the signet endpoints, and open the wallet in a data directory. With `CreateIfNotExists: true`, `bark.WalletOpen()` creates the wallet on the first launch and reopens it on later ones. Set `CreateIfNotExists` and `RunDaemon` to `true`, as in the sample. Go sets every `bool` field you leave out to `false`. ```go main.go theme={"theme":{"light":"github-light","dark":"github-dark"}} package main import ( "errors" "fmt" "log" "os" "path/filepath" "gitlab.com/ark-bitcoin/bark-ffi-bindings/golang/bark" ) func main() { if err := run(); err != nil { log.Fatal(err) } } func run() error { home, err := os.UserHomeDir() if err != nil { return err } appDir := filepath.Join(home, ".bark-quickstart") if err := os.MkdirAll(appDir, 0o700); err != nil { return err } // Signet tests only: don't store a real mnemonic in an unencrypted file mnemonicPath := filepath.Join(appDir, "bark-mnemonic") saved, err := os.ReadFile(mnemonicPath) mnemonic := string(saved) if errors.Is(err, os.ErrNotExist) { mnemonic, err = bark.GenerateMnemonic() if err == nil { err = os.WriteFile(mnemonicPath, []byte(mnemonic), 0o600) } } if err != nil { return err } // Configure the signet endpoints esploraAddress := "https://esplora.signet.2nd.dev" config := bark.Config{ ServerAddress: "https://ark.signet.2nd.dev", EsploraAddress: &esploraAddress, } // Create the wallet in datadir, or reopen it on later launches datadir := filepath.Join(appDir, "bark") wallet, err := bark.WalletOpen(bark.NetworkSignet, mnemonic, config, bark.WalletOpenArgs{ Datadir: datadir, CreateIfNotExists: true, RunDaemon: true, }) if err != nil { return err } // Stop the background daemon and release datadir when run() returns defer wallet.Destroy() fmt.Println("Wallet data directory:", datadir) return nil } ``` Run it with `go run .` from your module's directory. If the build fails with `undefined: BarkLogger`, cgo is off. Put a C compiler on your `PATH`, check that `go env CGO_ENABLED` prints `1`, and run it again. > [!WARNING] > > The sample code stores the mnemonic in an unencrypted file so that the next launch reopens the same wallet. That is acceptable for signet tests only. In a production app, store the mnemonic in your platform's secure storage. Also set up [continuous wallet data backups](/docs/backups), so users can restore their wallet without the Ark server's cooperation. **3. Get a receiving address** Generate an Ark address to receive bitcoin. Add this code at the end of `run()`, before `return nil`: ```go theme={"theme":{"light":"github-light","dark":"github-dark"}} address, err := wallet.NewAddress() if err != nil { return err } fmt.Println("Ark address:", address) ``` Run `go run .` to print the address. Send some signet sats to this address using [the faucet](https://signet.2nd.dev/). **4. Check your balance** With `RunDaemon: true`, Bark syncs the wallet in the background while it's open. Call `Sync()` when you need an up-to-date balance right away. Add this code after the address code, before `return nil`: ```go theme={"theme":{"light":"github-light","dark":"github-dark"}} if err := wallet.Sync(); err != nil { return err } balance, err := wallet.Balance() if err != nil { return err } fmt.Printf("Spendable: %d sats\n", balance.SpendableSats) ``` Balance amounts are `uint64` values. Run `go run .` again. The program reopens the same wallet and prints your spendable balance in sats. ## Next steps > **[Source code](https://gitlab.com/ark-bitcoin/bark-ffi-bindings/-/tree/master/golang)** > > Go bindings source on GitLab. > **[How Ark works](/docs/learn/intro)** > > Learn about the protocol powering your wallet. # Bark SDK Source: https://second.tech/docs/bark-sdk/index Build a self-custodial wallet app for mobile, desktop, or the browser: a Rust core with TypeScript, Flutter, Swift, Kotlin, and Go bindings. The Bark SDK is a set of libraries for building self-custodial bitcoin wallet apps. Keys stay on the user's device, and your app talks directly to Ark servers. Use the Bark SDK when you're building: * Mobile wallet apps * Desktop wallet apps * Browser-based wallet apps * Wallets for custom or embedded hardware > [!TIP] > > If you're building bitcoin applications for server infrastructure, [try Barkd](/docs/barkd). ## Pick your platform Each guide below walks you through installing the SDK, creating a wallet, and making your first payment, then links to the full library reference. Rust is the core implementation; the others are bindings around it. > **[Rust ★](/docs/bark-sdk/rust)** > > Core library—most complete and performant. > **[TypeScript - Web](/docs/bark-sdk/wasm)** > > Browser apps and PWAs via WebAssembly. > **[TypeScript - React Native](/docs/bark-sdk/react-native)** > > Cross-platform iOS and Android apps. > **[Flutter](/docs/bark-sdk/dart)** > > Cross-platform mobile apps with Dart. > **[Swift](/docs/bark-sdk/swift)** > > Native iOS apps. > **[Kotlin](/docs/bark-sdk/kotlin)** > > Native Android apps. > **[Go](/docs/bark-sdk/go)** > > Native Go bindings. ## See it in action > **[Built with Bark](/docs/built-with-bark)** > > Mobile wallets and integrations shipping bitcoin payments with the Bark SDK. ## How it works The Bark SDK runs the core Rust library directly in your app, through UniFFI bindings on mobile and desktop, and through WebAssembly in the browser. Everything happens on-device: * **Keys stay on the device:** The user's private keys are generated and stored locally. * **Direct protocol access:** Your app communicates directly with Ark servers. * **No backend required:** You don't need to run any server infrastructure. > [!NOTE] > > The user's mnemonic alone can restore a wallet's balance, with the Ark server's cooperation. For a full restore that includes payment history and in-progress exits, and doesn't depend on the server, make sure your app also [makes continuous backups](/docs/backups) of the wallet database. # Get started with Kotlin Source: https://second.tech/docs/bark-sdk/kotlin Add Ark payments to your Android or JVM application. Create a wallet, generate addresses, and check your balance in minutes. Use this prompt to get started quickly. # Bark SDK: Kotlin Build Ark wallet apps in Kotlin for Android or the JVM with the `bark-android` and `bark-jvm` libraries. Ark is a bitcoin layer 2 protocol for instant, low-fee, self-custodial payments. ## Prerequisites * Android: API 24+ (Android 7.0), Kotlin 1.9+ * JVM: Linux x86-64 with glibc 2.34+, JDK 17+, Kotlin 1.9+ ## Install (Android) ```kotlin theme={"theme":{"light":"github-light","dark":"github-dark"}} // settings.gradle.kts dependencyResolutionManagement { repositories { google() mavenCentral() maven { url = uri("https://gitlab.com/api/v4/projects/78057981/packages/maven") } } } // Module build.gradle.kts dependencies { implementation("tech.second.bark:bark-android:0.25.0+bark-0.7.1") } ``` ```xml theme={"theme":{"light":"github-light","dark":"github-dark"}} ``` ## Install (JVM) ```kotlin theme={"theme":{"light":"github-light","dark":"github-dark"}} // build.gradle.kts repositories { mavenCentral() maven { url = uri("https://gitlab.com/api/v4/projects/78057981/packages/maven") } } dependencies { implementation("tech.second.bark:bark-jvm:0.25.0+bark-0.7.1") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1") } ``` ## Create a wallet In a Kotlin JVM app, save this program as `src/main/kotlin/Main.kt`: ```kotlin theme={"theme":{"light":"github-light","dark":"github-dark"}} import java.io.File import kotlinx.coroutines.runBlocking import uniffi.bark.Config import uniffi.bark.Network import uniffi.bark.Wallet import uniffi.bark.WalletOpenArgs import uniffi.bark.generateMnemonic fun main() = runBlocking { // Signet tests only: don't store a real mnemonic in an unencrypted file val mnemonicFile = File("bark-mnemonic") val mnemonic = if (mnemonicFile.exists()) { mnemonicFile.readText() } else { generateMnemonic().also { mnemonicFile.writeText(it) } } // Configure the signet endpoints val config = Config( serverAddress = "https://ark.signet.2nd.dev", serverAccessToken = null, esploraAddress = "https://esplora.signet.2nd.dev", bitcoindAddress = null, bitcoindCookiefile = null, bitcoindUser = null, bitcoindPass = null, vtxoRefreshExpiryThreshold = null, vtxoExitMargin = null, htlcRecvClaimDelta = null, fallbackFeeRate = null, roundTxRequiredConfirmations = null, daemonSyncIntervalSecs = null, offboardRequiredConfirmations = null, daemonManualSync = null, lightningReceiveClaimRetries = null, userAgent = null, vtxoKeyGapLimit = null, ) // Create the wallet in datadir, or reopen it on later launches val wallet = Wallet.open( Network.SIGNET, mnemonic, config, WalletOpenArgs(datadir = "bark-data", onchain = null), ) } ``` On Android, run the same calls in a `suspend` function that builds the mnemonic file path and `datadir` from `context.filesDir`. Open the wallet once per app process and share that instance. Cache it in an `object` behind a coroutine `Mutex`. Open it inside `withContext(NonCancellable)` so the open completes even if Android destroys the calling activity. Get the wallet from a coroutine, such as `lifecycleScope.launch { }`. ## Get address and check balance Add these lines at the end of `main()`: ```kotlin theme={"theme":{"light":"github-light","dark":"github-dark"}} val address = wallet.newAddress() println("Ark address: $address") wallet.sync() val balance = wallet.balance() println("Spendable: ${balance.spendableSats} sats") ``` ## Signet test environment * Ark server: [https://ark.signet.2nd.dev](https://ark.signet.2nd.dev) * Esplora API: [https://esplora.signet.2nd.dev](https://esplora.signet.2nd.dev) * Faucet for test bitcoin: [https://signet.2nd.dev/](https://signet.2nd.dev/) * Network enum: `Network.SIGNET` ## Rules * Use the `bark-android` artifact on Android and `bark-jvm` on the JVM. Both come from the GitLab Maven registry above, not from Maven Central. * `bark-jvm` runs on Linux x86-64 only, not on Windows or macOS. * On the JVM, add `kotlinx-coroutines-core` yourself. Without it, `runBlocking` doesn't compile. * On Android, declare the `INTERNET` permission. Without it, `Wallet.open()` can't reach the Ark server. * Open wallets with `Wallet.open(network, mnemonic, config, WalletOpenArgs(datadir = datadir, onchain = null))`. It creates the wallet on first launch and reopens it afterwards. There is no `Wallet.create()`. * The `Config` constructor has no default values. Pass every parameter, with `null` for the ones you don't set. Set `serverAddress` and `esploraAddress`. `Wallet.open()` fails without an Esplora URL. Leave the `bitcoind*` fields `null`. This SDK supports Esplora only. The network is the first argument of `Wallet.open()`, not a `Config` field. * `WalletOpenArgs` has no default for `onchain`. Pass `onchain = null` to open the wallet without an on-chain wallet. * `datadir` is a plain directory path. Bark creates the directory if it doesn't exist. * Only one open wallet can use a `datadir` at a time, even within one process. A second `Wallet.open()` on it fails with "another process is already using datadir". Open the wallet once per process and reuse it. On Android, hold it in a process-wide object rather than in an activity. Don't close it when Android destroys an activity, which happens on rotation and theme changes. * Reuse the same mnemonic on every launch. `Wallet.open()` fails with "incorrect mnemonic" if it doesn't match the wallet stored in `datadir`. * `Wallet.open()` and most `Wallet` methods are `suspend` functions, on Android and on the JVM. Call them from a coroutine: `runBlocking` in a JVM `main()`, or a scope such as `lifecycleScope` on Android. * Balance amounts are `ULong` values. * Bark syncs the wallet in the background while it's open. `wallet.close()` stops the background sync. Call it when you're done with the wallet. * Import the `uniffi.bark` classes you use by name. A star import (`uniffi.bark.*`) brings in `uniffi.bark.Exception`, which shadows `kotlin.Exception`. * Use `Network.SIGNET` for testing. Mainnet is `Network.BITCOIN`. Never use mainnet without user confirmation. * Never hardcode or log mnemonics in production code. * Correct terminology: Ark (not ARC), VTXO (not vtxo), on-chain (not onchain), off-chain (not offchain). * "Bark" (capitalized) in prose, "bark" (lowercase) for the package name and CLI commands. > [!TIP] > > These examples connect to **signet** so you can test for free. To go live, point the same configuration at Second's mainnet endpoints from [Connection details](/docs/connection-details) and select the mainnet network. ## Prerequisites * Android: API 24+ (Android 7.0), Kotlin 1.9+ * JVM: Linux x86-64 with glibc 2.34+, JDK 17+, Kotlin 1.9+ ## Getting started **1. Install the SDK** Add the GitLab Maven registry and the Bark dependency to your Gradle project. **Android** In your root `settings.gradle.kts`: ```kotlin theme={"theme":{"light":"github-light","dark":"github-dark"}} dependencyResolutionManagement { repositories { google() mavenCentral() maven { url = uri("https://gitlab.com/api/v4/projects/78057981/packages/maven") } } } ``` In your module `build.gradle.kts`: ```kotlin theme={"theme":{"light":"github-light","dark":"github-dark"}} dependencies { implementation("tech.second.bark:bark-android:0.25.0+bark-0.7.1") } ``` In `AndroidManifest.xml`, give your app internet access: ```xml theme={"theme":{"light":"github-light","dark":"github-dark"}} ``` **JVM** In your `build.gradle.kts`: ```kotlin theme={"theme":{"light":"github-light","dark":"github-dark"}} repositories { mavenCentral() maven { url = uri("https://gitlab.com/api/v4/projects/78057981/packages/maven") } } dependencies { implementation("tech.second.bark:bark-jvm:0.25.0+bark-0.7.1") // Provides runBlocking for the sample program implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1") } ``` **2. Create a wallet** Generate a BIP39 mnemonic, configure the signet endpoints, and open the wallet in a data directory. `Wallet.open()` creates the wallet on the first launch and reopens it on later ones. **Android** Add this code to your app. `WalletHolder` opens the wallet once per app process and gives every caller the same instance: ```kotlin theme={"theme":{"light":"github-light","dark":"github-dark"}} import android.content.Context import java.io.File import kotlinx.coroutines.NonCancellable import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.withContext import uniffi.bark.Config import uniffi.bark.Network import uniffi.bark.Wallet import uniffi.bark.WalletOpenArgs import uniffi.bark.generateMnemonic object WalletHolder { private val mutex = Mutex() private var wallet: Wallet? = null // Opens the wallet on the first call and returns the same instance afterwards suspend fun get(context: Context): Wallet = mutex.withLock { // Finish opening even if Android destroys the calling activity, for example on rotation wallet ?: withContext(NonCancellable) { openWallet(context).also { wallet = it } } } } private suspend fun openWallet(context: Context): Wallet { // Signet tests only: don't store a real mnemonic in an unencrypted file val mnemonicFile = File(context.filesDir, "bark-mnemonic") val mnemonic = if (mnemonicFile.exists()) { mnemonicFile.readText() } else { generateMnemonic().also { mnemonicFile.writeText(it) } } // Configure the signet endpoints val config = Config( serverAddress = "https://ark.signet.2nd.dev", serverAccessToken = null, esploraAddress = "https://esplora.signet.2nd.dev", bitcoindAddress = null, bitcoindCookiefile = null, bitcoindUser = null, bitcoindPass = null, vtxoRefreshExpiryThreshold = null, vtxoExitMargin = null, htlcRecvClaimDelta = null, fallbackFeeRate = null, roundTxRequiredConfirmations = null, daemonSyncIntervalSecs = null, offboardRequiredConfirmations = null, daemonManualSync = null, lightningReceiveClaimRetries = null, userAgent = null, vtxoKeyGapLimit = null, ) val datadir = File(context.filesDir, "bark").path // Create the wallet in datadir, or reopen it on later launches return Wallet.open( Network.SIGNET, mnemonic, config, WalletOpenArgs(datadir = datadir, onchain = null), ) } ``` Get the wallet from a coroutine, for example in your activity: ```kotlin theme={"theme":{"light":"github-light","dark":"github-dark"}} lifecycleScope.launch { val wallet = WalletHolder.get(applicationContext) } ``` **JVM** Save this program as `src/main/kotlin/Main.kt`: ```kotlin theme={"theme":{"light":"github-light","dark":"github-dark"}} import java.io.File import kotlinx.coroutines.runBlocking import uniffi.bark.Config import uniffi.bark.Network import uniffi.bark.Wallet import uniffi.bark.WalletOpenArgs import uniffi.bark.generateMnemonic fun main() = runBlocking { // Signet tests only: don't store a real mnemonic in an unencrypted file val mnemonicFile = File("bark-mnemonic") val mnemonic = if (mnemonicFile.exists()) { mnemonicFile.readText() } else { generateMnemonic().also { mnemonicFile.writeText(it) } } // Configure the signet endpoints val config = Config( serverAddress = "https://ark.signet.2nd.dev", serverAccessToken = null, esploraAddress = "https://esplora.signet.2nd.dev", bitcoindAddress = null, bitcoindCookiefile = null, bitcoindUser = null, bitcoindPass = null, vtxoRefreshExpiryThreshold = null, vtxoExitMargin = null, htlcRecvClaimDelta = null, fallbackFeeRate = null, roundTxRequiredConfirmations = null, daemonSyncIntervalSecs = null, offboardRequiredConfirmations = null, daemonManualSync = null, lightningReceiveClaimRetries = null, userAgent = null, vtxoKeyGapLimit = null, ) // Create the wallet in datadir, or reopen it on later launches val wallet = Wallet.open( Network.SIGNET, mnemonic, config, WalletOpenArgs(datadir = "bark-data", onchain = null), ) } ``` > [!WARNING] > > The sample code stores the mnemonic in an unencrypted file so that the next launch reopens the same wallet. That is acceptable for signet tests only. In a production app, store the mnemonic in your platform's secure storage. Also set up [continuous wallet data backups](/docs/backups), so users can restore their wallet without the Ark server's cooperation. **3. Get a receiving address** Generate an Ark address to receive bitcoin. Add these lines at the end of `main()` on the JVM, or after `WalletHolder.get()` in your coroutine on Android: ```kotlin theme={"theme":{"light":"github-light","dark":"github-dark"}} val address = wallet.newAddress() println("Ark address: $address") ``` Run the JVM program or your Android app to print the address. On Android, `println()` output appears in Logcat. Send some signet sats to this address using [the faucet](https://signet.2nd.dev/). **4. Check your balance** Bark syncs the wallet in the background while it's open. Call `sync()` when you need an up-to-date balance right away. Add these lines after the previous ones: ```kotlin theme={"theme":{"light":"github-light","dark":"github-dark"}} wallet.sync() val balance = wallet.balance() println("Spendable: ${balance.spendableSats} sats") ``` Balance amounts are `ULong` values. Run the program or app again. It reopens the same wallet and prints your spendable balance in sats. ## Next steps > **[Source code](https://gitlab.com/ark-bitcoin/bark-ffi-bindings/-/tree/master/kotlin)** > > Kotlin bindings source on GitLab. > **[How Ark works](/docs/learn/intro)** > > Learn about the protocol powering your wallet. # Get started with TypeScript for React Native Source: https://second.tech/docs/bark-sdk/react-native Add Ark payments to your React Native app with TypeScript. Create a wallet, generate addresses, and check your balance in minutes. Use this prompt to get started quickly. # Bark SDK: TypeScript for React Native Build Ark wallet apps in TypeScript with `@secondts/bark-react-native`. Ark is a bitcoin layer 2 protocol for instant, low-fee, self-custodial payments. ## Prerequisites * React Native 0.76+ with the New Architecture and Hermes enabled * iOS 15.1+ / Android API 24+ * Expo: SDK 52+ with a development build (Expo Go is not supported) ## Install (Expo) ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} npx expo install @secondts/bark-react-native ``` Add the plugin to `app.json`: `{ "expo": { "plugins": ["@secondts/bark-react-native"] } }`, then run `npx expo prebuild`. ## Install (Bare React Native) ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} npm install @secondts/bark-react-native cd ios && pod install && cd .. ``` If you use pnpm v10+, run `pnpm approve-builds` and select `@secondts/bark-react-native`. ## Create a wallet ```tsx theme={"theme":{"light":"github-light","dark":"github-dark"}} import { Config, Network, Wallet, WalletOpenArgs, generateMnemonic, } from "@secondts/bark-react-native"; import RNFS from "react-native-fs"; // Signet tests only: don't store a real mnemonic in an unencrypted file const mnemonicPath = `${RNFS.DocumentDirectoryPath}/bark-mnemonic`; let mnemonic: string; if (await RNFS.exists(mnemonicPath)) { mnemonic = await RNFS.readFile(mnemonicPath, "utf8"); } else { mnemonic = generateMnemonic(); await RNFS.writeFile(mnemonicPath, mnemonic, "utf8"); } const config = Config.create({ serverAddress: "https://ark.signet.2nd.dev", esploraAddress: "https://esplora.signet.2nd.dev", }); const datadir = `${RNFS.DocumentDirectoryPath}/bark`; const wallet = await Wallet.open( Network.Signet, mnemonic, config, WalletOpenArgs.create({ datadir }), ); ``` On Expo, store the mnemonic and build `datadir` with `expo-file-system` instead. For `datadir`, take the `uri` of `new Directory(Paths.document, "bark")`, strip `file://` and the trailing slash, and decode it with `decodeURIComponent`. On Expo SDK 52 and 53 (`expo-file-system` 18), import `Directory`, `File`, and `Paths` from `expo-file-system/next`. ## Get address and check balance ```tsx theme={"theme":{"light":"github-light","dark":"github-dark"}} const address = await wallet.newAddress(); console.log("Ark address:", address); await wallet.sync(); const balance = await wallet.balance(); console.log(`Spendable: ${balance.spendableSats} sats`); ``` ## Print Bark's logs ```tsx theme={"theme":{"light":"github-light","dark":"github-dark"}} import { barkAttachConsoleLogger, LogLevel } from "@secondts/bark-react-native"; // Once per app process, before Wallet.open() barkAttachConsoleLogger(LogLevel.Debug); ``` ## Signet test environment * Ark server: [https://ark.signet.2nd.dev](https://ark.signet.2nd.dev) * Esplora API: [https://esplora.signet.2nd.dev](https://esplora.signet.2nd.dev) * Faucet for test bitcoin: [https://signet.2nd.dev/](https://signet.2nd.dev/) * Network enum: `Network.Signet` ## Rules * Enable the New Architecture and Hermes (`newArchEnabled=true`, `hermesEnabled=true`). * Open wallets with `Wallet.open(network, mnemonic, config, WalletOpenArgs.create({ datadir }))`. It creates the wallet on first launch and reopens it afterwards. There is no `Wallet.create()`. Don't call `new Wallet()`. * `Config.create()` takes one object. Set `serverAddress` and `esploraAddress`. `Wallet.open()` fails without an Esplora URL. Leave the `bitcoind*` fields unset. This SDK supports Esplora only. The network is the first argument of `Wallet.open()`, not a `Config` field. * `datadir` is a plain file path, not a `file://` URI. Bark creates the directory if it doesn't exist. * Reuse the same mnemonic on every launch. `Wallet.open()` fails with "incorrect mnemonic" if it doesn't match the wallet stored in `datadir`. * Balance amounts are `bigint` values. * Most wallet methods are async. Await them inside an `async` function. React Native doesn't support top-level `await`. * Install the logger once per app process, before `Wallet.open()`. A second `setLogger()` or `barkAttachConsoleLogger()` call throws "logger already installed". * A custom `BarkLogger.log()` must never throw and must never call Bark APIs. * Expo Go is not supported. Use a development build. * Use `Network.Signet` for testing. Never use mainnet without user confirmation. * Never hardcode or log mnemonics in production code. * Correct terminology: Ark (not ARC), VTXO (not vtxo), on-chain (not onchain), off-chain (not offchain). * "Bark" (capitalized) in prose, "bark" (lowercase) for the package name and CLI commands. > [!TIP] > > These examples connect to **signet** so you can test for free. To go live, point the same configuration at Second's mainnet endpoints from [Connection details](/docs/connection-details) and pass `Network.Bitcoin` as the network to `Wallet.open()`. ## Prerequisites * React Native 0.76+ with the [New Architecture](https://reactnative.dev/architecture/landing-page) and [Hermes](https://reactnative.dev/docs/hermes) enabled * iOS 15.1+ / Android API 24+ * For Expo: SDK 52+ and a [development build](https://docs.expo.dev/develop/development-builds/introduction/) (Expo Go is not supported) ## Getting started **1. Install the SDK** **Expo** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} npx expo install @secondts/bark-react-native ``` Add the plugin to your `app.json`: ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "expo": { "plugins": ["@secondts/bark-react-native"] } } ``` Then prebuild: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} npx expo prebuild ``` **Bare React Native** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} npm install @secondts/bark-react-native ``` For iOS, install the CocoaPods dependencies: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} cd ios && pod install && cd .. ``` > [!NOTE] > > If you use pnpm v10+, run `pnpm approve-builds` and select `@secondts/bark-react-native` to allow the postinstall script. **2. Create a wallet** Generate a BIP39 mnemonic, configure the signet endpoints, and open the wallet in a data directory. `Wallet.open()` creates the wallet on the first launch and reopens it on later ones. Run the code from this step and the next two inside an `async` function. React Native doesn't support top-level `await`. **Expo** ```tsx theme={"theme":{"light":"github-light","dark":"github-dark"}} import { Config, Network, Wallet, WalletOpenArgs, generateMnemonic, } from "@secondts/bark-react-native"; import { Directory, File, Paths } from "expo-file-system"; // Signet tests only: don't store a real mnemonic in an unencrypted file const mnemonicFile = new File(Paths.document, "bark-mnemonic"); let mnemonic: string; if (mnemonicFile.exists) { mnemonic = await mnemonicFile.text(); } else { mnemonic = generateMnemonic(); mnemonicFile.create(); mnemonicFile.write(mnemonic); } // Configure the signet endpoints const config = Config.create({ serverAddress: "https://ark.signet.2nd.dev", esploraAddress: "https://esplora.signet.2nd.dev", }); const dir = new Directory(Paths.document, "bark"); const datadir = decodeURIComponent(dir.uri.replace(/^file:\/\//, "")).replace(/\/+$/, ""); // Create the wallet in datadir, or reopen it on later launches const wallet = await Wallet.open( Network.Signet, mnemonic, config, WalletOpenArgs.create({ datadir }), ); ``` On Expo SDK 52 and 53 (`expo-file-system` 18), import `Directory`, `File`, and `Paths` from `expo-file-system/next`. **Bare React Native** ```tsx theme={"theme":{"light":"github-light","dark":"github-dark"}} import { Config, Network, Wallet, WalletOpenArgs, generateMnemonic, } from "@secondts/bark-react-native"; import RNFS from "react-native-fs"; // Signet tests only: don't store a real mnemonic in an unencrypted file const mnemonicPath = `${RNFS.DocumentDirectoryPath}/bark-mnemonic`; let mnemonic: string; if (await RNFS.exists(mnemonicPath)) { mnemonic = await RNFS.readFile(mnemonicPath, "utf8"); } else { mnemonic = generateMnemonic(); await RNFS.writeFile(mnemonicPath, mnemonic, "utf8"); } // Configure the signet endpoints const config = Config.create({ serverAddress: "https://ark.signet.2nd.dev", esploraAddress: "https://esplora.signet.2nd.dev", }); const datadir = `${RNFS.DocumentDirectoryPath}/bark`; // Create the wallet in datadir, or reopen it on later launches const wallet = await Wallet.open( Network.Signet, mnemonic, config, WalletOpenArgs.create({ datadir }), ); ``` > [!WARNING] > > The sample code stores the mnemonic in an unencrypted file so that the next launch reopens the same wallet. That is acceptable for signet tests only. In a production app, store the mnemonic in your platform's secure storage. Also set up [continuous wallet data backups](/docs/backups), so users can restore their wallet without the Ark server's cooperation. **3. Get a receiving address** Generate an Ark address to receive bitcoin. ```tsx theme={"theme":{"light":"github-light","dark":"github-dark"}} const address = await wallet.newAddress(); console.log("Ark address:", address); ``` Run your wallet app to log the address. Send some signet sats to this address using [the faucet](https://signet.2nd.dev/). **4. Check your balance** Bark syncs the wallet in the background while it's open. Call `sync()` when you need an up-to-date balance right away. ```tsx theme={"theme":{"light":"github-light","dark":"github-dark"}} await wallet.sync(); const balance = await wallet.balance(); console.log(`Spendable: ${balance.spendableSats} sats`); ``` Balance amounts are `bigint` values. Relaunch your wallet app. It reopens the same wallet and logs your spendable balance in sats. ## Debug with Bark's logs (optional) Bark prints nothing until your wallet app installs a logger. ### Install the console logger Call `barkAttachConsoleLogger()` once, at startup, before `Wallet.open()`. ```tsx theme={"theme":{"light":"github-light","dark":"github-dark"}} import { Exception, LogLevel, barkAttachConsoleLogger } from "@secondts/bark-react-native"; try { // The default level is LogLevel.Info barkAttachConsoleLogger(LogLevel.Debug); } catch (e) { // A logger is already installed in this app process if (!Exception.instanceOf(e)) throw e; } ``` Install it once per app process. A second call throws `logger already installed`, which the `catch` block ignores. > [!NOTE] > > **Known issue in 0.25.0: logging after a JS reload** > > A JS reload (`DevSettings.reload()` or `reloadAsync()` from `expo-updates`) replaces the JS runtime but not the app process, so the installed logger points at the old runtime. After a reload, no logs reach JS, and the next Bark log can hang `Wallet.open()` or crash the app. Restart the app instead of reloading it while a logger is installed. The next release makes `setLogger()` replaceable and adds `clearLogger()`, which fixes this. Each line starts with `[bark]`, the level, and the Rust module that logged it: ```text Console output wrap theme={"theme":{"light":"github-light","dark":"github-dark"}} [bark][Info][server_rpc::client::transport] Connecting to Ark server at https://ark.signet.2nd.dev using TLS... [bark][Info][bark] Created wallet with fingerprint: 2377a97c [bark][Debug][bark::mailbox] Ark server has 0 mailbox messages for us [bark][Info][bark_ffi::core::wallet] [SYNC] Sync completed ``` ### Set Bark's log level Pick the level when you install the logger. You can't change it until your wallet app restarts. | Level | Records your logger receives | | - | - | | `LogLevel.Error` | Errors | | `LogLevel.Warn` | Errors and warnings | | `LogLevel.Info` | Errors, warnings, and routine activity such as connections, syncs, and payments (default) | | `LogLevel.Debug` | Everything above, plus debugging detail | | `LogLevel.Trace` | Every record, including high-volume HTTP/2 records from networking libraries | > [!TIP] > > Use `LogLevel.Trace` only for short debugging sessions. It sends thousands of records. Bark waits for your logger to handle each one. ### Send logs to your own destination To store logs in memory for a bug report, or to forward them to your crash reporter, implement `BarkLogger` and install it with `setLogger()` instead of `barkAttachConsoleLogger()`. ```tsx theme={"theme":{"light":"github-light","dark":"github-dark"}} import { Exception, LogLevel, setLogger, type BarkLogger } from "@secondts/bark-react-native"; // The last 500 log lines, for example to attach to a bug report export const recentLogs: string[] = []; class AppBarkLogger implements BarkLogger { log(level: LogLevel, target: string, message: string): void { try { recentLogs.push(`${new Date().toISOString()} ${LogLevel[level]} ${target} ${message}`); if (recentLogs.length > 500) recentLogs.shift(); } catch {} } } try { setLogger(new AppBarkLogger(), LogLevel.Info); } catch (e) { // A logger is already installed in this app process if (!Exception.instanceOf(e)) throw e; } ``` Your `log()` method has three constraints: * **Never throw:** An exception that escapes `log()` becomes a Rust panic, which can crash your wallet app. * **Never call Bark APIs:** A Bark call that logs re-enters your logger, which can overflow the stack or deadlock your wallet app. * **Return quickly:** The Rust thread that emitted the record waits until `log()` returns. > [!TIP] > > Treat Bark's logs as private data before you send them to a third party. They include balances, invoices, transaction IDs, and addresses. Bark's log records never include the mnemonic or private keys. ## Next steps > **[Source code](https://gitlab.com/ark-bitcoin/bark-ffi-bindings/-/tree/master/react-native)** > > React Native bindings source on GitLab. > **[How Ark works](/docs/learn/intro)** > > Learn about the protocol powering your wallet. # Get started with Rust Source: https://second.tech/docs/bark-sdk/rust Add Ark payments to your Rust application. Create a wallet, generate addresses, and check your balance in minutes. Use this prompt to get started quickly. # Bark SDK: Rust Build Ark wallet apps in Rust with the `bark-wallet` crate. Ark is a bitcoin layer 2 protocol for instant, low-fee, self-custodial payments. ## Prerequisites * The latest stable Rust with Cargo * `protoc` (the Protocol Buffers compiler) in `PATH`, or its full path in the `PROTOC` environment variable ## Install ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} cargo add bark-wallet cargo add tokio --features full cargo add anyhow ``` ## Create a wallet ```rust theme={"theme":{"light":"github-light","dark":"github-dark"}} use std::path::PathBuf; use bark::ark::bitcoin::Network; use bark::bip39::Mnemonic; use bark::{Config, OpenWalletArgs, Wallet, WalletSeed}; #[tokio::main] async fn main() -> anyhow::Result<()> { let network = Network::Signet; // Signet tests only: don't store a real mnemonic in an unencrypted file let mnemonic_path = PathBuf::from("bark-mnemonic"); let mnemonic: Mnemonic = if mnemonic_path.exists() { let words = tokio::fs::read_to_string(&mnemonic_path).await?; words.trim().parse()? } else { let mnemonic = Mnemonic::generate(12)?; tokio::fs::write(&mnemonic_path, mnemonic.to_string()).await?; mnemonic }; // Configure the signet endpoints let config = Config { server_address: "https://ark.signet.2nd.dev".into(), esplora_address: Some("https://esplora.signet.2nd.dev".into()), ..Config::network_default(network) }; let datadir = PathBuf::from("bark"); // Create the wallet in datadir, or reopen it on later launches let wallet = Wallet::open( network, WalletSeed::new_from_mnemonic(network, &mnemonic), config, OpenWalletArgs { datadir: Some(datadir), ..Default::default() }, ) .await?; Ok(()) } ``` ## Get address and check balance Add these lines at the end of `main`, before `Ok(())`: ```rust theme={"theme":{"light":"github-light","dark":"github-dark"}} let address = wallet.new_address().await?; println!("Ark address: {address}"); wallet.sync().await; let balance = wallet.balance().await?; println!("Spendable: {} sats", balance.spendable.to_sat()); ``` ## Signet test environment * Ark server: [https://ark.signet.2nd.dev](https://ark.signet.2nd.dev) * Esplora API: [https://esplora.signet.2nd.dev](https://esplora.signet.2nd.dev) * Faucet for test bitcoin: [https://signet.2nd.dev/](https://signet.2nd.dev/) * Network enum: `Network::Signet` ## Rules * Open wallets with `Wallet::open(network, WalletSeed::new_from_mnemonic(network, &mnemonic), config, OpenWalletArgs { datadir: Some(datadir), ..Default::default() })`. It creates the wallet on first launch and reopens it afterwards. Don't use `Wallet::create()`, a low-level call that only writes a new wallet and returns `anyhow::Result<()>`, not a `Wallet`. * Build `Config` with `server_address`, `esplora_address`, and `..Config::network_default(network)` for the other fields. `Wallet::open()` fails without an Esplora URL or bitcoind settings. * Bark creates `datadir` if it doesn't exist. Only one open `Wallet` can use a `datadir` at a time, even within one process. A second `Wallet::open()` on it fails with "another process is already using datadir". Open the wallet once and clone the `Wallet` where you need it. * Reuse the same mnemonic on every launch. `Wallet::open()` fails with "incorrect mnemonic" if it doesn't match the wallet stored in `datadir`. * Keep the `Wallet` in scope for the life of your app. `Wallet::open()` starts Bark's background sync, which stops when you drop the last `Wallet` clone. * Wallet operations are async. Run them inside a Tokio runtime, such as `#[tokio::main]`. * `wallet.sync().await` returns `()`. Don't put `?` after it. * Balance amounts are `Amount` values from `bark::ark::bitcoin`. Call `.to_sat()` to get sats. * Import `Network` from `bark::ark::bitcoin` and `Mnemonic` from `bark::bip39` instead of adding the `bitcoin` or `bip39` crates. Their latest versions can differ from Bark's. * Use `Network::Signet` for testing. Mainnet is `Network::Bitcoin`. Never use mainnet without user confirmation. * Never hardcode or log mnemonics in production code. * The crate name is `bark-wallet`, not `bark`, `bark-bitcoin`, or `bark-sdk`. Its library name is `bark`, as in `use bark::Wallet`. * Correct terminology: Ark (not ARC), VTXO (not vtxo), on-chain (not onchain), off-chain (not offchain). * "Bark" (capitalized) in prose, "bark" (lowercase) for the crate name and CLI commands. > [!TIP] > > These examples connect to **signet** so you can test for free. To go live, point the same configuration at Second's mainnet endpoints from [Connection details](/docs/connection-details) and select the mainnet network. ## Prerequisites * The latest stable [Rust](https://rust-lang.org/tools/install/) with Cargo * `protoc`, the Protocol Buffers compiler Install `protoc` for your platform: **macOS** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} brew install protobuf ``` **Debian and Ubuntu** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} sudo apt install protobuf-compiler ``` **Windows** Download `protoc--win64.zip` from the [protobuf releases](https://github.com/protocolbuffers/protobuf/releases) and extract it. Then add its `bin` folder to your `PATH`, or set the `PROTOC` environment variable to the full path of `protoc.exe`. ## Getting started **1. Install the SDK** In your project directory, run: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} cargo add bark-wallet ``` Then add Tokio and `anyhow`: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} cargo add tokio --features full cargo add anyhow ``` Import `bitcoin` and `bip39` types from Bark's re-exports, `bark::ark::bitcoin` and `bark::bip39`, instead of adding those crates. **2. Create a wallet** Generate a BIP39 mnemonic, configure the signet endpoints, and open the wallet in a data directory. `Wallet::open()` creates the wallet on the first launch and reopens it on later ones. ```rust src/main.rs theme={"theme":{"light":"github-light","dark":"github-dark"}} use std::path::PathBuf; use bark::ark::bitcoin::Network; use bark::bip39::Mnemonic; use bark::{Config, OpenWalletArgs, Wallet, WalletSeed}; #[tokio::main] async fn main() -> anyhow::Result<()> { let network = Network::Signet; // Signet tests only: don't store a real mnemonic in an unencrypted file let mnemonic_path = PathBuf::from("bark-mnemonic"); let mnemonic: Mnemonic = if mnemonic_path.exists() { let words = tokio::fs::read_to_string(&mnemonic_path).await?; words.trim().parse()? } else { let mnemonic = Mnemonic::generate(12)?; tokio::fs::write(&mnemonic_path, mnemonic.to_string()).await?; mnemonic }; // Configure the signet endpoints let config = Config { server_address: "https://ark.signet.2nd.dev".into(), esplora_address: Some("https://esplora.signet.2nd.dev".into()), ..Config::network_default(network) }; let datadir = PathBuf::from("bark"); // Create the wallet in datadir, or reopen it on later launches let wallet = Wallet::open( network, WalletSeed::new_from_mnemonic(network, &mnemonic), config, OpenWalletArgs { datadir: Some(datadir), ..Default::default() }, ) .await?; Ok(()) } ``` > [!WARNING] > > The sample code stores the mnemonic in an unencrypted file so that the next launch reopens the same wallet. That is acceptable for signet tests only. In a production app, store the mnemonic in your platform's secure storage. Also set up [continuous wallet data backups](/docs/backups), so users can restore their wallet without the Ark server's cooperation. **3. Get a receiving address** Generate an Ark address to receive bitcoin. Add these lines at the end of `main`, before `Ok(())`: ```rust theme={"theme":{"light":"github-light","dark":"github-dark"}} let address = wallet.new_address().await?; println!("Ark address: {address}"); ``` Run `cargo run` to print the address. Send some signet sats to this address using [the faucet](https://signet.2nd.dev/). **4. Check your balance** Bark syncs the wallet in the background while it's open. Call `sync()` when you need an up-to-date balance right away. Add these lines after the address lines, before `Ok(())`: ```rust theme={"theme":{"light":"github-light","dark":"github-dark"}} wallet.sync().await; let balance = wallet.balance().await?; println!("Spendable: {} sats", balance.spendable.to_sat()); ``` Balance amounts are `Amount` values from `bark::ark::bitcoin`. Run `cargo run` again. The program reopens the same wallet and prints your spendable balance in sats. ## Next steps > **[API reference](https://docs.rs/bark-wallet/latest/bark/index.html)** > > Full Rust API documentation on docs.rs. > **[How Ark works](/docs/learn/intro)** > > Learn about the protocol powering your wallet. # Get started with Swift Source: https://second.tech/docs/bark-sdk/swift Add Ark payments to your iOS or macOS application. Create a wallet, generate addresses, and check your balance in minutes. Use this prompt to get started quickly. # Bark SDK: Swift Build Ark wallet apps for iOS and macOS with the `Bark` Swift package. Ark is a bitcoin layer 2 protocol for instant, low-fee, self-custodial payments. ## Prerequisites * iOS 14+ or macOS 14+, with Xcode 15+ (Swift 5.9+) ## Install (Xcode) File > Add Package Dependencies, enter `https://gitlab.com/ark-bitcoin/bark-ffi-bindings.git`, set the dependency rule to the exact version `0.25.0`, and add the `Bark` product to your app target. ## Install (Package.swift) ```swift theme={"theme":{"light":"github-light","dark":"github-dark"}} platforms: [.iOS(.v14), .macOS(.v14)], dependencies: [ .package(url: "https://gitlab.com/ark-bitcoin/bark-ffi-bindings.git", exact: "0.25.0"), ], // In your target's dependencies: .product(name: "Bark", package: "bark-ffi-bindings") ``` ## Create a wallet ```swift theme={"theme":{"light":"github-light","dark":"github-dark"}} import Bark import Foundation // Store the wallet files in your app's Application Support folder let appDir = try FileManager.default.url( for: .applicationSupportDirectory, in: .userDomainMask, appropriateFor: nil, create: true ).appendingPathComponent(Bundle.main.bundleIdentifier ?? "bark-quickstart") try FileManager.default.createDirectory(at: appDir, withIntermediateDirectories: true) // Signet tests only: don't store a real mnemonic in an unencrypted file let mnemonicFile = appDir.appendingPathComponent("bark-mnemonic") let mnemonic: String if FileManager.default.fileExists(atPath: mnemonicFile.path) { mnemonic = try String(contentsOf: mnemonicFile, encoding: .utf8) } else { mnemonic = try generateMnemonic() try mnemonic.write(to: mnemonicFile, atomically: true, encoding: .utf8) } // Configure the signet endpoints. nil leaves a setting at Bark's default. let config = Config( serverAddress: "https://ark.signet.2nd.dev", serverAccessToken: nil, esploraAddress: "https://esplora.signet.2nd.dev", bitcoindAddress: nil, bitcoindCookiefile: nil, bitcoindUser: nil, bitcoindPass: nil, vtxoRefreshExpiryThreshold: nil, vtxoExitMargin: nil, htlcRecvClaimDelta: nil, fallbackFeeRate: nil, roundTxRequiredConfirmations: nil, daemonSyncIntervalSecs: nil, offboardRequiredConfirmations: nil, daemonManualSync: nil, lightningReceiveClaimRetries: nil, userAgent: nil, vtxoKeyGapLimit: nil ) let datadir = appDir.appendingPathComponent("bark").path // Create the wallet in datadir, or reopen it on later launches let wallet = try await Wallet.open( network: .signet, mnemonicOrSeed: mnemonic, config: config, args: WalletOpenArgs(datadir: datadir, onchain: nil) ) ``` ## Get address and check balance ```swift theme={"theme":{"light":"github-light","dark":"github-dark"}} let address = try await wallet.newAddress() print("Ark address: \(address)") try await wallet.sync() let balance = try await wallet.balance() print("Spendable: \(balance.spendableSats) sats") ``` ## Signet test environment * Ark server: [https://ark.signet.2nd.dev](https://ark.signet.2nd.dev) * Esplora API: [https://esplora.signet.2nd.dev](https://esplora.signet.2nd.dev) * Faucet for test bitcoin: [https://signet.2nd.dev/](https://signet.2nd.dev/) * Network enum: `Network.signet` ## Rules * Open wallets with `Wallet.open(network:mnemonicOrSeed:config:args:)`. It creates the wallet on first launch and reopens it afterwards. There is no `Wallet.create()`. * The `Config` initializer has no default values. Pass all 18 arguments in order, with `nil` for every setting you don't change. * Set `serverAddress` and `esploraAddress` in `Config`. `Wallet.open()` fails without an Esplora URL. Leave the `bitcoind*` fields `nil`. This SDK supports Esplora only. The network is the first argument of `Wallet.open()`, not a `Config` field. * Pass the data directory with `WalletOpenArgs(datadir: datadir, onchain: nil)`. `onchain` has no default value, so pass `nil`. * `datadir` is a file system path (`URL.path`), not a `file://` URL. Bark creates the directory if it doesn't exist. * Only one open wallet can use a `datadir` at a time, even within one process. A second `Wallet.open()` on it fails with "another process is already using datadir". Open the wallet once per process and reuse it. * Reuse the same mnemonic on every launch. `Wallet.open()` fails with "incorrect mnemonic" if it doesn't match the wallet stored in `datadir`. * `Wallet.open()`, `newAddress()`, `sync()`, and `balance()` are `async throws`. Call them with `try await` inside an `async throws` function or a `Task`. `generateMnemonic()` throws but isn't async, so call it with `try`. * Balance amounts are `UInt64` values. * In a sandboxed macOS app, add the `com.apple.security.network.client` entitlement (**App Sandbox** > **Outgoing Connections (Client)**). Without it, `Wallet.open()` fails with a DNS lookup error. * Import `Bark` (capital B), not `bark`. * Use `Network.signet` for testing. Mainnet is `Network.bitcoin`. Never use mainnet without user confirmation. * Never hardcode or log mnemonics in production code. * Correct terminology: Ark (not ARC), VTXO (not vtxo), on-chain (not onchain), off-chain (not offchain). * "Bark" (capitalized) in prose, "bark" (lowercase) for CLI commands and repository names. > [!TIP] > > These examples connect to **signet** so you can test for free. To go live, point the same configuration at Second's mainnet endpoints from [Connection details](/docs/connection-details) and select the mainnet network. ## Prerequisites * iOS 14+ or macOS 14+, with Xcode 15+ (Swift 5.9+) ## Getting started **1. Install the SDK** **Xcode** In Xcode, go to **File** > **Add Package Dependencies** and enter the package URL: ``` https://gitlab.com/ark-bitcoin/bark-ffi-bindings.git ``` For **Dependency Rule**, select **Exact Version** and enter `0.25.0`. Then add the `Bark` product to your app target. **Package.swift** Add the minimum platforms and the dependency to your `Package.swift`: ```swift theme={"theme":{"light":"github-light","dark":"github-dark"}} platforms: [.iOS(.v14), .macOS(.v14)], dependencies: [ .package( url: "https://gitlab.com/ark-bitcoin/bark-ffi-bindings.git", exact: "0.25.0" ) ] ``` Then add the `Bark` product to your target's dependencies: ```swift theme={"theme":{"light":"github-light","dark":"github-dark"}} .target( name: "YourApp", dependencies: [ .product(name: "Bark", package: "bark-ffi-bindings") ] ) ``` In a macOS app, open your app target's **Signing & Capabilities** tab. Under **App Sandbox**, select **Outgoing Connections (Client)**. **2. Create a wallet** Generate a BIP39 mnemonic, configure the signet endpoints, and open the wallet in a data directory. `Wallet.open()` creates the wallet on the first launch and reopens it on later ones. Run the code from this step and the next two inside an `async throws` function or a `Task`, with the `import` lines at the top of the file. ```swift theme={"theme":{"light":"github-light","dark":"github-dark"}} import Bark import Foundation // Store the wallet files in your app's Application Support folder let appDir = try FileManager.default.url( for: .applicationSupportDirectory, in: .userDomainMask, appropriateFor: nil, create: true ).appendingPathComponent(Bundle.main.bundleIdentifier ?? "bark-quickstart") try FileManager.default.createDirectory(at: appDir, withIntermediateDirectories: true) // Signet tests only: don't store a real mnemonic in an unencrypted file let mnemonicFile = appDir.appendingPathComponent("bark-mnemonic") let mnemonic: String if FileManager.default.fileExists(atPath: mnemonicFile.path) { mnemonic = try String(contentsOf: mnemonicFile, encoding: .utf8) } else { mnemonic = try generateMnemonic() try mnemonic.write(to: mnemonicFile, atomically: true, encoding: .utf8) } // Configure the signet endpoints. nil leaves a setting at Bark's default. let config = Config( serverAddress: "https://ark.signet.2nd.dev", serverAccessToken: nil, esploraAddress: "https://esplora.signet.2nd.dev", bitcoindAddress: nil, bitcoindCookiefile: nil, bitcoindUser: nil, bitcoindPass: nil, vtxoRefreshExpiryThreshold: nil, vtxoExitMargin: nil, htlcRecvClaimDelta: nil, fallbackFeeRate: nil, roundTxRequiredConfirmations: nil, daemonSyncIntervalSecs: nil, offboardRequiredConfirmations: nil, daemonManualSync: nil, lightningReceiveClaimRetries: nil, userAgent: nil, vtxoKeyGapLimit: nil ) let datadir = appDir.appendingPathComponent("bark").path // Create the wallet in datadir, or reopen it on later launches let wallet = try await Wallet.open( network: .signet, mnemonicOrSeed: mnemonic, config: config, args: WalletOpenArgs(datadir: datadir, onchain: nil) ) ``` > [!WARNING] > > The sample code stores the mnemonic in an unencrypted file so that the next launch reopens the same wallet. That is acceptable for signet tests only. In a production app, store the mnemonic in your platform's secure storage. Also set up [continuous wallet data backups](/docs/backups), so users can restore their wallet without the Ark server's cooperation. **3. Get a receiving address** Generate an Ark address to receive bitcoin. ```swift theme={"theme":{"light":"github-light","dark":"github-dark"}} let address = try await wallet.newAddress() print("Ark address: \(address)") ``` Run your app to print the address. In Xcode, `print()` output appears in the console. Send some signet sats to this address using [the faucet](https://signet.2nd.dev/). **4. Check your balance** Bark syncs the wallet in the background while it's open. Call `sync()` when you need an up-to-date balance right away. ```swift theme={"theme":{"light":"github-light","dark":"github-dark"}} try await wallet.sync() let balance = try await wallet.balance() print("Spendable: \(balance.spendableSats) sats") ``` Balance amounts are `UInt64` values. Run your app again. It reopens the same wallet and prints your spendable balance in sats. ## Next steps > **[Source code](https://gitlab.com/ark-bitcoin/bark-ffi-bindings/-/tree/master/swift)** > > Swift bindings source on GitLab. > **[How Ark works](/docs/learn/intro)** > > Learn about the protocol powering your wallet. # Get started with TypeScript for web apps Source: https://second.tech/docs/bark-sdk/wasm Add Ark payments to your web app or PWA with TypeScript. Create a wallet, generate addresses, and check your balance in minutes. Use this prompt to get started quickly. # Bark SDK: TypeScript for the web Build Ark wallet apps in the browser with `@secondts/bark`. Ark is a bitcoin layer 2 protocol for instant, low-fee, self-custodial payments. The SDK runs entirely in the browser via WebAssembly, with wallet state persisted to IndexedDB. ## Prerequisites * A modern browser with WebAssembly, IndexedDB, and the Web Locks API (`navigator.locks`) * A secure context: served over **HTTPS** or `localhost` * For the bundler setups: a bundler that can emit a `.wasm` asset (Vite, webpack, Next.js) ## Install (Vite) ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} npm install @secondts/bark ``` Import from the `@secondts/bark/web` subpath and pass the URL of the `.wasm` binary to `init()`. The only bundler-specific line is how you get that URL: * **Vite:** `import wasmUrl from "@secondts/bark/web/bark_ffi_wasm_bg.wasm?url"` * **webpack / Next.js:** `new URL("@secondts/bark/web/bark_ffi_wasm_bg.wasm", import.meta.url)` * **Fallback (any):** Copy `bark_ffi_wasm_bg.wasm` into your static assets folder, such as `public/`, and pass its path as `module_or_path`, for example `init({ module_or_path: "/bark_ffi_wasm_bg.wasm" })`. ## Install (Vanilla HTML/JS) No install step. Import `https://unpkg.com/@secondts/bark@0.25.0/web/bark_ffi_wasm.js` inside a ` ``` **2. Create a wallet** Instantiate the WebAssembly module, generate a BIP39 mnemonic, and open the wallet on signet. `Wallet.open()` creates the wallet in IndexedDB on the first visit and reopens it on later ones. **Vite** ```ts theme={"theme":{"light":"github-light","dark":"github-dark"}} import init, { Wallet, generateMnemonic } from "@secondts/bark/web"; import type { Config, Network } from "@secondts/bark/web"; // Vite resolves `?url` to the URL of the wasm binary import wasmUrl from "@secondts/bark/web/bark_ffi_wasm_bg.wasm?url"; // Instantiate the wasm module before calling any other binding await init({ module_or_path: wasmUrl }); // Configure the signet endpoints const network: Network = "Signet"; const config: Config = { serverAddress: "https://ark.signet.2nd.dev", esploraAddress: "https://esplora.signet.2nd.dev", }; // Signet tests only: don't store a real mnemonic in unencrypted localStorage let mnemonic = localStorage.getItem("bark-mnemonic"); if (!mnemonic) { mnemonic = generateMnemonic(); localStorage.setItem("bark-mnemonic", mnemonic); } // Create the wallet on the first visit, or reopen it on later ones. // The fourth argument is an optional on-chain wallet, not needed here. const wallet = await Wallet.open(network, mnemonic, config, undefined, { indexedDbName: "bark-signet", }); ``` **Next.js** ```tsx theme={"theme":{"light":"github-light","dark":"github-dark"}} // app/BarkClient.tsx "use client"; import { useEffect } from "react"; import type { Wallet } from "@secondts/bark/web"; // Load the wasm and open the wallet once per page load let walletPromise: Promise | undefined; function getWallet(): Promise { walletPromise ??= (async () => { // The dynamic import excludes the wasm module from the server render const { default: init, Wallet, generateMnemonic } = await import("@secondts/bark/web"); await init({ module_or_path: new URL("@secondts/bark/web/bark_ffi_wasm_bg.wasm", import.meta.url) }); // Signet tests only: don't store a real mnemonic in unencrypted localStorage let mnemonic = localStorage.getItem("bark-mnemonic"); if (!mnemonic) { mnemonic = generateMnemonic(); localStorage.setItem("bark-mnemonic", mnemonic); } // Create the wallet on the first visit, or reopen it on later ones. // The fourth argument is an optional on-chain wallet, not needed here. return Wallet.open( "Signet", mnemonic, { serverAddress: "https://ark.signet.2nd.dev", esploraAddress: "https://esplora.signet.2nd.dev" }, undefined, { indexedDbName: "bark-signet" }, ); })(); return walletPromise; } export default function BarkClient() { useEffect(() => { let cancelled = false; (async () => { const wallet = await getWallet(); if (cancelled) return; const address = await wallet.newAddress(); console.log("Ark address:", address); await wallet.sync(); const balance = await wallet.balance(); console.log("Spendable:", balance.spendableSats, "sats"); })(); return () => { cancelled = true; }; }, []); return
see console
; } ``` > [!NOTE] > > The SDK is browser-only. Load it from `useEffect` in a `"use client"` component so it never runs during server rendering. Store the wallet promise at module level. React Strict Mode runs effects twice in development, which would otherwise call `init()` twice. `next/dynamic` with `ssr: false` isn't allowed in Server Components. **Vanilla HTML/JS** ```html theme={"theme":{"light":"github-light","dark":"github-dark"}} ``` > [!WARNING] > > The sample code stores the mnemonic in `localStorage`, unencrypted, so that the next visit reopens the same wallet. That is acceptable for signet tests only. In a production app, encrypt the mnemonic before you store it, for example with a key derived from a user password. Also set up [continuous wallet data backups](/docs/backups), so users can restore their wallet without the Ark server's cooperation. **3. Get a receiving address** Generate an Ark address to receive bitcoin. ```ts theme={"theme":{"light":"github-light","dark":"github-dark"}} const address = await wallet.newAddress(); console.log("Ark address:", address); ``` Load your page to log the address in the browser's developer console. Send some signet sats to this address using [the faucet](https://signet.2nd.dev/). **4. Check your balance** Bark syncs the wallet in the background for as long as your page holds a reference to the `Wallet` object. Call `sync()` when you need an up-to-date balance right away. ```ts theme={"theme":{"light":"github-light","dark":"github-dark"}} await wallet.sync(); const balance = await wallet.balance(); console.log("Spendable:", balance.spendableSats, "sats"); ``` Balance amounts are `number` values. Reload the page. It reopens the same wallet and logs your spendable balance in sats. ## Next steps > **[Source code](https://gitlab.com/ark-bitcoin/bark-ffi-bindings/-/tree/master/wasm)** > > Web bindings package source on GitLab. > **[How Ark works](/docs/learn/intro)** > > Learn about the protocol powering your wallet. # Wallet backups Source: https://second.tech/docs/bark-wallet/backup Record your seed phrase for simple backups that rely on the Ark server, and set up continuous wallet database backups for fully trustless restores. Before receiving any payments, make sure you back up your wallet. 1. **[Write down your seed phrase](#write-down-your-seed-phrase):** This is enough to recover your balance in the event of a system failure. Recovery from the seed phrase alone requires the Ark server's cooperation, and it doesn't restore your payment history or the state of any in-progress exits. 2. **[Set up continuous backups](#set-up-continuous-backups)** (optional): A backup that you fully control, with your entire payment history included. The [Backups](/docs/backups) page explains the mechanics behind both in more depth. ## Write down your seed phrase The wallet app showed you your 12-word seed phrase when you [created the wallet](/docs/bark-wallet/create). If you haven't written it down yet, reveal it in Settings. **1. Open Settings** Select **Settings** in the wallet app's sidebar. **2. Reveal the seed phrase** Scroll to the **Seed phrase** field at the bottom of the page and select the eye icon. **3. Write down the 12 words** Copy them in order, somewhere safe and offline. The seed phrase never changes, so this is a one-time step. ![Screenshot of the bottom of the Settings page, with the revealed seed phrase and its backup warning above the Danger zone](https://mintcdn.com/second-0659a37d/3KiAlC1Xlv9QyI7k/images/bark-wallet/settings-danger-zone.png?fit=max\&auto=format\&n=3KiAlC1Xlv9QyI7k\&q=85\&s=1ca434358b33b498855ebf8f69d8f79b) The revealed seed phrase and its backup warning in Settings ## Set up continuous backups **Umbrel** We don't have a mature continuous backup solution for Bark Wallet on Umbrel yet. For adventurous users, some options to consider: * **[Native umbrelOS backups](https://umbrel.com/support/backups-and-recovery/backing-up-your-data):** Encrypted backups of your Umbrel, wallet directory included, taken every hour. Sync apps in the Umbrel App Store, such as Syncthing and Duplicati, can't reach the wallet directory. > [!WARNING] > > If a backup misses your latest wallet changes, recovering your whole balance will require [restoring from your seed phrase](/docs/bark-wallet/restore), which relies on the Ark server's cooperation. **Start9** Bark Wallet on StartOS makes continuous backups automatically from the moment you launch the app, using the external backup target you set up during [installation](/docs/bark-wallet/install). On every change in wallet state (send, receive, refresh, exit), the service sends an encrypted snapshot of your wallet data to that target. We'd still recommend you run a manual test to confirm the backups are working. **1. Run Back Up Now** Go to the service's **Actions & Config** and select **Back Up Now**. **2. Check the Wallet Backup health check** Once the run succeeds, the service's **Wallet Backup** health check shows your last backup time. Every later backup is automatic. ![Screenshot of the running Bark Wallet service, with the Web Interface and Wallet Backup health checks green](https://mintcdn.com/second-0659a37d/3KiAlC1Xlv9QyI7k/images/bark-wallet/start9-dashboard-running.png?fit=max\&auto=format\&n=3KiAlC1Xlv9QyI7k\&q=85\&s=1a18697cf797807a6c95ddde72a3d9ad) A successful Wallet Backup health check > [!TIP] > > Keep taking regular [StartOS backups](https://docs.start9.com/start-os/0.4.0.x/backup-create.html) too, under **System** > **Create Backup**, and take a new one whenever you change backup targets. They deliberately leave the wallet database out, but they carry your seed phrase and your backup-target credentials. If you ever restore one, the service pulls the freshest wallet snapshot from your backup target automatically. Your StartOS master password encrypts these backups, so keep it safe. **Self-host** We don't have a mature continuous backup solution for self-hosted installs yet. For adventurous users, some options to consider: * **[bark-backupd](https://gitlab.com/ark-bitcoin/labs/bark-backupd):** Second's experimental backup daemon. It runs alongside `barkd`. On every change, it snapshots the wallet database, encrypts the snapshot with a key derived from your seed phrase, and ships it to your chosen targets: a USB drive, Nextcloud, Google Drive, or anything S3-compatible. Test `bark-backupd restore` before you rely on it. * **[Litestream](https://litestream.io/):** A streaming replicator that copies new changes in the wallet database to a replica you configure, such as an S3-compatible bucket, every second by default. The wallet database isn't formally tested in the WAL journal mode Litestream requires, so treat the approach as experimental. > [!WARNING] > > If a backup misses your latest wallet changes, recovering your whole balance will require [restoring from your seed phrase](/docs/bark-wallet/restore), which relies on the Ark server's cooperation. For restoring a wallet backup, see [Restore your wallet](/docs/bark-wallet/restore). # Create your wallet Source: https://second.tech/docs/bark-wallet/create Create your Bark Wallet the first time the app opens: name it, write down your seed phrase, confirm it, and open the dashboard. The first time it opens, the wallet app shows a welcome screen with two ways to set up your wallet. 1. **Create new wallet:** Generates a fresh wallet and its seed phrase, in the steps below. 2. **[Import existing wallet](/docs/bark-wallet/restore#restore-from-your-seed-phrase):** Brings back a wallet you already own from its seed phrase. **1. Select Create new wallet** On the welcome screen, select **Create new wallet**. ![Screenshot of the Bark Wallet welcome screen, with the Create new wallet and Import existing wallet buttons](https://mintcdn.com/second-0659a37d/aWt2qtiAzrDPasuK/images/bark-wallet/welcome-screen.png?fit=max\&auto=format\&n=aWt2qtiAzrDPasuK\&q=85\&s=457f9ae9322c6b6438b687b143f3cbed) The welcome screen: create a new wallet, or import one from its seed phrase **2. Name the wallet** Enter a display name (it doesn't affect recovery) and select **Continue**. **3. Write down your seed phrase** The wallet app generates your 12-word seed phrase. Write the words down in order, put them somewhere safe and offline, then select **Continue**. ![Screenshot of the Seed phrase step, showing the 12 numbered words of a new wallet and the Continue button](https://mintcdn.com/second-0659a37d/aWt2qtiAzrDPasuK/images/bark-wallet/create-seed-phrase.png?fit=max\&auto=format\&n=aWt2qtiAzrDPasuK\&q=85\&s=12ad127358f8e07898b05a717885becc) Write the 12 words down in order before you continue > [!WARNING] > > Your seed phrase is the only way to recover your bitcoin if you lose this device, and anyone who reads it can spend from your wallet. Store it offline and never share it. **4. Confirm your seed phrase** Select the 12 words in the order you wrote them down. The wallet app flags a wrong pick so you can correct it. Once all 12 are in place, select **Continue**. ![Screenshot of the Confirm seed phrase step, with the shuffled words and the first few already selected in order](https://mintcdn.com/second-0659a37d/aWt2qtiAzrDPasuK/images/bark-wallet/create-confirm-seed-phrase.png?fit=max\&auto=format\&n=aWt2qtiAzrDPasuK\&q=85\&s=ab1d29c9d1af4438f8fb2e5a06e75576) Select the words in the order you wrote them down; a wrong pick turns red **5. Confirm the network and servers** The wallet app shows the network, Ark server, and chain source, which you can't change here. Select **Continue** to finish. The dashboard opens with an empty balance. With your seed phrase written down, the next thing to do is [set up continuous backups](/docs/bark-wallet/backup#set-up-continuous-backups). # Understand your dashboard Source: https://second.tech/docs/bark-wallet/dashboard Read the Bark Wallet dashboard: one main balance with off-chain and on-chain sub-balances, the next round countdown, and your payment history. ## One balance, two sub-balances Your wallet balance is shown at the top of the dashboard, and is made up of two sub-balances: * **Off-chain:** Where Ark and Lightning payments arrive, held in [VTXOs](/docs/learn/vtxo). * **On-chain:** Where on-chain payments arrive, held in regular UTXOs. Select the eye button on the balance card to turn on [discreet mode](/docs/bark-wallet/settings#display-units-and-price) and hide your balances and transaction amounts. ![Screenshot of the Bark Wallet dashboard, with the main balance, its off-chain and on-chain sub-balances, the next round countdown, and the payment history](https://mintcdn.com/second-0659a37d/3KiAlC1Xlv9QyI7k/images/bark-wallet/dashboard-overview.png?fit=max\&auto=format\&n=3KiAlC1Xlv9QyI7k\&q=85\&s=7eb3fa1eb98f57d6f4e9d9c86f5a5a7b) The main balance totals its sub-balances ## Your off-chain balance Your off-chain balance is the bread and butter of your wallet, where most of your transaction activity takes place. * **Sending:** You can pay anyone from your off-chain balance, whether over [Ark, Lightning, or on-chain](/docs/bark-wallet/send-receive#send-bitcoin). * **Receiving:** [Ark and Lightning payments](/docs/bark-wallet/send-receive#receive-bitcoin) arrive in your off-chain balance. On-chain payments arrive in your [on-chain balance](#your-on-chain-balance) instead. ## Your on-chain balance Your on-chain balance can receive bitcoin from [on-chain payments](/docs/bark-wallet/send-receive#receive-bitcoin), [offboards](/docs/learn/offboard), and [emergency exits](/docs/learn/exit). It also covers the on-chain fees in the event you need to make an emergency exit. To move bitcoin into or out of your on-chain balance, use the on-chain option when making a [Receive](/docs/bark-wallet/send-receive#receive-bitcoin) or [Send](/docs/bark-wallet/send-receive#send-bitcoin). > [!TIP] > > It's a good idea to maintain a small on-chain balance so that you can initiate an exit without delay if one is ever needed. That said, it's still perfectly viable to deposit on-chain bitcoin at the time of exit if you don't have any on hand. It just means one extra step when timing may matter. ## Pending sub-balances Bitcoin on the move shows as a pending sub-balance. It counts toward your main balance, but can't be spent until it settles. | Pending sub-balance | What it tracks | | - | - | | Pending on-chain | An incoming on-chain payment awaiting confirmation. | | Pending change | Change from emergency exit fee transactions, awaiting confirmation. | | Pending board | An on-chain deposit [boarding onto Ark](/docs/learn/board). | | Pending in round | Bitcoin in a [refresh](/docs/bark-wallet/vtxos#the-wallet-app-refreshes-vtxos-for-you) that hasn't completed yet. | | Pending Lightning send | An outgoing Lightning payment that hasn't settled yet. | | Pending exit | Bitcoin pending the completion of an [emergency exit](/docs/learn/exit). | ## The next round countdown The card beside the balance counts down to the next [round](/docs/learn/rounds), which is when queued [refreshes](/docs/bark-wallet/vtxos#the-wallet-app-refreshes-vtxos-for-you) execute. ## History The history table mixes your payments with wallet maintenance. Maintenance entries (refreshes and exit fees) are hidden by default. Reveal them from the **Filters** menu. The **All**, **Ark**, **Lightning**, and **On-chain** tabs filter by network. Select a row to open the transaction details: * Where the bitcoin went or came from. * The fee. * Created and completed timestamps. * An editable label and tags. * A **Copy raw JSON** button for troubleshooting. ![Screenshot of the transaction details dialog, with the destination, fee, timestamps, and the editable label and tags](https://mintcdn.com/second-0659a37d/3KiAlC1Xlv9QyI7k/images/bark-wallet/transaction-details.png?fit=max\&auto=format\&n=3KiAlC1Xlv9QyI7k\&q=85\&s=79cde6eea16b1d7f75873400b51e402e) Every entry carries its destination, fee, and an editable label and tags # Bark Wallet Source: https://second.tech/docs/bark-wallet/index A self-custodial wallet app for Ark, Lightning, and on-chain payments, with no channels or liquidity to manage. Run it on Umbrel, Start9, or Docker. Bark Wallet runs on your own hardware. Install it from the Umbrel App Store or the Start9 Registry, or self-host it with Docker. Then create your wallet in your browser and start making payments. ![Screenshot of the Bark Wallet dashboard, with the main balance, its off-chain and on-chain sub-balances, the next round countdown, and the payment history](https://mintcdn.com/second-0659a37d/3KiAlC1Xlv9QyI7k/images/bark-wallet/dashboard-overview.png?fit=max\&auto=format\&n=3KiAlC1Xlv9QyI7k\&q=85\&s=7eb3fa1eb98f57d6f4e9d9c86f5a5a7b) One main balance, spendable over Ark, Lightning, and on-chain ## One balance, every payment network Your bitcoin lives in your Ark balance, and you spend it over Ark, Lightning, or on-chain: * **Pays to anything:** Ark addresses, on-chain addresses, BOLT11 invoices, BOLT12 offers, Lightning addresses, LNURL, and BIP-321 payment links. * **One receive code:** A single QR code combines your Ark, Lightning, and on-chain payment details, and the sender's app picks the cheapest option it supports. * **Free Ark payments:** Sends to another wallet app on the same Ark server cost nothing, down to a single sat. * **Wallet maintenance:** Bark Wallet handles all required maintenance tasks (e.g., [refreshes](/docs/learn/rounds)) in the background for you. * **Emergency exit:** Move your balance back on-chain at any time, [even if the Ark server is offline](/docs/learn/exit). * **Branta-verified recipients:** When a recipient registers with [Branta](https://branta.pro), the wallet app confirms the payment details before you send. ## Barkd under the hood Bark Wallet packages [Barkd](/docs/barkd), Second's wallet daemon, with a web interface (bark-web). Barkd holds your keys on your own device and connects to Second's Ark server, which coordinates rounds and handles Lightning connectivity. Your bitcoin stays under your control. The app is open source under the MIT license, built as a reference implementation: if you're building a wallet app on Barkd, the [bark-web repository](https://gitlab.com/ark-bitcoin/bark-web) shows how Second's own team approached it, UX decisions included. ## Set up and use Bark Wallet > **[Install Bark Wallet](/docs/bark-wallet/install)** > > One click from the Umbrel App Store or the Start9 Registry, or self-host with Docker. > **[Create your wallet](/docs/bark-wallet/create)** > > Name the wallet, write down your seed phrase, and confirm it. > **[Wallet backups](/docs/bark-wallet/backup)** > > Write down your seed phrase and set up continuous backups. > **[Understand your dashboard](/docs/bark-wallet/dashboard)** > > How to read your main balance and its sub-balances, and your payment history. > **[Send and receive bitcoin](/docs/bark-wallet/send-receive)** > > Pay any address or invoice, and receive over Ark, Lightning, or on-chain. > **[Manage your VTXOs](/docs/bark-wallet/vtxos)** > > Inspect the VTXOs behind your balance, and refresh, offboard, or exit them manually. > **[Configure the wallet app](/docs/bark-wallet/settings)** > > Display preferences, refresh behavior, your seed phrase, and the emergency exit. > **[Remote access](/docs/bark-wallet/remote-access)** > > Open the wallet app while you're away from home. > **[Restore your wallet](/docs/bark-wallet/restore)** > > Bring a wallet back from a continuous backup or from your seed phrase. > **[Update or uninstall](/docs/bark-wallet/update-uninstall)** > > Keep the app up to date, or remove it safely after emptying the wallet. # Install Bark Wallet Source: https://second.tech/docs/bark-wallet/install Install Bark Wallet from the Umbrel App Store or the Start9 Registry, or self-host it with Docker, plus instructions on how to create your first wallet. Unless you're using the web version of Bark Wallet, you'll need to install the app. The process depends on the platform you're using. **Umbrel** You need: * A device running [umbrelOS](https://umbrel.com/umbrelos) 0.5 or later. **1. Open the App Store** Open umbrelOS in your browser, at `http://umbrel.local` by default, and select **App Store** in the dock. **2. Find Bark Wallet** Search for "Bark Wallet", or browse the Bitcoin category. The same listing is on the web at [apps.umbrel.com/app/bark-wallet](https://apps.umbrel.com/app/bark-wallet). ![Screenshot of the Bark Wallet listing in the Umbrel App Store, with the Install button](https://mintcdn.com/second-0659a37d/3KiAlC1Xlv9QyI7k/images/bark-wallet/umbrel-app-store.png?fit=max\&auto=format\&n=3KiAlC1Xlv9QyI7k\&q=85\&s=0f382dc60f349f8faf2c059d7067af57) One-click install from the official Umbrel App Store **3. Select Install** umbrelOS downloads and starts the app in the background. **4. Open the app** Select **Open** on the listing, or the new Bark Wallet icon on your umbrelOS home screen. The wallet app opens on its welcome screen: continue with [Create your wallet](/docs/bark-wallet/create). > [!WARNING] > > Bark Wallet has no login of its own. Anyone who can sign in to your umbrelOS can open the wallet app and spend from it. By default, Bark Wallet connects to Second's mainnet Ark server at `ark.second.tech`. You can't configure a different server yet. **Start9** You need: * A device running [StartOS](https://start9.com/) 0.4.0 or later. **1. Open the Marketplace** Select **Marketplace** in the top navigation bar. **2. Install Bark Wallet** Find **Bark Wallet** and select **Install**. The service appears on your **Services** page. ![Screenshot of the Bark Wallet listing in the Start9 Registry, with the Install button and the version panel](https://mintcdn.com/second-0659a37d/3KiAlC1Xlv9QyI7k/images/bark-wallet/start9-marketplace.png?fit=max\&auto=format\&n=3KiAlC1Xlv9QyI7k\&q=85\&s=19694039196757c78f279f816c94ca59) Bark Wallet in the Start9 Registry **3. Run the Set UI Password task** The onboarding tasks sit on the service's **Dashboard**, under **Tasks**. This one generates your login password and displays it. Save it somewhere secure. **4. Acknowledge the Backup Safety task** Read and accept this disclaimer. With Bark, restoring an out-of-date copy of your wallet can cause permanent loss of bitcoin, so only ever restore your most recent backup. The [Wallet backups](/docs/bark-wallet/backup) page explains why. **5. Configure an external backup target** Run the **Configure Backups** task and enable at least one target on a different machine: Google Drive, Dropbox, Nextcloud, or SFTP. > [!WARNING] > > You'll need your seed phrase to [recover from any backups](/docs/bark-wallet/backup) sent to this target. **6. Start the service** Back on the service's **Dashboard**, select **Start**. ![Screenshot of the Bark Wallet service Dashboard on StartOS, with the Stopped status, the Start button, and all tasks complete](https://mintcdn.com/second-0659a37d/3KiAlC1Xlv9QyI7k/images/bark-wallet/start9-dashboard.png?fit=max\&auto=format\&n=3KiAlC1Xlv9QyI7k\&q=85\&s=bb078d6b655ba185c4c54eb54c1ef1f1) All tasks complete: start the service from its Dashboard **7. Open UI and log in** Once the service is running, select **Open UI** and log in with the generated password. The wallet app opens on its welcome screen: continue with [Create your wallet](/docs/bark-wallet/create). ![Screenshot of the Unlock Bark Wallet screen, asking for the password before showing the wallet app](https://mintcdn.com/second-0659a37d/3KiAlC1Xlv9QyI7k/images/bark-wallet/start9-login.png?fit=max\&auto=format\&n=3KiAlC1Xlv9QyI7k\&q=85\&s=3beade976d20936bb27a95b95d00aac1) Password protection blocks unauthorized access to the wallet app on your network By default, Bark Wallet connects to Second's mainnet Ark server at `ark.second.tech`. You can't configure a different server yet. **Self-host** You need: * [Docker](https://docs.docker.com/get-started/get-docker/) with Docker Compose. On Windows, macOS, and Linux, [Docker Desktop](https://docs.docker.com/desktop/) includes both; on Linux, [Docker Engine](https://docs.docker.com/engine/install/) with the [Docker Compose plugin](https://docs.docker.com/compose/install/) also works. * [Git](https://git-scm.com/downloads/). * Optionally, [Node.js](https://nodejs.org/en) 22.12 or later, which gives you shorter npm commands. Docker does the work either way. > **Already running your own Barkd?** > > You can run the web interface alone against an existing `barkd`, without Docker. This path needs [Node.js](https://nodejs.org/en) 22.12 or later. > > **1. Clone the repository and install the dependencies** > > ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} > git clone https://gitlab.com/ark-bitcoin/bark-web.git > cd bark-web > npm install > ``` > > **2. Create your configuration** > > ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} > cp .env.byob.example .env.byob > ``` > > **3. Point it at your daemon** > > In `.env.byob`, set `BARKD_URL` and `BARKD_AUTH_TOKEN`, and match `BARK_NETWORK`, `ARK_SERVER`, and `CHAIN_SOURCE` to your daemon's network; the file ships signet defaults. The token stays server-side and never reaches the browser. > > **4. Start the interface** > > ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} > npm run dev:byob > ``` > > Then open [http://localhost:5173](http://localhost:5173). ### Run the wallet app **1. Clone the repository** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} git clone https://gitlab.com/ark-bitcoin/bark-web.git cd bark-web ``` **2. Start the stack on your network** Pick your network. Mainnet moves real bitcoin; signet is for testing with free bitcoin. **Mainnet** ```bash Docker theme={"theme":{"light":"github-light","dark":"github-dark"}} docker compose --env-file .env.mainnet up --build ``` ```bash npm theme={"theme":{"light":"github-light","dark":"github-dark"}} npm run dev:mainnet ``` By default you'll connect to Second's Ark server at `ark.second.tech`. **Signet** ```bash Docker theme={"theme":{"light":"github-light","dark":"github-dark"}} docker compose --env-file .env.signet up --build ``` ```bash npm theme={"theme":{"light":"github-light","dark":"github-dark"}} npm run dev:signet ``` By default you'll connect to Second's signet Ark server. Setup takes a few minutes during your first run. Leave the terminal running. > [!NOTE] > > The first start creates the Docker volume that will hold your wallet. A storage mirror (RAID 1, or a ZFS or Btrfs mirror) writes a copy of your wallet data, [VTXOs](/docs/learn/vtxo) included, to another disk, so your wallet survives a disk failure. To use one, move Docker's storage onto the mirrored disk before the first start. > > * **Docker Engine:** set [`data-root`](https://docs.docker.com/engine/daemon/) in `/etc/docker/daemon.json`. > * **Docker Desktop:** change **Disk image location** under [**Settings** > **Resources**](https://docs.docker.com/desktop/settings-and-maintenance/settings/). > > A mirror is not a backup, though. See [Wallet backups](/docs/bark-wallet/backup). **3. Open the wallet app** Go to [http://localhost:5173](http://localhost:5173). The wallet app opens on its welcome screen: continue with [Create your wallet](/docs/bark-wallet/create). > [!TIP] > > On signet, fund the wallet with free sats from [Second's faucet](https://signet.2nd.dev/). ### Turn on password protection Out of the box the wallet app has no login. Anyone who can open the wallet page, on your machine or from any device on your local network, can spend from it. To enable password protection on the app, follow these steps. **1. Create the password file** In the repository directory, create `.auth-dev/ui_password` containing only your password (replace `your-strong-password` with your preferred password in the command below). ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} mkdir .auth-dev echo "your-strong-password" > .auth-dev/ui_password ``` **2. Start the wallet app with password protection** **Mainnet** ```bash Docker theme={"theme":{"light":"github-light","dark":"github-dark"}} docker compose -f docker-compose.yml -f docker-compose.auth.yml --env-file .env.mainnet up --build ``` ```bash npm theme={"theme":{"light":"github-light","dark":"github-dark"}} npm run dev:mainnet:auth ``` **Signet** ```bash Docker theme={"theme":{"light":"github-light","dark":"github-dark"}} docker compose -f docker-compose.yml -f docker-compose.auth.yml --env-file .env.signet up --build ``` ```bash npm theme={"theme":{"light":"github-light","dark":"github-dark"}} npm run dev:signet:auth ``` Once enabled, the wallet app asks for your password the next time you open the wallet page. Sessions last seven days, and five failed login attempts trigger an escalating lockout of up to 15 minutes. ![Screenshot of the Unlock Bark Wallet screen, asking for the password before showing the wallet app](https://mintcdn.com/second-0659a37d/3KiAlC1Xlv9QyI7k/images/bark-wallet/password-protection.png?fit=max\&auto=format\&n=3KiAlC1Xlv9QyI7k\&q=85\&s=e4ceb2163a9eb9af16b315fd3ff13acb) With password protection on, the wallet app asks for your password first ### Open from other devices on your network The wallet app is reachable from any device on your network at your machine's local IP address, while the API and `barkd` stay private on your machine. Find the address with `ipconfig` on Windows, `ifconfig` on macOS, or `ip addr` on Linux, then go to `http://:5173` on the other device. Every device talks to the same `barkd`, so the same wallet loads everywhere. Once you've installed Bark Wallet, you'll want to [create your wallet](/docs/bark-wallet/create). # Remote access Source: https://second.tech/docs/bark-wallet/remote-access Open Bark Wallet while you're away from home, using the remote access options for Umbrel, Start9, or a self-hosted install. At home, the wallet app is available on your own network. To use it while you're away, set up remote access for your platform. **Umbrel** Umbrel recommends [Tailscale for remote access](https://umbrel.com/support/basics/remote-access). Install the Tailscale app from the Umbrel App Store, install Tailscale on the device you want to connect from, and sign both into the same Tailscale account. Your Tailscale address then works anywhere you would normally use `umbrel.local`, so you can sign in to umbrelOS and open the wallet app just like you do at home. > [!WARNING] > > Remote access extends who can reach your wallet app. Anyone who can sign in to your umbrelOS can open the wallet app and spend from it, so keep your umbrelOS credentials safe. **Start9** StartOS supports several remote access strategies, including a VPN, Tor, and a public domain. The [official remote access guide](https://docs.start9.com/start-os/0.4.0.x/remote-access.html) walks through each one. Once your connection is set up, open the wallet app with **Open UI** and log in just like you do at home. > [!WARNING] > > Remote access extends who can reach your wallet app. Anyone who has your login password can open the wallet app and spend from it, so keep the password safe. **Self-host** A VPN such as [Tailscale](https://tailscale.com/) gives your devices a secure connection back to the machine that runs the wallet app. Install Tailscale on that machine, install it on the device you want to connect from, and sign both into the same Tailscale account. You can then open the wallet app from anywhere at `http://:5173`. > [!WARNING] > > Remote access extends who can reach your wallet app. Turn on password protection first, under the Self-host tab on the [installation page](/docs/bark-wallet/install), so that a password is required before anyone can spend. > [!NOTE] > > Browsers only allow the camera and clipboard on HTTPS or localhost, so the Scan and Paste buttons stay hidden over a plain HTTP connection. # Restore your wallet Source: https://second.tech/docs/bark-wallet/restore Restore Bark Wallet from your seed phrase or from a continuous backup, on Umbrel, Start9, or a self-hosted install. How you restore depends on which backup you hold. 1. **[Restore from your seed phrase](#restore-from-your-seed-phrase):** Rebuilds your off-chain balance with the Ark server's help. 2. **[Restore a continuous backup](#restore-a-continuous-backup):** Brings the wallet back without any assistance from the server, balance and payment history intact. ## Restore from your seed phrase Restoring from your seed phrase pulls your [VTXOs](/docs/learn/vtxo) back from the Ark server and recovers your on-chain balance with a chain scan. You need: * Your 12-word seed phrase. * A wallet app on the same network and Ark server as the original. > [!WARNING] > > Only restore a seed phrase whose original wallet is gone: two live wallets on the same seed phrase drift apart, which can cause permanent loss of bitcoin. **1. Open the welcome screen** Open the wallet app. If it holds no wallet yet, it opens on the welcome screen, and you can go straight to the next step. If the dashboard opens instead, the wallet app already holds a wallet, and you must delete that wallet before you can restore your old one. Go to **Settings** > **Danger zone** > **Delete wallet** and select **Delete** in the dialog. The wallet app returns to the welcome screen. > [!WARNING] > > Deleting a wallet destroys any bitcoin it still holds. Check the balance first, and if it isn't empty, send the bitcoin out or write down that wallet's seed phrase before deleting. **2. Select Import existing wallet** On the welcome screen, select **Import existing wallet**. ![Screenshot of the Wallet name step of the import flow, with the Seed phrase and Network and servers steps queued in the progress bar, a name field, and the Continue button](https://mintcdn.com/second-0659a37d/aWt2qtiAzrDPasuK/images/bark-wallet/restore-wallet-name.png?fit=max\&auto=format\&n=aWt2qtiAzrDPasuK\&q=85\&s=e6e5e073394d97b2f02140b11b848333) Import existing wallet opens on the Wallet name step **3. Name the wallet** Enter a display name (it doesn't affect recovery) and select **Continue**. **4. Enter your seed phrase** Type your 12 words in order; each field autocompletes as you type. You can also paste the whole seed phrase into the first field, and the wallet app fills in the rest. Select **Continue**. A word the wallet app doesn't recognize turns its field red: check it against the words you wrote down. If the wallet app accepts all 12 words but still reports an invalid seed phrase, check their order. ![Screenshot of the Import seed phrase step, with the 12 numbered word fields and an autocomplete suggestion open](https://mintcdn.com/second-0659a37d/aWt2qtiAzrDPasuK/images/bark-wallet/import-seed-phrase.png?fit=max\&auto=format\&n=aWt2qtiAzrDPasuK\&q=85\&s=a1fc74268e5ce03fcfe626d3ca364be3) Each field autocompletes as you type **5. Confirm the network and servers** The wallet app shows the network, Ark server, and chain source, which you can't change here; check that they match your original wallet. The birthday height is optional and not used with the default chain source, so leave it blank. Select **Continue** to finish. > [!NOTE] > > On a self-hosted install that uses Bitcoin Core as its chain source, the wallet app requires a birthday height. If you don't know it, enter a block height you're sure is earlier than the wallet's creation: a lower height only makes the scan take longer. The wallet app scans the chain for your on-chain balance and pulls your live VTXOs back from the Ark server to rebuild your off-chain balance, then opens the dashboard. This can take a moment. ## Restore a continuous backup **Umbrel** There's no mature continuous backup solution for Bark Wallet on Umbrel yet; we'll update this section when that changes. If you set up umbrelOS backups, you can try [restoring your latest one](https://umbrel.com/support/backups-and-recovery/restoring-from-a-backup). The restore covers your entire Umbrel, every app included, so your wallet directory comes back as it was when that backup was taken. > [!WARNING] > > If your wallet has changed since the backup was taken, you may need to [restore from your seed phrase](#restore-from-your-seed-phrase), which relies on the Ark server. **Start9** To restore from a continuous backup, follow Start9's [official guide for restoring an individual service](https://docs.start9.com/start-os/0.4.0.x/backup-restore.html#restoring-individual-services). If you need to restore onto a new Start9 device, follow the [initial setup guide](https://docs.start9.com/start-os/0.4.0.x/initial-setup.html) and select **Restore From Backup**. Server-level backups don't include your wallet data. They carry a pointer instead, made up of your seed phrase and your backup-target credentials. After the restore, the service pulls the freshest wallet snapshot from your backup targets automatically, bringing back your balance and payment history. If no target is reachable, the service falls back to a seed phrase recovery, which relies on the Ark server. **Self-host** There's no mature continuous backup solution for self-hosted installs yet, so restore depends on what you set up; we'll update this section when that changes. If you were using [bark-backupd](https://gitlab.com/ark-bitcoin/labs/bark-backupd), stop the wallet app and run `bark-backupd restore` before starting it again. If you were replicating with [Litestream](https://litestream.io/reference/restore/), run `litestream restore` to put your latest copy back in the wallet data volume before starting the stack. > [!WARNING] > > If your wallet has changed since the backup was taken, you may need to [restore from your seed phrase](#restore-from-your-seed-phrase), which relies on the Ark server. # Send and receive bitcoin Source: https://second.tech/docs/bark-wallet/send-receive Move bitcoin in and out of Bark Wallet: receive over Ark, Lightning, or on-chain with one QR code, and send to any address, invoice, or payment link. Move bitcoin in and out of Bark Wallet with the **Send** and **Receive** buttons at the top right, available from every page. A **Scan** button appears alongside them when the browser can use a camera, which requires a secure (HTTPS) connection. Over umbrelOS's default HTTP connection, Scan stays hidden. ## Receive bitcoin Receive opens on the **Pay to** tab: one QR code, a single BIP-321 payment link that contains: * Your Ark address. * A Lightning invoice, once you enter an amount. * Your on-chain address. The sender's wallet app picks the cheapest network it supports, and the pills underneath show which networks the QR code covers. ![Screenshot of the Receive modal on the Pay to tab, with the combined QR code and the Ark, Lightning, and On-chain network pills](https://mintcdn.com/second-0659a37d/3KiAlC1Xlv9QyI7k/images/bark-wallet/receive-pay-to.png?fit=max\&auto=format\&n=3KiAlC1Xlv9QyI7k\&q=85\&s=abe7bd53bfeb85565de414683bb7282e) One QR code, payable over Ark, Lightning, or on-chain The other tabs isolate a single network: * **Ark:** An Ark address, for payments from wallet apps on the same Ark server. * **Lightning:** A BOLT11 invoice. Enter an amount to generate it. * **On-chain:** An on-chain address. Where the bitcoin lands depends on the network: * Ark and Lightning payments arrive in your off-chain balance as [VTXOs](/docs/learn/vtxo), ready to spend immediately. * On-chain payments arrive in the [on-chain balance](/docs/bark-wallet/dashboard#your-on-chain-balance), the wallet app's reserve for emergency exit fees and on-chain sends. You can attach a label and tags under **Additional details**; they'll mark the incoming payment in your [history](/docs/bark-wallet/dashboard#history). **New address** (or **New invoice** on the Lightning tab) generates a fresh one. ## Send bitcoin **1. Select Send** Or select **Scan** to point the camera at a QR code directly. **2. Paste or scan the destination** Bark Wallet accepts: * Ark addresses * On-chain addresses * BOLT11 invoices * BOLT12 offers * Lightning addresses * LNURL links * BIP-321 payment links For Lightning addresses, you can add an optional **Message** under **Additional details**; it travels with the payment. **3. Pick the network, if the destination offers several** A BIP-321 payment link may be payable over more than one network. The app preselects the cheapest and shows the alternatives as pills, each with its fee; Ark shows as free. ![Screenshot of the Send modal with a BIP-321 destination decoded into Ark, Lightning, and On-chain pills, with the Ark option selected as free](https://mintcdn.com/second-0659a37d/3KiAlC1Xlv9QyI7k/images/bark-wallet/send-destinations.png?fit=max\&auto=format\&n=3KiAlC1Xlv9QyI7k\&q=85\&s=0a3b9e8123a9b0538e9478edeb51ebdd) One payment link, three networks to choose from **4. Enter the amount** Use the toggle in the field to switch between bitcoin and fiat entry. Invoices that carry a fixed amount fill and lock the field. The estimated fee appears under the amount. **5. Select Confirm send** The payment appears in your [history](/docs/bark-wallet/dashboard#history) with its status. For an on-chain destination, a **Pay from** selector also appears. It defaults to your Ark balance and can stay there. Its **On-chain wallet** option spends the [on-chain balance](/docs/bark-wallet/dashboard#your-on-chain-balance) instead, and only pays on-chain addresses. ## Bark Wallet fees * **From the Ark balance:** Sends to Lightning or on-chain destinations carry fees that scale with the amount and your VTXOs' remaining lifetime; sends to an Ark address are free. See [Second's pricing](https://second.tech/pricing). * **From the on-chain wallet:** Standard on-chain fees. ## Confirm the recipient with Branta When the destination you enter is registered with [Branta](https://branta.pro), a verification panel names the platform it belongs to, so you can confirm the payment details match who you think you're paying. Recipients opt in to Branta on their side: no panel simply means the destination isn't registered, not that anything is wrong. # Configure the wallet app Source: https://second.tech/docs/bark-wallet/settings Configure Bark Wallet: display and units, the auto-refresh threshold, your seed phrase backup, diagnostic logs, and the Danger zone emergency exit. Bark Wallet's configuration lives on the **Settings** page, in the sidebar. Changes apply as you make them. ![Screenshot of the top of the Bark Wallet Settings page, with the wallet name, theme, unit, and currency options](https://mintcdn.com/second-0659a37d/3KiAlC1Xlv9QyI7k/images/bark-wallet/settings.png?fit=max\&auto=format\&n=3KiAlC1Xlv9QyI7k\&q=85\&s=9d0acdb1462c316a9872a7eea8eeaeeb) ## Display, units, and price * **Wallet name:** The name shown in the sidebar. * **Interface theme:** Light, Dark, or System (the default). * **Bitcoin unit:** Amounts in Sats (the default) or Bitcoin. * **Bitcoin price source:** Kraken (the default), CoinGecko, or Binance. * **Fiat currency:** USD (the default) or EUR. The wallet app values history rows at the latest price, not the price at payment time. * **Discreet mode:** Hide balances and transaction amounts. Off by default. ## Refresh behavior ### Auto-refresh threshold The wallet app refreshes any VTXO whose remaining lifetime drops below this threshold. Every option in the picker is labeled with its cost. The default, one day before expiry, keeps automatic refreshes free, while wider thresholds trade [liquidity fees](/docs/learn/rounds#round-economics) for a larger safety margin. ### Refresh on receive Off by default. When enabled, the wallet app refreshes each received VTXO in the next available round rather than waiting for the threshold. Maximum security, at a significantly higher running cost: see [receiving a Lightning payment](/docs/learn/payments-lightning#receiving-a-lightning-payment) for the trust model, and [Second's pricing](https://second.tech/pricing). ### Refresh all Queue every VTXO in your wallet for the next round. ## Back up your seed phrase The **Seed phrase** control reveals your wallet's 12 words; write them down somewhere safe and offline. ![Screenshot of the bottom of the Settings page, with the seed phrase backup warning, the support entries, and the Danger zone holding the Emergency exit all and Delete wallet buttons](https://mintcdn.com/second-0659a37d/3KiAlC1Xlv9QyI7k/images/bark-wallet/settings-danger-zone.png?fit=max\&auto=format\&n=3KiAlC1Xlv9QyI7k\&q=85\&s=1ca434358b33b498855ebf8f69d8f79b) The seed phrase warning and the Danger zone sit at the bottom of Settings > [!NOTE] > > Restoring your wallet takes two things: the seed phrase, and the wallet data that tracks its bitcoin. [Wallet backups](/docs/bark-wallet/backup) explains the model and shows how to set up continuous backups on your platform. ## Get help and report issues * **Community forum:** Questions and advice, at [community.second.tech](https://community.second.tech). * **Report an issue:** Bugs and feature requests, on the [bark-web repository](https://gitlab.com/ark-bitcoin/bark-web). * **Diagnostic logs:** Download the `barkd` debug log to share when troubleshooting. ## Danger zone **Emergency exit all** begins a process that reclaims your entire off-chain balance on-chain [without the Ark server's cooperation](/docs/learn/exit). To exit only some VTXOs, use the [VTXOs page](/docs/bark-wallet/vtxos#refresh-offboard-or-exit-selected-vtxos) instead. > [!WARNING] > > Use this only when the Ark server is unresponsive and you can no longer spend your VTXOs. Completing an exit takes multiple on-chain transactions per VTXO, so fees can be significant. If the server is still responding, an on-chain payment from [Send](/docs/bark-wallet/send-receive#send-bitcoin) is faster and cheaper. **1. Check the cost estimate** The dialog shows how many VTXOs will exit and an estimated total cost at the current feerate. The wallet app pays exit fees from your [on-chain balance](/docs/bark-wallet/dashboard#your-on-chain-balance). If the balance can't cover the estimate, the app asks you to deposit on-chain bitcoin first. **2. Set the destination address** This is where the wallet app sweeps the exited bitcoin once the exit outputs unlock. Paste your own on-chain address, or select **Use my Bark on-chain wallet**. > [!WARNING] > > Double-check the address. An emergency exit cannot be canceled once started. **3. Select Start emergency exit** The wallet app starts broadcasting the exit transactions and shows a progress card in Settings. ![Screenshot of the Emergency exit all dialog, with the cost estimate, the number of VTXOs to exit, the on-chain balance, and the destination address field](https://mintcdn.com/second-0659a37d/3KiAlC1Xlv9QyI7k/images/bark-wallet/emergency-exit-dialog.png?fit=max\&auto=format\&n=3KiAlC1Xlv9QyI7k\&q=85\&s=b0ff2045eb6a768c16482879484445fa) ## Follow the exit to completion An emergency exit takes time. The wallet app broadcasts multiple on-chain transactions in sequence, and once a VTXO's final exit transaction confirms, a timelock (the exit delta) must pass before its output unlocks. The progress card tracks every VTXO through its phases, from Starting and Broadcasting through Timelocked, Ready to claim, Claiming, and Claimed. Once outputs unlock and a destination address is set, the wallet app sweeps them automatically while it's open in your browser. If the card shows **Add address to claim**, set a destination so the sweep can proceed. Completed exits appear in your [history](/docs/bark-wallet/dashboard#history) as "On-chain: Exit"; their fees show as "On-chain: Exit fee", hidden by default like other maintenance entries. ## Delete the wallet **Delete wallet**, also in the Danger zone, deletes the current wallet. Select **Delete** in the confirmation dialog, and the wallet app returns to its welcome screen, where you can [create a new wallet](/docs/bark-wallet/create) or [import an existing one](/docs/bark-wallet/restore#restore-from-your-seed-phrase). > [!WARNING] > > Deleting the wallet cannot be undone. Empty the wallet, or make sure you've [backed it up](/docs/bark-wallet/backup), before deleting. # Update or uninstall the wallet app Source: https://second.tech/docs/bark-wallet/update-uninstall Keep Bark Wallet up to date on Umbrel, Start9, or a self-hosted install, or uninstall it safely when you no longer need it. ## Update the wallet app New versions carry the latest security fixes, so update as soon as one ships. **Umbrel** Update manually from the App Store when a new version ships. **1. Open the App Store** Select **App Store** in the dock. When a new Bark Wallet version is available, an **Updates** button appears at the top right. **2. Update Bark Wallet** Select **Updates**, then **Update** next to Bark Wallet. **Start9** Update manually when a new version reaches the registry. **1. Open the Updates tab** Select **Updates** in the top navigation bar. A badge on the tab signals a waiting update. **2. Update Bark Wallet** Select **Update** next to Bark Wallet. **Self-host** Pull the latest code, then start the stack with the same command. **Mainnet** ```bash Docker theme={"theme":{"light":"github-light","dark":"github-dark"}} git pull docker compose --env-file .env.mainnet up --build ``` ```bash npm theme={"theme":{"light":"github-light","dark":"github-dark"}} git pull npm run dev:mainnet ``` **Signet** ```bash Docker theme={"theme":{"light":"github-light","dark":"github-dark"}} git pull docker compose --env-file .env.signet up --build ``` ```bash npm theme={"theme":{"light":"github-light","dark":"github-dark"}} git pull npm run dev:signet ``` ## Uninstall the wallet app **Umbrel** > [!WARNING] > > umbrelOS permanently deletes an uninstalled app's data, wallet included. Empty the wallet, or make sure you've [backed it up](/docs/bark-wallet/backup), before uninstalling. **1. Uninstall from the home screen** Right-click the Bark Wallet icon on your umbrelOS home screen and select **Uninstall**. **2. Confirm the deletion** umbrelOS warns that all app data will be permanently deleted. Select **Uninstall** to confirm. **Start9** > [!WARNING] > > StartOS permanently deletes an uninstalled service's data, wallet included. Empty the wallet, or make sure you've [backed it up](/docs/bark-wallet/backup), before uninstalling. **1. Uninstall from Actions & Config** Go to the Bark Wallet service's **Actions & Config** and select **Uninstall**, under **StartOS**. **2. Confirm the deletion** StartOS warns that Bark Wallet's data will be permanently deleted. Select **Uninstall** to confirm. **Self-host** To stop the wallet app without deleting anything, run the stop command from the repository directory. **Mainnet** ```bash Docker theme={"theme":{"light":"github-light","dark":"github-dark"}} docker compose --env-file .env.mainnet down ``` ```bash npm theme={"theme":{"light":"github-light","dark":"github-dark"}} npm run down:mainnet ``` **Signet** ```bash Docker theme={"theme":{"light":"github-light","dark":"github-dark"}} docker compose --env-file .env.signet down ``` ```bash npm theme={"theme":{"light":"github-light","dark":"github-dark"}} npm run down:signet ``` Your wallet stays in place for the next start. Docker stores each network's wallet in its own volume, `bark-signet_wallet-data` or `bark-mainnet_wallet-data`, so your signet and mainnet wallets stay separate. To delete a wallet, reset it. A reset deletes the network's volume and its wallet, and on the next start the wallet app opens on its welcome screen, where you [create](/docs/bark-wallet/create) or [import](/docs/bark-wallet/restore#restore-from-your-seed-phrase) a wallet. The commands are the stop commands with `-v` added. > [!WARNING] > > A reset permanently deletes that network's wallet, seed phrase included. Empty the wallet, or make sure you've [backed it up](/docs/bark-wallet/backup), before resetting. **Mainnet** ```bash Docker theme={"theme":{"light":"github-light","dark":"github-dark"}} docker compose --env-file .env.mainnet down -v ``` ```bash npm theme={"theme":{"light":"github-light","dark":"github-dark"}} npm run down:mainnet -- -v ``` **Signet** ```bash Docker theme={"theme":{"light":"github-light","dark":"github-dark"}} docker compose --env-file .env.signet down -v ``` ```bash npm theme={"theme":{"light":"github-light","dark":"github-dark"}} npm run down:signet -- -v ``` # Manage your VTXOs Source: https://second.tech/docs/bark-wallet/vtxos Inspect the VTXOs behind your Bark Wallet off-chain balance, let the app refresh them automatically, and refresh, offboard, or exit them manually. The **VTXOs** page, in the sidebar, lists the [VTXOs](/docs/learn/vtxo) that make up your off-chain balance. A VTXO shows as **Spendable** most of its life, as locked while an operation uses it, and with its exit phase while an [emergency exit](/docs/bark-wallet/settings#danger-zone) is in progress. Spent VTXOs are hidden; the **Filter** menu can reveal exited ones. ![Screenshot of the VTXOs page listing spendable VTXOs with their expiry block heights, statuses, and amounts](https://mintcdn.com/second-0659a37d/3KiAlC1Xlv9QyI7k/images/bark-wallet/vtxos.png?fit=max\&auto=format\&n=3KiAlC1Xlv9QyI7k\&q=85\&s=ce6d9b57fb198adfaefc86df94447f5d) The VTXOs behind your off-chain balance, with their expiry and status ## The wallet app refreshes VTXOs for you VTXOs have a limited [lifetime](/docs/learn/lifetime), so they must be refreshed before expiry, and Bark Wallet does this for you. It automatically refreshes any VTXO whose remaining lifetime drops below the configured threshold, one day by default, which keeps automatic refreshes inside the free window. You can raise the threshold, refresh every payment as it's received, or refresh everything at once from [settings](/docs/bark-wallet/settings#refresh-behavior). The wallet app submits queued refreshes to [rounds](/docs/learn/rounds), which occur every hour; the countdown at the top of the page shows when the next one starts. ## Refresh, offboard, or exit selected VTXOs Advanced users may sometimes want granular control over their VTXOs. For example, a user with a particularly large VTXO might prefer to refresh it before it reaches the threshold, or to bring its bitcoin on-chain. To act on individual VTXOs, tick one or more in the list, then select an action in the bar that appears: * **Refresh:** Mark the selected VTXOs for refresh in the next [round](/docs/learn/rounds). You forfeit them and receive fresh ones. * **Offboard:** Make an on-chain payment from the selected VTXOs to an address you paste, or to the wallet app's own on-chain wallet with **Use my Bark on-chain wallet**. The wallet app deducts the on-chain transaction fee from the [offboarded](/docs/learn/offboard) amount. * **Emergency Exit:** Reclaim the selected VTXOs' bitcoin on-chain without the Ark server's cooperation: the per-VTXO version of the [emergency exit](/docs/bark-wallet/settings#danger-zone), with the same warnings. ![Screenshot of the VTXOs page with two VTXOs selected and the action bar showing the Refresh, Offboard, and Emergency Exit buttons](https://mintcdn.com/second-0659a37d/3KiAlC1Xlv9QyI7k/images/bark-wallet/vtxos-selected.png?fit=max\&auto=format\&n=3KiAlC1Xlv9QyI7k\&q=85\&s=adfdd1abfea41157c9100c07e39f2829) Selecting VTXOs brings up the Refresh, Offboard, and Emergency Exit actions > [!TIP] > > To bring off-chain bitcoin on-chain, most users will prefer [Send](/docs/bark-wallet/send-receive#send-bitcoin) instead. You can send from your Ark balance straight to an on-chain address. ## Inspect a VTXO Select a row to open its details: * The policy type (how the VTXO can be spent). * The [expiry](/docs/learn/lifetime). * The [exit delta](/docs/learn/exit#the-emergency-exit-process) (how long an exit output stays timelocked after confirming on-chain). * The exit depth (how many on-chain transactions a full exit takes). * The ID and the [chain anchor](/docs/learn/vtxo). **Copy raw JSON** exports everything for troubleshooting. ![Screenshot of the VTXO details dialog, with the policy type, expiry, exit delta, exit depth, and chain anchor](https://mintcdn.com/second-0659a37d/3KiAlC1Xlv9QyI7k/images/bark-wallet/vtxo-details.png?fit=max\&auto=format\&n=3KiAlC1Xlv9QyI7k\&q=85\&s=6a5ebb399209008925008dc11f80bfc2) A VTXO's details, including its exit delta and exit depth ## Refresh an expired VTXO If a VTXO has [expired](/docs/learn/lifetime#what-happens-when-vtxos-expire), the **Expiry** column shows **Expired** under its block height. Bark Wallet queues it for the next round as soon as you open the wallet app. Let the refresh complete before you send an Ark payment: 1. Check that the VTXO's status shows **Queued** or **Refreshing**. 2. If it still shows **Spendable** a minute after you open the wallet app, tick the VTXO and select **Refresh**. A **Refresh started** message confirms it. 3. Wait for the round's transaction to confirm, about one block after the round. A fresh VTXO then replaces the expired one. ![Screenshot of the VTXOs page with an expired VTXO whose status shows Queued, above VTXOs that expire in about four weeks](https://mintcdn.com/second-0659a37d/sWpp6Y7pxlHxdWXE/images/bark-wallet/vtxos-expired.png?fit=max\&auto=format\&n=sWpp6Y7pxlHxdWXE\&q=85\&s=ba0797ca12832dc476fdc8f1f0d12c03) Bark Wallet queues an expired VTXO for the next round by itself # Get bitcoin tip height Source: https://second.tech/docs/barkd/api-reference/bitcoin/get-bitcoin-tip-height https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json get /api/v1/bitcoin/tip Queries the wallet's chain source for the block height of the latest block on the best chain. # Board a specific amount Source: https://second.tech/docs/barkd/api-reference/boards/board-a-specific-amount https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json post /api/v1/boards/board-amount Moves the specified amount of bitcoin in the on-chain wallet onto the Ark protocol. Creates and broadcasts a funding transaction, then returns the pending board details. The resulting VTXO is not spendable off-chain until the funding transaction reaches the number of on-chain confirmations required by the Ark server. # Board all on-chain bitcoin Source: https://second.tech/docs/barkd/api-reference/boards/board-all-on-chain-bitcoin https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json post /api/v1/boards/board-all Moves all bitcoin in the on-chain wallet onto the Ark protocol. Creates and broadcasts a funding transaction that drains the on-chain balance into a single VTXO, then returns the pending board details. The resulting VTXO is not spendable off-chain until the funding transaction reaches the number of on-chain confirmations required by the Ark server. # List pending boards Source: https://second.tech/docs/barkd/api-reference/boards/list-pending-boards https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json get /api/v1/boards/pending Returns all boards whose funding transactions have not yet reached the number of on-chain confirmations required by the Ark server. # Cancel an exit Source: https://second.tech/docs/barkd/api-reference/exits/cancel-an-exit https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json post /api/v1/exits/cancel/{vtxo_id} Aborts an in-progress emergency exit while it is still safe to do so—before its final transaction has been broadcast. Exit transactions are ordered topologically and only the final one moves the VTXO on-chain, so an exit can still be canceled even after its shared ancestor transactions are in the mempool or a block. Canceling leaves the VTXO spendable, so a fresh exit can be started for it later. Before canceling, the endpoint verifies directly against the chain that the final transaction hasn't been broadcast; nothing is rebroadcast in the process. Canceling an already-canceled exit succeeds as a no-op, so retries are safe. Note the daemon auto-progresses exits at the interval set by the `daemon_sync_interval_secs` config setting, so cancel promptly once an exit reaches a state you no longer wish to pursue. # Claim all exited VTXOs Source: https://second.tech/docs/barkd/api-reference/exits/claim-all-exited-vtxos https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json post /api/v1/exits/claim/all Sweeps all claimable exit outputs into a single on-chain transaction sent to the specified address. Unlike `progress`, the daemon does not claim automatically—this endpoint must be called manually. Poll the `status` endpoint or call `progress` and check for `done: true` to know when VTXOs are ready to claim. This is the final step of the emergency exit process—the bitcoin is not considered back on-chain until this transaction confirms. # Claim specific exited VTXOs Source: https://second.tech/docs/barkd/api-reference/exits/claim-specific-exited-vtxos https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json post /api/v1/exits/claim/vtxos Sweeps the specified claimable exit outputs into a single on-chain transaction sent to the specified address. Unlike `progress`, the daemon does not claim automatically—this endpoint must be called manually. Poll the `status` endpoint or call `progress` and check for `done: true` to know when VTXOs are ready to claim. This is the final step of the emergency exit process—the bitcoin is not considered back on-chain until this transaction confirms. # Estimate emergency exit fee Source: https://second.tech/docs/barkd/api-reference/exits/estimate-emergency-exit-fee https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json get /api/v1/exits/fee Estimates the on-chain cost of unilaterally (emergency) exiting a set of VTXOs without server cooperation. The breakdown separates the broadcast cost—CPFP-bumping every not-yet-confirmed transaction in each VTXO's exit tree, paid from confirmed on-chain funds—from the claim cost of the single batched transaction that later drains the matured outputs. The estimate reflects current chain state, so exit transactions already confirmed cost nothing. The broadcast fee includes the `fee_margin` scaling and is the on-chain balance to fund the exit with at that margin; the wallet's actual funds are never consulted. # Get exit status (deprecated) Source: https://second.tech/docs/barkd/api-reference/exits/get-exit-status-deprecated https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json get /api/v1/exits/status/{vtxo_id} Deprecated: use `GET /exits/status/vtxo/{vtxo_id}` instead. # Get VTXO exit status Source: https://second.tech/docs/barkd/api-reference/exits/get-vtxo-exit-status https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json get /api/v1/exits/status/vtxo/{vtxo_id} Returns the exit status for the given VTXO, live or finished. Optionally includes the state history and the exit transactions with their CPFP children. # List all exit statuses Source: https://second.tech/docs/barkd/api-reference/exits/list-all-exit-statuses https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json get /api/v1/exits/status/all Returns every exit, live and finished. Optionally includes each exit's state history and its transactions with their CPFP children. # List all exit statuses (deprecated) Source: https://second.tech/docs/barkd/api-reference/exits/list-all-exit-statuses-deprecated https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json get /api/v1/exits/status Deprecated: redirects to `GET /exits/status/all`. # List finished exits Source: https://second.tech/docs/barkd/api-reference/exits/list-finished-exits https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json get /api/v1/exits/status/finished Returns exits that reached a terminal state: claimed, aborted because the VTXO was already spent, or canceled. Finished exits are dropped from active tracking—they are never progressed—but they're retained for auditing and surfaced here. # List live exit statuses Source: https://second.tech/docs/barkd/api-reference/exits/list-live-exit-statuses https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json get /api/v1/exits/status/live Returns exits that are still progressing. Optionally includes each exit's state history and its transactions with their CPFP children. # Progress exits Source: https://second.tech/docs/barkd/api-reference/exits/progress-exits https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json post /api/v1/exits/progress Triggers all in-progress exits to advance. The daemon already progresses exits automatically in the background—use this endpoint when you want immediate progress rather than waiting for the next automatic cycle. On each call, the endpoint syncs transaction statuses, advances the exit state machine, and creates or fee-bumps CPFP children for any exit transactions that need them. The on-chain wallet must have sufficient bitcoin to cover transaction fees. # Start exit for all VTXOs Source: https://second.tech/docs/barkd/api-reference/exits/start-exit-for-all-vtxos https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json post /api/v1/exits/start/all Registers all wallet VTXOs for emergency exit. The daemon automatically progresses registered exits in the background at the interval set by the `daemon_sync_interval_secs` config setting, creating and broadcasting the required transactions in sequence. Once all exit transactions are confirmed and the timelock has elapsed, call `claim` to sweep the resulting outputs to an on-chain address. # Start exit for specific VTXOs Source: https://second.tech/docs/barkd/api-reference/exits/start-exit-for-specific-vtxos https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json post /api/v1/exits/start/vtxos Registers the specified VTXOs for emergency exit. The daemon automatically progresses registered exits in the background at the interval set by the `daemon_sync_interval_secs` config setting, creating and broadcasting the required transactions in sequence. Once all exit transactions are confirmed and the timelock has elapsed, call `claim` to sweep the resulting outputs to an on-chain address. # Estimate board fee Source: https://second.tech/docs/barkd/api-reference/fees/estimate-board-fee https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json get /api/v1/fees/board Estimates the Ark protocol fee for boarding the specified amount of on-chain bitcoin. The net amount is what the user receives as a VTXO. Does not include the on-chain transaction fee for the board anchor transaction. # Estimate Lightning receive fee Source: https://second.tech/docs/barkd/api-reference/fees/estimate-lightning-receive-fee https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json get /api/v1/fees/lightning/receive Estimates the fee for receiving the specified amount over Lightning. The gross amount is the Lightning payment amount, and the net amount is what the user receives as a VTXO after the Ark server deducts its fee. # Estimate Lightning send fee Source: https://second.tech/docs/barkd/api-reference/fees/estimate-lightning-send-fee https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json get /api/v1/fees/lightning/pay Estimates the fee for sending the specified amount over Lightning. The net amount is what the recipient receives. The fee depends on the VTXOs selected and their expiry. If the wallet has insufficient funds, returns a worst-case fee estimate assuming the user acquires enough funds to cover the payment. # Estimate offboard-all fee Source: https://second.tech/docs/barkd/api-reference/fees/estimate-offboard-all-fee https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json get /api/v1/fees/offboard-all Estimates the fee for offboarding the entire Ark balance to the given on-chain address. The gross amount is the total spendable balance, and the net amount is what the user receives on-chain after fees. The fee depends on the destination address type, current fee rates, and VTXO expiry. # Estimate offboard fee Source: https://second.tech/docs/barkd/api-reference/fees/estimate-offboard-fee https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json post /api/v1/fees/offboard Estimates the fee for offboarding a specific set of VTXOs to the given on-chain address. Each VTXO is offboarded in full. The gross amount is the total value of the selected VTXOs, and the net amount is what the user receives on-chain after fees. The fee depends on the destination address type, current fee rates, and VTXO expiry. # Estimate send-onchain fee Source: https://second.tech/docs/barkd/api-reference/fees/estimate-send-onchain-fee https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json get /api/v1/fees/send-onchain Estimates the total fee for sending bitcoin from the Ark wallet to an on-chain address. The fee depends on the destination address type and current fee rates. The gross amount is what the user pays (including VTXOs spent), and the net amount is what the recipient receives on-chain. # Get on-chain fee rates Source: https://second.tech/docs/barkd/api-reference/fees/get-on-chain-fee-rates https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json get /api/v1/fees/onchain Returns the current mempool fee rates from the chain source at three confirmation targets: fast (~1 block), regular (~3 blocks), and slow (~6 blocks). Rates are in sat/vB, rounded up. # Get wallet history Source: https://second.tech/docs/barkd/api-reference/history/get-wallet-history https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json get /api/v1/history Returns the history of wallet movements ordered from newest to oldest. A movement represents any wallet operation that affects VTXOs—an arkoor send or receive, Lightning send or receive, board, offboard, or refresh. Each entry records which VTXOs were consumed and produced, the effective balance change (if any), fees paid, and the operation status. Supplying the `type` and `value` query parameters (together) restricts the result to movements involving that single payment method, such as all payments sent to one address. # Patch movement metadata Source: https://second.tech/docs/barkd/api-reference/history/patch-movement-metadata https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json post /api/v1/history/{id}/metadata Applies an [RFC 7396](https://www.rfc-editor.org/rfc/rfc7396) JSON Merge Patch to a movement's metadata. Use this to annotate history entries after the fact (e.g. refund notes, counterparty info). Keys set to `null` are removed; other values are recursively merged. # Cancel a pending receive Source: https://second.tech/docs/barkd/api-reference/lightning/cancel-a-pending-receive https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json delete /api/v1/lightning/receives/{identifier} Cancels a pending Lightning receive identified by its payment hash or invoice string. The server will refuse cancellation if HTLC-recv VTXOs have already been granted. Bark also prevents cancellation when the preimage has been revealed. # Create a BOLT11 invoice Source: https://second.tech/docs/barkd/api-reference/lightning/create-a-bolt11-invoice https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json post /api/v1/lightning/receives/invoice Generates a new BOLT11 invoice for the specified amount via the Ark server, creating a pending Lightning receive. # Create a BOLT11 invoice for an Ark address Source: https://second.tech/docs/barkd/api-reference/lightning/create-a-bolt11-invoice-for-an-ark-address https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json post /api/v1/lightning/receives/invoice/for-address Generates a new BOLT11 invoice. When paid, the wallet claims the Lightning receive and forwards the resulting Ark VTXO to the supplied Ark address mailbox. # Get receive status Source: https://second.tech/docs/barkd/api-reference/lightning/get-receive-status https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json get /api/v1/lightning/receives/{identifier} Returns the status of a specified Lightning receive, identified by its payment hash, invoice string, or preimage. `state` tracks its progress and `settled_at` records when it settled. A receive that ended without settling, for example a canceled one, is no longer known and returns 404. # Get send status Source: https://second.tech/docs/barkd/api-reference/lightning/get-send-status https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json get /api/v1/lightning/sends/{identifier} Returns the status of a specified outgoing Lightning payment, identified by its payment hash or invoice string. The `state` field tracks the payment lifecycle from `start` through `paid`; the preimage is included once the payment succeeded. If the wallet does not recognize the payment hash, it will return `unknown`. This is a read on the status in the db, so it does not trigger any `sync` before checking the state. # List all pending receive statuses Source: https://second.tech/docs/barkd/api-reference/lightning/list-all-pending-receive-statuses https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json get /api/v1/lightning/receives Returns the statuses of all pending Lightning receives, ordered from oldest to newest. A receive is pending until its `finished_at` timestamp is set, indicating it has settled or been canceled. # Send a Lightning payment Source: https://second.tech/docs/barkd/api-reference/lightning/send-a-lightning-payment https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json post /api/v1/lightning/pay Sends a payment to a Lightning destination. Accepts a BOLT11 invoice, BOLT12 offer, Lightning address, or LNURL. The `amount_sat` field is required for Lightning addresses and LNURL but optional for invoices and offers that already encode an amount. Comments are only supported for Lightning addresses and LNURL. # Sign a message Source: https://second.tech/docs/barkd/api-reference/message/sign-a-message https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json post /api/v1/message/sign Signs an arbitrary message with a BIP-340 Schnorr signature over a prefixed hash (`SHA256("bark/message" || message)`) of the UTF-8 message bytes. The message is signed with the key of the given Ark address, which must be one of the wallet's own addresses; addresses that do not belong to the wallet are rejected. The resulting signature can be checked with the `/message/verify` endpoint. # Verify a signed message Source: https://second.tech/docs/barkd/api-reference/message/verify-a-signed-message https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json post /api/v1/message/verify Verifies a BIP-340 Schnorr signature over a prefixed hash (`SHA256("bark/message" || message)`) of the UTF-8 message bytes, as created by the `/message/sign` endpoint. The signature is checked against a public key (`pubkey`) or against the user public key of an Ark address (`address`); exactly one of the two must be set. Verification is stateless and works for signatures made by any wallet, not just this one. # Create a websocket ticket Source: https://second.tech/docs/barkd/api-reference/notifications/create-a-websocket-ticket https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json get /api/v1/notifications/ws/ticket Creates a single-use ticket that authenticates a websocket connection at `ws:///api/v1/notifications/ws?ticket=`. The ticket must be used within 10 minutes of creation; the resulting websocket connection is long-lived. The handshake answers 401 for an unknown, already used or expired ticket, and 422 when no wallet is loaded. The ticket is consumed in all of these cases. # Long-poll for wallet notifications Source: https://second.tech/docs/barkd/api-reference/notifications/long-poll-for-wallet-notifications https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json get /api/v1/notifications/wait Long-polls for wallet notifications. Returns all notifications received since the given timestamp. If no timestamp is provided, returns all notifications in the buffer. Returned notifications are sorted by timestamp in ascending order. # Drain on-chain wallet Source: https://second.tech/docs/barkd/api-reference/onchain/drain-on-chain-wallet https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json post /api/v1/onchain/drain Sends the entire on-chain wallet balance to the specified address. The recipient receives the full balance minus transaction fees. Broadcasts immediately at a fee rate targeting confirmation within three blocks and returns the transaction ID. # Generate on-chain address Source: https://second.tech/docs/barkd/api-reference/onchain/generate-on-chain-address https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json post /api/v1/onchain/addresses/next Generates a new on-chain receiving address. Each call returns the next unused address from the wallet's HD keychain. # Get on-chain balance Source: https://second.tech/docs/barkd/api-reference/onchain/get-on-chain-balance https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json get /api/v1/onchain/balance Returns the current on-chain wallet balance, broken down by confirmation status. The `trusted_spendable_sat` field is the sum of `confirmed_sat` and `trusted_pending_sat`—the balance that can be safely spent without risk of double-spend. # List on-chain transactions Source: https://second.tech/docs/barkd/api-reference/onchain/list-on-chain-transactions https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json get /api/v1/onchain/transactions Returns all on-chain wallet transactions, ordered from oldest to newest. Each entry includes the raw transaction, its fee (when known), the wallet's net balance change, and confirmation status. The fee is `null` for inbound or collaboratively-funded transactions whose foreign prevouts BDK has not indexed. # List on-chain UTXOs Source: https://second.tech/docs/barkd/api-reference/onchain/list-on-chain-utxos https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json get /api/v1/onchain/utxos Returns all UTXOs in the on-chain wallet. Each entry includes the outpoint, amount, and confirmation height (if confirmed). # Send on-chain payment Source: https://second.tech/docs/barkd/api-reference/onchain/send-on-chain-payment https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json post /api/v1/onchain/send Sends the specified amount to an on-chain address. Broadcasts the transaction immediately at a fee rate targeting confirmation within three blocks and returns the transaction ID. # Send to multiple addresses Source: https://second.tech/docs/barkd/api-reference/onchain/send-to-multiple-addresses https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json post /api/v1/onchain/send-many Batches multiple payments into a single on-chain transaction. Each destination is formatted as `address:amount`. Broadcasts the transaction immediately at a fee rate targeting confirmation within three blocks and returns the transaction ID. # Sync on-chain wallet Source: https://second.tech/docs/barkd/api-reference/onchain/sync-on-chain-wallet https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json post /api/v1/onchain/sync Syncs the on-chain wallet state with the chain source. Fetches new blocks and transactions, updates the UTXO set, and re-submits any stale unconfirmed transactions to the mempool. # Build a BIP 321 payment URI Source: https://second.tech/docs/barkd/api-reference/wallet/build-a-bip-321-payment-uri https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json post /api/v1/wallet/bip321 Builds a single BIP 321 `bitcoin:` URI bundling multiple ways to receive the same payment, so one call prepares everything needed for an incoming payment. A fresh Ark address is always included. When `amount_sat` is given, a BOLT11 invoice for that amount is generated and the amount is embedded in the URI. When `onchain` is `true`, a fresh on-chain address is added (placed in the URI body on mainnet, as a `tb=` parameter on test networks). Set the `uppercase` query parameter to upper-case the `bip321` URI so QR encoders can use the compact alphanumeric mode; this fails if the URI carries case-sensitive data. The individual `ark`, `bolt11`, and `onchain` destinations are always returned in their natural case for direct use. # Check server connection Source: https://second.tech/docs/barkd/api-reference/wallet/check-server-connection https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json get /api/v1/wallet/connected Checks whether the wallet has an active connection to the Ark server. Returns `true` if the wallet can reach the server and retrieve its configuration, `false` otherwise. The background daemon checks the server connection every second, so this reflects the most recent known state. # Create a wallet Source: https://second.tech/docs/barkd/api-reference/wallet/create-a-wallet https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json post /api/v1/wallet/create Creates a new wallet with the specified Ark server and chain source configuration. Fails if a wallet already exists. Returns the wallet fingerprint on success. # Delete the wallet Source: https://second.tech/docs/barkd/api-reference/wallet/delete-the-wallet https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json delete /api/v1/wallet Stops the wallet and removes every wallet file from the datadir; barkd's own files survive. Requires `dangerous: true` and, while a wallet is loaded, the wallet's fingerprint. With no wallet loaded, the call still removes any leftover wallet files. A retry completes an interrupted deletion. # Generate Ark address Source: https://second.tech/docs/barkd/api-reference/wallet/generate-ark-address https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json post /api/v1/wallet/addresses/next Generates a new Ark receiving address. Each call returns the next unused address from the wallet's HD keychain. # Get apiv1wallet Source: https://second.tech/docs/barkd/api-reference/wallet/get-apiv1wallet https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json get /api/v1/wallet # Get Ark address by index Source: https://second.tech/docs/barkd/api-reference/wallet/get-ark-address-by-index https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json get /api/v1/wallet/addresses/index/{index} Returns a previously generated Ark address by its derivation index. Only addresses that have already been generated are available. # Get Ark server info Source: https://second.tech/docs/barkd/api-reference/wallet/get-ark-server-info https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json get /api/v1/wallet/ark-info Returns the Ark server's configuration parameters, including network, public key, round interval, VTXO expiry and exit deltas, fee settings, and Lightning support details. # Get encoded VTXO Source: https://second.tech/docs/barkd/api-reference/wallet/get-encoded-vtxo https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json get /api/v1/wallet/vtxos/{id}/encoded Returns the hex-encoded serialization of a VTXO. The `encoded` field can be passed to `POST /wallet/import-vtxo` to re-import this VTXO. # Get next round time Source: https://second.tech/docs/barkd/api-reference/wallet/get-next-round-time https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json get /api/v1/wallet/next-round Queries the Ark server for the next scheduled round start time and returns it in RFC 3339 format. # Get VTXO detail Source: https://second.tech/docs/barkd/api-reference/wallet/get-vtxo-detail https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json get /api/v1/wallet/vtxos/{id} Returns detail for a single VTXO. To get the hex-encoded serialization use `GET /vtxos/{id}/encoded`. # Get wallet balance Source: https://second.tech/docs/barkd/api-reference/wallet/get-wallet-balance https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json get /api/v1/wallet/balance Returns the wallet balance broken down by category: spendable sats available for immediate use, sats pending in an Ark round, sats locked in outgoing or incoming Lightning payments, sats awaiting board confirmation, and sats in a pending exit. The balance is computed from local state, which the background daemon keeps reasonably fresh (Lightning syncs every second, mailbox and boards every 30 seconds). For the most up-to-date figures, call `sync` before this endpoint. # Get wallet debug info Source: https://second.tech/docs/barkd/api-reference/wallet/get-wallet-debug-info https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json get /api/v1/wallet/debug-info Returns wallet information that helps to debug issues: the bitcoin network, the ID of the wallet's server mailbox and the xpub from which all VTXO keypairs are derived. # Get wallet history (deprecated) Source: https://second.tech/docs/barkd/api-reference/wallet/get-wallet-history-deprecated https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json get /api/v1/wallet/history Deprecated: use `GET /api/v1/history` instead. # Get wallet mnemonic Source: https://second.tech/docs/barkd/api-reference/wallet/get-wallet-mnemonic https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json get /api/v1/wallet/mnemonic Returns the BIP-39 mnemonic phrase backing the wallet. Returns 404 when mnemonic exposure is disabled. Exposure is off by default; the endpoint returns 404 unless barkd is started with the `--expose-mnemonic` flag. # Import a VTXO Source: https://second.tech/docs/barkd/api-reference/wallet/import-a-vtxo https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json post /api/v1/wallet/import-vtxo Imports the hex-encoded serialized VTXOs in the request body into the wallet; it does not read them from the server mailbox. Validates that each VTXO is anchored on-chain and owned by this wallet. Useful for restoring VTXOs after database loss, or for re-importing ones obtained elsewhere. Ownership is resolved by scanning the seed-derived key space, bounded by `gap_limit` or the wallet's configured gap limit; a key the scan does not reach is a 400. Only VTXOs the server reports as spendable or spent are stored, in that state, so one that has already been spent is recorded as spent rather than rejected. A VTXO still in flight (unclaimed, unregistered, or awaiting a preimage) is rejected with a 422, because it becomes importable once that flow finishes. Pass `skip_status_check` to store them as spendable without asking the server. Expiry is not checked. The VTXOs are imported together, in one key scan and one transaction, so a rejected VTXO leaves none of them stored; pass `allow_partial` to keep the VTXOs that did import, and the response then lists only those. Already-imported VTXOs are skipped, so the operation is idempotent and a failed request can be retried. # List movements (deprecated) Source: https://second.tech/docs/barkd/api-reference/wallet/list-movements-deprecated https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json get /api/v1/wallet/movements Deprecated: Use history instead # List round participations Source: https://second.tech/docs/barkd/api-reference/wallet/list-round-participations https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json get /api/v1/wallet/rounds Returns all active round participations and their current status. A round participation is created when you call one of the `refresh` endpoints and persists until the round's funding transaction is confirmed on-chain (2 confirmations on mainnet, 1 on testnet). The list can contain multiple entries—for example, a previous round awaiting on-chain confirmation alongside a newly submitted round waiting for the next server round to start. Confirmed and failed rounds are removed automatically by the background daemon. # List VTXOs Source: https://second.tech/docs/barkd/api-reference/wallet/list-vtxos https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json get /api/v1/wallet/vtxos Returns VTXOs held by the wallet, including their state and expiry information. By default returns only non-spent VTXOs. Set `all=true` to include all VTXOs regardless of state. # Offboard all VTXOs Source: https://second.tech/docs/barkd/api-reference/wallet/offboard-all-vtxos https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json post /api/v1/wallet/offboard/all Cooperatively moves all spendable VTXOs off the Ark protocol to an on-chain address. Each VTXO is offboarded in full—partial amounts are not supported. The on-chain transaction fee is deducted from the total, and the remaining amount is sent to the destination. If no address is specified, the wallet generates a new on-chain address. To send a specific amount on-chain, use `send-onchain` instead. # Offboard specific VTXOs Source: https://second.tech/docs/barkd/api-reference/wallet/offboard-specific-vtxos https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json post /api/v1/wallet/offboard/vtxos Cooperatively moves the specified VTXOs off the Ark protocol to an on-chain address. Each VTXO is offboarded in full—partial amounts are not supported. The on-chain transaction fee is deducted from the total, and the remaining amount is sent to the destination. If no address is specified, the wallet generates a new on-chain address. To send a specific amount on-chain, use `send-onchain` instead. # Refresh all VTXOs Source: https://second.tech/docs/barkd/api-reference/wallet/refresh-all-vtxos https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json post /api/v1/wallet/refresh/all Registers all spendable VTXOs for refresh in the next Ark round. The input VTXOs are locked immediately and will be forfeited once the round completes, yielding new VTXOs with a fresh expiry. The background daemon automatically participates in the round and progresses it to completion. Use the `rounds` endpoint to track progress. # Refresh received VTXOs Source: https://second.tech/docs/barkd/api-reference/wallet/refresh-received-vtxos https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json post /api/v1/wallet/refresh/counterparty Registers all out-of-round VTXOs held by the wallet for refresh in the next Ark round. Refreshing replaces out-of-round VTXOs under arkoor trust assumptions with trustless, in-round VTXOs. Out-of-round VTXOs whose entire transaction chain originates from your own in-round VTXOs are excluded. The background daemon automatically participates in the round and progresses it to completion. Use the `rounds` endpoint to track progress. # Refresh specific VTXOs Source: https://second.tech/docs/barkd/api-reference/wallet/refresh-specific-vtxos https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json post /api/v1/wallet/refresh/vtxos Registers the specified VTXOs for refresh in the next Ark round. The input VTXOs are locked immediately and will be forfeited once the round completes, yielding new VTXOs with a fresh expiry. The background daemon automatically participates in the round and progresses it to completion. Use the `rounds` endpoint to track progress. # Refresh VTXOs in delegated mode Source: https://second.tech/docs/barkd/api-reference/wallet/refresh-vtxos-in-delegated-mode https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json post /api/v1/wallet/refresh/delegated/vtxos Registers the specified VTXOs for refresh as a delegated participation: the wallet hands the server a signed participation and the server carries it through the round, so the wallet doesn't need to follow the round interactively. The input VTXOs are locked immediately and will be forfeited once the round completes, yielding new VTXOs with a fresh expiry. Set `height` to schedule the refresh for a future block height: the refresh fee is priced at that height and the server includes the participation in the first round once the chain tip reaches it. When `height` is omitted, the participation is eligible for the next round. Use the `rounds` endpoint to track progress. # Send a payment Source: https://second.tech/docs/barkd/api-reference/wallet/send-a-payment https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json post /api/v1/wallet/send Sends a payment to the specified destination. Accepts an Ark address, BOLT11 invoice, BOLT12 offer, Lightning address, LNURL, bitcoin address, or BIP 321 URI. When the destination offers several payment methods, `method` picks the kind to pay with; without it the wallet picks Ark, then Lightning, then on-chain. Ark address payments are settled instantly via an out-of-round (arkoor) transaction. The `amount_sat` field is required unless the destination carries an amount. Comments are only supported for Lightning addresses and LNURL. # Send on-chain from Ark balance Source: https://second.tech/docs/barkd/api-reference/wallet/send-on-chain-from-ark-balance https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json post /api/v1/wallet/send-onchain Sends the specified amount to an on-chain address using the wallet's off-chain Ark balance. The on-chain transaction fee is paid on top of the specified amount. Internally creates an out-of-round transaction to consolidate VTXOs into the exact amount needed, then cooperatively sends the on-chain payment via the Ark server. To offboard entire VTXOs without specifying an amount, use `offboard/vtxos` or `offboard/all` instead. # Sync mailbox only Source: https://second.tech/docs/barkd/api-reference/wallet/sync-mailbox-only https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json post /api/v1/wallet/sync/mailbox Triggers an immediate mailbox sync without running any of the other off-chain sync steps. Fetches any pending mailbox messages from the Ark server, processes them (incoming arkoor payments, lightning receive notifications), and returns the new mailbox checkpoint (tip). Useful in `daemon_manual_sync` mode where background mailbox subscription is disabled and the operator needs a granular way to pull incoming events. # Sync wallet Source: https://second.tech/docs/barkd/api-reference/wallet/sync-wallet https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json post /api/v1/wallet/sync Triggers an immediate sync of the wallet's off-chain state. Updates on-chain fee rates, processes incoming arkoor payments, resolves outgoing and incoming Lightning payments, and progresses pending rounds and boards toward confirmation. The background daemon already runs these operations automatically (e.g., Lightning every second, mailbox and boards every 30 seconds), but calling `sync` forces all of them to run immediately. # Authenticate Source: https://second.tech/docs/barkd/authenticate How Barkd generates an auth token and how to retrieve or rotate it with `barkd secret show` and `barkd secret refresh`. All REST calls to `barkd` must include a bearer token. `barkd` generates one automatically on first start and stores it in the data directory. **1. Show the token** Print the current bearer token: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} barkd --datadir secret show ``` **2. Rotate the token** To rotate the token, run: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} barkd --datadir secret refresh ``` You can also supply your own secret instead of letting `barkd` generate one. Pass it as 64 hex characters (32 bytes), and `barkd` derives the bearer token from it: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} barkd --datadir secret refresh --secret <64-hex-character-secret> ``` Both commands print the new token. Restart `barkd` for the new token to take effect. ## Next steps With the daemon running and a token in hand, you can start driving `barkd` over its REST API. > **[REST API](/docs/barkd/api-reference/wallet/create-a-wallet)** > > Full reference for every `barkd` REST endpoint. # Clients Source: https://second.tech/docs/barkd/clients Typed TypeScript, C#, and Python clients that wrap the Barkd REST API, generated from its OpenAPI spec. The packages let you call the `barkd` REST API from typed code without writing raw HTTP. They are generated from the [OpenAPI spec](/docs/barkd/api-reference/wallet/create-a-wallet) and live in the [barkd-clients repository](https://gitlab.com/ark-bitcoin/barkd-clients). Each client needs the bearer token from [Authenticate](/docs/barkd/authenticate) in its configuration. > [!TIP] > > These examples create a **signet** wallet for free testing. To go live, set `arkServer` and the Esplora `chainSource` to Second's mainnet endpoints from [Connection details](/docs/connection-details), and set the network to `mainnet`. **TypeScript** ### Prerequisites * Node.js ### Install ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} npm install @secondts/barkd ``` ### Usage ```typescript theme={"theme":{"light":"github-light","dark":"github-dark"}} import { Configuration, WalletApi } from '@secondts/barkd' const config = new Configuration({ basePath: 'http://localhost:3000', accessToken: 'your bearer token' }) const walletApi = new WalletApi(config) // Create wallet await walletApi.createWallet({ createWalletRequest: { arkServer: 'https://ark.signet.2nd.dev', chainSource: { esplora: { url: 'https://esplora.signet.2nd.dev' } }, network: 'signet', mnemonic: 'your seed phrase' } }) // Get address const { address } = await walletApi.address() // Get balance const balance = await walletApi.balance() ``` **C#** ### Prerequisites * .NET SDK ### Install ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} dotnet add package Second.Barkd ``` ### Usage ```csharp theme={"theme":{"light":"github-light","dark":"github-dark"}} using System; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Second.Barkd.Api; using Second.Barkd.Client; using Second.Barkd.Extensions; using Second.Barkd.Model; var host = Host.CreateDefaultBuilder(args) .ConfigureApi((context, services, options) => { options.AddTokens(new BearerToken("your bearer token")); options.AddApiHttpClients(client => client.BaseAddress = new Uri("http://localhost:3000")); }) .Build(); var walletApi = host.Services.GetRequiredService(); // Create wallet await walletApi.CreateWalletAsync(new CreateWalletRequest( arkServer: "https://ark.signet.2nd.dev", chainSource: new ChainSourceConfig( new ChainSourceConfigOneOf1( new ChainSourceConfigOneOf1Esplora("https://esplora.signet.2nd.dev") ) ), network: BarkNetwork.Signet, mnemonic: "your seed phrase" )); // Get address var address = (await walletApi.AddressAsync()).Ok(); // Get balance var balance = (await walletApi.BalanceAsync()).Ok(); ``` **Python** ### Prerequisites * Python 3.9+ ### Install ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} pip install barkd-client ``` ### Usage ```python theme={"theme":{"light":"github-light","dark":"github-dark"}} import barkd_client from barkd_client import ( Configuration, WalletApi, CreateWalletRequest, ChainSourceConfig, ChainSourceConfigOneOf1, ChainSourceConfigOneOf1Esplora, BarkNetwork, ) config = Configuration(host='http://localhost:3000', access_token='your bearer token') with barkd_client.ApiClient(config) as api_client: wallet_api = WalletApi(api_client) # Create wallet wallet_api.create_wallet(CreateWalletRequest( ark_server='https://ark.signet.2nd.dev', chain_source=ChainSourceConfig(actual_instance=ChainSourceConfigOneOf1( esplora=ChainSourceConfigOneOf1Esplora(url='https://esplora.signet.2nd.dev') )), network=BarkNetwork.SIGNET, mnemonic='your seed phrase', )) # Get address address = wallet_api.address().address # Get balance balance = wallet_api.balance() ``` > [!NOTE] > > Need a client for another language? Generate one yourself from the [OpenAPI spec](https://gitlab.com/ark-bitcoin/bark/-/raw/master/bark-rest/openapi.json) using [openapi-generator](https://openapi-generator.tech). # Barkd Source: https://second.tech/docs/barkd/index Barkd is Second's reference Bark wallet daemon. Run it on your server and drive it from any language via a local REST API. Barkd runs as a daemon alongside your other services and exposes a local REST API, so any backend in your stack can send and receive bitcoin over Ark, Lightning, and on-chain. Barkd is the right fit when you run infrastructure and need to manage bitcoin server-side: * Self-hosted node platforms (Umbrel, Start9, RaspiBlitz, etc.) * Webshops and e-commerce platforms accepting payments * Exchanges managing user deposits and withdrawals * Payment processors settling merchant payments * Backend services automating payouts, subscriptions, or reconciliation > [!TIP] > > If you're building bitcoin apps for mobile or desktop, [try the Bark SDK](/docs/bark-sdk). ## Get started > **[Install](/docs/barkd/install)** > > Download binaries or compile `barkd` from source. > **[Start the daemon](/docs/barkd/start)** > > Run `barkd` with the right data directory, bind address, and CORS settings. > **[Authenticate](/docs/barkd/authenticate)** > > Retrieve and rotate the bearer token `barkd` uses to authorize REST calls. > **[REST API](/docs/barkd/api-reference/wallet/create-a-wallet)** > > Full reference for every `barkd` REST endpoint. > **[Clients](/docs/barkd/clients)** > > Typed TypeScript and C# packages that wrap the REST API. # Install Barkd Source: https://second.tech/docs/barkd/install Install Barkd on Linux, macOS, or Windows. Download a pre-built binary from GitLab releases or compile from source. Barkd has two installation methods: * Download and install the binary release * [Compile from source](#compile-from-source) ## Binary release Pre-built `barkd` binaries are published on [GitLab releases](https://gitlab.com/ark-bitcoin/bark/-/releases). Pick the archive for your platform and drop the binary into your `PATH`. **Ubuntu/Debian** **1. Download barkd** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} curl -L https://gitlab.com/ark-bitcoin/bark/-/releases/bark-0.8.0/downloads/barkd-0.8.0-linux-x86_64 --output barkd ``` **2. Mark the binary as executable** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} chmod +x barkd ``` **3. Add barkd to your PATH** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} sudo cp barkd /usr/local/bin/ ``` **Fedora/CentOS** **1. Download barkd** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} curl -L https://gitlab.com/ark-bitcoin/bark/-/releases/bark-0.8.0/downloads/barkd-0.8.0-linux-x86_64 --output barkd ``` **2. Mark the binary as executable** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} chmod +x barkd ``` **3. Add barkd to your PATH** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} sudo cp barkd /usr/local/bin/ ``` **macOS** **1. Download barkd** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} curl -L https://gitlab.com/ark-bitcoin/bark/-/releases/bark-0.8.0/downloads/barkd-0.8.0-apple-aarch64 --output barkd ``` **2. Mark the binary as executable** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} chmod +x barkd ``` **3. Add barkd to your PATH** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} sudo cp barkd /usr/local/bin/ ``` **macOS (Intel)** **1. Download barkd** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} curl -L https://gitlab.com/ark-bitcoin/bark/-/releases/bark-0.8.0/downloads/barkd-0.8.0-apple-x86_64 --output barkd ``` **2. Mark the binary as executable** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} chmod +x barkd ``` **3. Add barkd to your PATH** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} sudo cp barkd /usr/local/bin/ ``` **Windows** Download barkd: ```PowerShell theme={"theme":{"light":"github-light","dark":"github-dark"}} wget https://gitlab.com/ark-bitcoin/bark/-/releases/bark-0.8.0/downloads/barkd-0.8.0-windows-x86_64.exe -OutFile barkd.exe ``` > [!NOTE] > > When using Windows, replace `barkd` with `barkd.exe` in the rest of the commands. ## Verify installation ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} barkd --version ``` You should see: `barkd 0.8.0 ()` ## Compile from source **1. Clone the repository** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} git clone https://gitlab.com/ark-bitcoin/bark cd bark ``` **2. Install Rust** You need a Rust compiler. The [rustup website](https://rustup.rs) offers installation instructions for almost any platform. **3. Install build dependencies** Download additional dependencies using your package manager. **Ubuntu/Debian** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} apt update apt install build-essential clang protobuf-compiler ``` **Fedora/CentOS** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} yum install gcc make clang protobuf-compiler ``` **macOS** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} brew install gcc make llvm@14 protobuf ``` **Windows** ```PowerShell theme={"theme":{"light":"github-light","dark":"github-dark"}} winget install protobuf ezwinports.make LLVM.LLVM ``` **Nix** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} nix develop ``` Requires the `nix-command` and `flakes` experimental features. **4. Build barkd** Use `cargo build` to produce the binary in `target/`, or `cargo install` to build and add it to your `PATH` in one step. **build** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} cargo build --bin barkd ./target/debug/barkd --version ``` **build and install** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} cargo install --locked --path ./bark-cli --bin barkd barkd --version ``` **5. Verify installation** Run `barkd --version` to confirm the install completed successfully. # Start the daemon Source: https://second.tech/docs/barkd/start Start the Barkd daemon, point it at a data directory, set the bind address for its REST API, and list the CORS origins allowed to call it from a browser. Run `barkd` and point it at a data directory. On first start, it initializes the data directory and generates an [auth token](/docs/barkd/authenticate). ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} barkd --datadir ``` The API listens on `http://localhost:3000/api/v1` by default. A Swagger UI is served at `/swagger-ui` and the OpenAPI spec at `/api-docs/openapi.json`. ## Common flags * `--datadir ` — where `barkd` stores wallet data and its auth secret. Defaults to `~/.bark`. Also settable via `BARKD_DATADIR`. * `--host ` and `--port ` — bind address for the REST API. Also settable via `BARKD_BIND_HOST` and `BARKD_BIND_PORT`. * `--allowed-origins ` — comma-separated list of CORS origins allowed to call the API from a browser. Cross-origin requests are denied by default. Also settable via `BARKD_ALLOWED_ORIGINS`. > [!WARNING] > > `barkd` serves plain HTTP and binds to loopback by default. Every request carries the bearer token, and anyone with the token can control the wallet. To expose the API beyond loopback, put it behind a reverse proxy that terminates TLS. # Use your Bark wallet through the API Source: https://second.tech/docs/btcpay/api List your store's Bark wallet transactions and balance over BTCPay's Greenfield API, match them to BTCPay invoice payments, and use BTCPay's Lightning API with Bark. The plugin adds two read-only Greenfield API endpoints for your store's Bark wallet. One lists every transaction, including refreshes and exits. The other returns the balance. They work like BTCPay's on-chain wallet endpoints, with `BTC-ARK` as the payment method ID. Transactions also carry a few extra fields. Use them to connect to accounting tools and match Bark transactions to BTCPay invoice payments. The endpoints appear in your server's API documentation, at `/docs` on your BTCPay Server, under **Store Wallet (Ark)**. > [!NOTE] > > BTCPay's on-chain wallet endpoints don't list Bark's transactions. BTCPay's Lightning API lists only Lightning invoices and payments. For the wallet's full history, use `GET /api/v1/stores/{storeId}/payment-methods/BTC-ARK/wallet/transactions`. ## Create an API key Generate an API key with the **View wallets** permission (`btcpay.store.canviewwallet`) for the store, on your account's **API Keys** page in BTCPay. ## List the transactions ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} curl -H "Authorization: token $API_KEY" \ "https://btcpay.example.com/api/v1/stores/$STORE_ID/payment-methods/BTC-ARK/wallet/transactions?limit=50" ``` Transactions come newest first. A new transaction can take up to 15 seconds to appear. All parameters are optional: | Parameter | What it does | | - | - | | `statusFilter` | Only `Confirmed` or `Unconfirmed` transactions. Repeat the parameter to pass both. | | `labelFilter` | Only transactions carrying this label, such as `invoice` for the ones that paid an invoice. If you also pass `statusFilter`, the filters combine with OR: the response includes each transaction that matches either filter, once. | | `skip` | How many transactions to skip, after filtering. | | `limit` | The maximum number of transactions to return. All of them by default. | Each transaction looks like this one, an Ark payment to an invoice: ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "id": "1-639275347581234567:eac17c4b3d1f45d2b70f3bccfb3da992ef8d82b803aafa6482d61d27a2631373:0", "kind": "ark-receive", "movementId": 1, "outpoint": "eac17c4b3d1f45d2b70f3bccfb3da992ef8d82b803aafa6482d61d27a2631373:0", "paymentHash": null, "fee": "0", "transactionHash": "eac17c4b3d1f45d2b70f3bccfb3da992ef8d82b803aafa6482d61d27a2631373", "comment": "", "labels": { "invoice": { "ref": "4S6YW64waM9JoAfVHF97DX", "type": "invoice", "text": "invoice" } }, "amount": "0.0015", "blockHash": null, "blockHeight": null, "confirmations": 1, "timestamp": 1791937958, "status": "Confirmed" } ``` ## Read the fields | Field | What it contains | | - | - | | `id` | The transaction's ID, unique within the store. Treat it as an opaque string. See [Identify a transaction](#identify-a-transaction). | | `kind` | See [Transaction types](#transaction-types). | | `amount` | The transaction's net effect on the wallet's total balance, in BTC, after its `fee`: positive for bitcoin in, negative for bitcoin out. Over the wallet's full history, the amounts add up to its total balance. | | `fee` | What the wallet paid for the transaction, in BTC, already included in `amount`. Zero when the transaction cost nothing. Null on `onchain-receive` transactions, where the sender paid the fee, and when the plugin can't tell what the fee was. | | `status` | `Confirmed` once the transaction's amount can no longer change, `Unconfirmed` before that. An `Unconfirmed` transaction can still change its amount, gain its `transactionHash`, or disappear (a failed refresh, for example). | | `confirmations` | `1` once the transaction is confirmed, `0` before. Boards, offboards to the Bark on-chain wallet, and that wallet's own on-chain transactions report their block confirmations instead. | | `timestamp` | When Bark created the payment or operation. For transactions of the Bark on-chain wallet, when the plugin first saw them, or a time estimated from the block height if they were already confirmed. | | `transactionHash` | The ID of the underlying on-chain or Ark transaction, if there is one. See [Transaction types](#transaction-types). Several transactions in the response can share one. | | `outpoint` | On `ark-receive` transactions, the received VTXO, as `txid:vout`. Null on the rare `ark-receive` transaction that covers several VTXOs because the plugin couldn't split it. | | `paymentHash` | On Lightning transactions, the payment hash. | | `movementId` | The Bark wallet's own number for the payment or operation. Transactions share a number when a payment arrived as several VTXOs, and an exit's `exit-fee` and `exit-claim` transactions carry the `exit` transaction's number. Null on transactions of the Bark on-chain wallet that belong to no Bark payment. Numbers start over at 1 if the wallet is re-created or restored, so use `id`, not `movementId`, to identify a transaction. | | `labels` | The transaction's labels, as on BTCPay's on-chain wallet transactions. The `invoice` label's `ref` is the ID of the BTCPay invoice that the transaction paid. [Store labels](/docs/btcpay/dashboard#label-your-transactions) that you attach on the Bark Receive and Send screens appear as `raw` labels. | | `blockHash`, `blockHeight` | The block that confirmed the transaction. Set only on boards, offboards to the Bark on-chain wallet, and that wallet's own on-chain transactions. | Failed or canceled payments, sent or received, are listed only when they still moved bitcoin, with their real amount. Their `status` doesn't show that they failed or were canceled. The [Bark wallet page](/docs/btcpay/dashboard#transactions) lists every failed or canceled payment. ### Transaction types Each type is a value of the `kind` field. The Type column of the [Bark Wallet report](/docs/btcpay/reporting) shows the same types under display names. | `kind` | Report Type | What it is | `transactionHash` | | - | - | - | - | | `ark-receive` | Ark Receive | A payment to your off-chain balance over Ark, as one VTXO (rarely several) | The received VTXO's [exit transaction](/docs/learn/exit#the-emergency-exit-process), which stays off-chain unless the VTXO is exited | | `ark-send` | Ark Send | A payment from your off-chain balance over Ark | None | | `lightning-receive` | Lightning Receive | A payment to your off-chain balance over Lightning | None | | `lightning-send` | Lightning Send | A payment from your off-chain balance over Lightning | None | | `refresh` | Refresh | [VTXOs renewed](/docs/btcpay/vtxos) in a round, within your off-chain balance | The on-chain round transaction, once Bark knows it | | `board` | Board | Bitcoin moved from the Bark on-chain wallet to your off-chain balance | The on-chain board transaction | | `offboard` | Offboard | VTXOs moved from your off-chain balance to an on-chain address, with the fee taken from them | The on-chain transaction that pays the address, once Bark knows it | | `send-onchain` | Send On-chain | A payment from your off-chain balance to an on-chain address, with the fee on top | The on-chain transaction that pays the address, once Bark knows it | | `exit` | Exit | One VTXO moved from your off-chain balance to the blockchain without the Ark server, in an [emergency exit](/docs/btcpay/settings#danger-zone) | The VTXO's final [exit transaction](/docs/learn/exit#the-emergency-exit-process), broadcast before the claim | | `exit-fee` | Exit Fee | A child-pays-for-parent (CPFP) payment from the Bark on-chain wallet for the fee of one of an exit's transactions. An exit typically has several. | The on-chain CPFP transaction | | `exit-claim` | Exit Claim | Exited bitcoin moved to the Bark on-chain wallet or another address, once the exit's timelock ends | The on-chain claim transaction | | `onchain-receive` | On-chain Receive | A payment to the Bark on-chain wallet from an on-chain address | The on-chain transaction that pays the Bark on-chain wallet | | `onchain-send` | On-chain Send | A payment from the Bark on-chain wallet to an on-chain address | The on-chain transaction that pays the address | | `onchain-internal` | On-chain Internal | Bitcoin moved within the Bark wallet in an on-chain transaction, such as part of a board, offboard, or exit | The on-chain transaction | | `unknown` | The barkd subsystem name and kind, such as `bark.foo (bar)` | A transaction this plugin version doesn't recognize | None | > [!TIP] > > Later plugin versions may add new `kind` values. Write your code so that a value missing from this table doesn't break it. ## Identify a transaction Use `id` to store transactions in your own system and to recognize the ones you've already seen. It's unique within the store, including when a wallet is re-created and Bark numbers its payments from 1 again. Store a transaction only once it's `Confirmed`. After that, its `id` and amount stay the same. Only its labels and confirmations can still change. > [!NOTE] > > If you [restore the wallet from its recovery phrase](/docs/btcpay/backups#restore-a-wallet-from-its-recovery-phrase), Bark doesn't bring back its transaction history. Ark and Lightning transactions from before the restore drop out of the list. The bitcoin that the restore recovers appears in no transaction, so `balance` leaves it out. Some transactions can come back with a different `id`. Match those to the ones you stored by `outpoint` or `transactionHash`. > > If you re-created or restored the wallet before plugin 0.11.0, store labels from before then can still show on unrelated transactions. ## Match transactions to invoice payments BTCPay gives each payment on an invoice a payment ID. Match it to transactions as follows: * **Ark payments:** BTCPay records one payment per received VTXO, with the ID `txid-vout`. Replace the hyphen with a colon and match the result to `outpoint`. The amounts are equal. Don't match on `transactionHash`, which several transactions can share. * **Lightning payments:** The payment ID is the payment hash, so match it to `paymentHash`. BTCPay's payment amount is what the customer paid, which is the transaction's `amount` plus its `fee`. Some Ark payments have a payment ID that covers several transactions: * `{invoiceId}#ark-movement-{movementId}-{index}`: Ark payments to invoices created before plugin 0.10.0, and the rare payment that the plugin can't split by VTXO. * `{invoiceId}#ark-movement-{movementId}`: Ark payments recorded by plugin 0.7.0 or earlier. Match these to the transactions with that `movementId` whose `invoice` label `ref` is the invoice ID. Their amounts add up to the payment. If one movement paid several invoices, its transactions carry no `invoice` label. ## Get the wallet balance ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} curl -H "Authorization: token $API_KEY" \ "https://btcpay.example.com/api/v1/stores/$STORE_ID/payment-methods/BTC-ARK/wallet" ``` ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "balance": "0.0015", "unconfirmedBalance": "-0.0000062", "confirmedBalance": "0.0015062", "label": "" } ``` The endpoint needs the same **View wallets** permission. Its response has the shape of BTCPay's on-chain wallet overview, with four fields: * `balance` is the sum of every transaction's `amount`, in BTC, across your off-chain balance and the Bark on-chain wallet. It leaves out the bitcoin that a restore from the recovery phrase brings back. * `confirmedBalance` adds up the `Confirmed` transactions, the part of the balance that can no longer change. * `unconfirmedBalance` adds up the `Unconfirmed` transactions. It's negative while more is pending out than in, for example a fee during a refresh. * `label` is always empty. The balance can be up to 15 seconds old. It differs from the balance on the Bark wallet page in four cases: * **Payment in progress:** While a Lightning send, an Ark send, an on-chain send, or an offboard is under way, the Bark wallet page still counts the bitcoin it spends as a pending sub-balance, including any change coming back. The endpoint counts the payment as sent as soon as Bark records it. * **Refresh waiting for its round:** The Bark wallet page counts the VTXOs going into the round, so it includes the refresh fee until the round confirms. The endpoint already counts the fee as paid. * **Unconfirmed exit claim:** The Bark wallet page counts the claimed bitcoin twice, as a pending exit and as pending on-chain bitcoin. The endpoint counts it once. * **After a restore from the recovery phrase:** The endpoint leaves out the bitcoin that the restore brought back. ## Use BTCPay's Lightning API When Bark runs your store's Lightning (see [Lightning settings](/docs/btcpay/settings#lightning-settings)), BTCPay's own Lightning API works with the Bark wallet. Its endpoints appear in the API documentation under **Lightning (Store)**. Four of them read and pay through Bark: | Endpoint | What it does | Permission | | - | - | - | | `GET /api/v1/stores/{storeId}/lightning/BTC/invoices` | Lists the wallet's Lightning invoices: paid ones, and unpaid ones Bark still waits on. Pass `pendingOnly=true` for unpaid ones only. | `btcpay.store.canviewlightninginvoice` | | `GET /api/v1/stores/{storeId}/lightning/BTC/payments` | Lists the Lightning payments the wallet made, completed ones only unless you pass `includePending=true`, which adds pending and failed ones. | `btcpay.store.canuselightningnode` | | `GET /api/v1/stores/{storeId}/lightning/BTC/payments/{paymentHash}` | Returns one payment the wallet made. | `btcpay.store.canuselightningnode` | | `POST /api/v1/stores/{storeId}/lightning/BTC/invoices/pay` | Pays a BOLT11 invoice from your off-chain balance. | `btcpay.store.canuselightningnode` | Both lists come oldest first, at most 100 items per call. `offsetIndex` skips that many items, counted after filtering, so to read the next page, add the number of items you received. An invoice expires when its BOLT11 does, and the Ark server sets that expiry, whatever expiry was requested. Once Bark cancels an unpaid invoice, it forgets it, so the invoice drops out of the list. To pay an invoice, send its BOLT11: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} curl -X POST -H "Authorization: token $API_KEY" -H "Content-Type: application/json" \ -d '{"BOLT11": "lnbc..."}' \ "https://btcpay.example.com/api/v1/stores/$STORE_ID/lightning/BTC/invoices/pay" ``` The request answers once the payment settles, with its fee and preimage, or fails. If the payment is still in flight after 30 seconds, or after the `sendTimeout` you pass in seconds (up to 10 minutes), the request answers `202 Accepted` with the status `Pending`. Check it later with `GET .../lightning/BTC/payments/{paymentHash}`: a payment that can't reach its recipient can take a few minutes to fail. Passing `sendTimeout` also sets how long the Ark server keeps trying to pay the invoice, so it limits how long such a payment takes to fail. Without it, the Ark server's own default applies. Paying an invoice the wallet already paid returns that payment rather than paying it again. > [!NOTE] > > Creating and reading single invoices and reading the Lightning balance work too. Node information, channels, and deposit addresses don't apply to Bark, so those endpoints answer `503`. ## Errors These are the errors of the two **Store Wallet (Ark)** endpoints. | Status | When | | - | - | | 401 | The request has no API key, or the key is invalid. | | 403 | The API key lacks the **View wallets** permission for the store. | | 404 | `paymentmethod-not-found`: Bark isn't set up for the store. | | 422 | A negative `skip` or `limit`, or an unknown status in `statusFilter`. | | 503 | `not-available`: the store's Bark wallet couldn't be reached, or didn't return everything the list needs. When the wallet answered only in part, the message names what's missing. | ## Payment method ID migration Bark's payment method ID is `BTC-ARK`, alongside BTCPay's own `BTC-CHAIN` and `BTC-LN`. Before plugin 0.10.0 it was `BARK`. Invoices created before the upgrade keep `BARK` and still settle, so a tool that reads payment method IDs from invoices, payments, or webhooks sees both. # Back up your wallet Source: https://second.tech/docs/btcpay/backups Back up your store's Bark wallet in BTCPay Server: write down the recovery phrase, set up continuous backups, and restore the wallet if its data is lost. Before accepting any payments, make sure you back up your store's wallet. 1. **[Write down the recovery phrase](#write-down-the-recovery-phrase):** This is enough to recover the wallet's balance in the event of a system failure. Recovery from the phrase alone requires the Ark server's cooperation, and it doesn't restore the payment history or the state of any in-progress exits. 2. **[Set up continuous backups](#set-up-continuous-backups)** (optional): A backup that you fully control, with the entire payment history included. The [Backups](/docs/backups) page explains the mechanics behind both in more depth. ## Write down the recovery phrase **1. Open the Bark settings** Go to **Bark** > **Settings**. **2. Reveal the phrase** Select **View Recovery Phrase** in the **Backup** section. **3. Write down the 12 words** Copy them in order, somewhere safe and offline. The phrase never changes, so this is a one-time step. Select **Done** to return to Settings. ## Set up continuous backups Each store's wallet lives in BTCPay Server's data directory, under `bark/stores/`, with its recovery phrase alongside. The **Backup** section of **Bark** > **Settings** shows the exact path, with a copy button. On a standard Docker deployment, that directory sits inside the BTCPay data volume on your server's disk. > [!WARNING] > > Your backups contain the wallet's keys. The recovery phrase is stored in plain text. Anyone who can read the wallet directory or its backups can spend the wallet's bitcoin, so restrict access to both. Second doesn't have a mature continuous backup solution for the Bark plugin yet. If you're comfortable experimenting, consider these options: * **[bark-backupd](https://gitlab.com/ark-bitcoin/labs/bark-backupd):** Second's experimental backup daemon. It watches a wallet directory and snapshots the database on every change. It encrypts each snapshot with a key derived from the recovery phrase, then ships it to a cloud drive or any S3-compatible target. Test `bark-backupd restore` before you rely on it. * **[Litestream](https://litestream.io/):** A streaming replicator that copies new changes in the wallet database to a replica you configure, such as an S3-compatible bucket, every second by default. The wallet database isn't formally tested in the WAL journal mode Litestream requires, so treat the approach as experimental. Regular [BTCPay backups](https://docs.btcpayserver.org/Docker/backup-restore/) are a baseline whole-server backup, but they typically aren't frequent enough for a reliable Bark wallet backup. > [!WARNING] > > If a backup misses your latest wallet changes, recovering the whole balance will require restoring from the recovery phrase, which relies on the Ark server's cooperation. ## Restore a wallet from its recovery phrase To bring a wallet back on a store that has no Bark wallet yet, select **Import existing wallet** on the **Set up Bark** screen and enter the 12 words in the **Seed phrase** field. [Set up a Bark wallet for your store](/docs/btcpay/install#set-up-a-bark-wallet-for-your-store) walks through that screen. The plugin rebuilds the wallet with the Ark server's help, and the balance appears once the wallet has synced. ![Screenshot of the Set up Bark screen with Import existing wallet selected and the 12 numbered word fields under Seed phrase](https://mintcdn.com/second-0659a37d/oyMVF3OPOvsi31EU/images/btcpay/setup-bark-import.png?fit=max\&auto=format\&n=oyMVF3OPOvsi31EU\&q=85\&s=6681cd58d092cb4dfd649ac67fe8d8d4) Import existing wallet turns the Set up Bark screen into a 12-word entry form ## Restore a wallet whose data is lost A store's wallet directory can go missing, for example after a disk failure, a lost Docker volume, or a server restore that left it out. The plugin then doesn't create a new wallet in its place. It pauses the store's Ark payments, and its Lightning payments if Bark runs the store's Lightning. On-chain payments to your native BTCPay wallet carry on. BTCPay notifies the store's users. The same happens when the directory holds another wallet's data, for example one copied over from a different store. > [!WARNING] > > While the wallet is paused, the plugin doesn't refresh VTXOs or send expiry alerts. Your VTXOs still move toward expiry, so restore the wallet as soon as you can. Restoring needs a store role that can modify the store's settings, such as Owner. If your server doesn't let non-admins create hot wallets, a server admin with that role on the store has to restore the wallet. If you have a [continuous backup](#set-up-continuous-backups) of the wallet directory, restore it to `bark/stores/` in BTCPay Server's data directory. The backup has to include both `db.sqlite` and the `mnemonic` file. Then select **Bark** in your store's sidebar. Otherwise, bring the wallet back from its recovery phrase: **1. Open the restore page** Select **Restore wallet** in the warning on **Bark** > **Settings**, or select the notification. **2. Enter the recovery phrase** Enter the wallet's 12 words and select **Restore wallet**. The page accepts only the phrase of this store's wallet. If the directory held another wallet's data, the plugin moves it to `bark/replaced` in BTCPay Server's data directory rather than deleting it. Ark and Lightning payments resume. The balance appears once the wallet has synced with the Ark server. If you've lost the recovery phrase too, a server admin with that role on the store can replace its wallet on the same page. > [!WARNING] > > Without its recovery phrase, nobody can recover the old wallet's bitcoin. **1. Enter the store's name** Under **Replace the wallet**, enter the store's name to confirm. **2. Enter another wallet's phrase, if you have one** Leave the phrase fields empty to create a new wallet instead. **3. Replace the wallet** Select **Replace wallet**. With empty phrase fields, the plugin then shows the new wallet's recovery phrase. Write it down. > [!NOTE] > > The plugin recognizes a store's wallet by its fingerprint, which it records when the wallet starts. For a store set up before plugin 0.11.0, it records the fingerprint on the wallet's first start after the upgrade. A store whose wallet directory was already missing at the upgrade gets a new wallet one last time. # Understand your balances Source: https://second.tech/docs/btcpay/dashboard Read the Bark wallet page in BTCPay Server: the main balance and its breakdown, the balance chart, the transactions list, and the store Dashboard widgets. Select **Bark** in your store's sidebar to open the wallet page. ![Screenshot of the Bark wallet page in BTCPay Server, with the main balance, its sub-balances, the balance chart, and a list of transactions](https://mintcdn.com/second-0659a37d/oyMVF3OPOvsi31EU/images/btcpay/dashboard.png?fit=max\&auto=format\&n=oyMVF3OPOvsi31EU\&q=85\&s=227b3d399292c52d7c7c38a6e0109250) The main balance totals its sub-balances, and the transactions list mixes checkout payments with your own sends and receives ## One main balance, several sub-balances The headline figure totals every sub-balance, with its fiat value in your store's default currency beneath. While all you hold is spendable off-chain bitcoin, the headline stands alone. As soon as you hold anything else, a breakdown appears under it, showing only the non-zero rows: | Sub-balance | What it holds | | - | - | | Off-chain | Bitcoin held in [VTXOs](/docs/learn/vtxo), ready to spend. This is where Lightning and Ark checkout payments arrive. | | Needs refresh | Bitcoin in VTXOs that have [expired](/docs/learn/lifetime#what-happens-when-vtxos-expire) or reached the Ark server's limit on how long their exit path can grow. It can't go into an Ark payment until it's refreshed. The refresh happens automatically in the next round. | | On-chain | Confirmed bitcoin in the Bark on-chain wallet. | | Pending on-chain | An incoming on-chain payment to the Bark on-chain wallet, awaiting confirmation. | | Pending change | Change from emergency exit fee transactions, awaiting confirmation. | | Pending board | An on-chain deposit [boarding onto Ark](/docs/learn/board). | | Pending in round | Bitcoin going into a [refresh](/docs/btcpay/vtxos) whose round hasn't confirmed yet. It counts the full amount going in, so it includes the refresh fee until the round confirms. | | Pending Ark send | An outgoing Ark payment that hasn't completed yet, including any change coming back to you. | | Pending Lightning send | An outgoing Lightning payment that hasn't settled yet. | | Pending offboard | An [offboard](/docs/learn/offboard), or a send to an on-chain address from your off-chain balance, whose transaction hasn't been broadcast yet. It includes any change coming back to you. | | Pending exit | Bitcoin pending the completion of an [emergency exit](/docs/btcpay/settings#danger-zone). | ## The Bark on-chain balance is a separate wallet The on-chain sub-balance is not your store's regular BTCPay wallet. BTCPay Server and the Bark plugin use two separate on-chain wallets: 1. **Native BTCPay wallet:** Receives on-chain checkout payments. The plugin never spends from it. 2. **Bark on-chain wallet:** Holds the reserve that pays the on-chain fees of an emergency exit. It also receives the bitcoin delivered by [exits](/docs/learn/exit) and by [offboards](/docs/learn/offboard). More on [managing your Bark on-chain wallet](/docs/btcpay/send-receive#fund-and-withdraw-the-on-chain-balance). > [!TIP] > > It's a good idea to maintain a small on-chain balance in your Bark wallet so that you can initiate an exit without delay if one is ever needed. That said, it's still perfectly viable to deposit on-chain bitcoin at the time of exit if you don't have any on hand. It just means one extra step when timing may matter. ## Follow your balance over time The **Balance over time** chart plots your whole wallet: off-chain, on-chain, and any bitcoin mid-exit. The plugin records a point every 15 minutes while the balance moves, at least every two hours otherwise, and adds a live point when you open the page. Switch the period with **1W**, **1M**, **1Y**, or **ALL**, and the unit between **BTC** and your store's currency. ## Transactions The transactions list shows every payment your Bark wallet sends and receives, in the store's own vocabulary. Each row shows: | Column | What it shows | | - | - | | Date | When the payment was created. | | Transaction | The transaction ID, with a copy button. See [Transaction IDs](#transaction-ids). | | Label | The row's [labels](#label-your-transactions). | | Status | Successful, Pending, Failed, or Canceled. | | Payment type | A badge for how the bitcoin moved. See [Payment types](#payment-types). | | Amount | Positive for what you received, negative for what you sent, with its value in your store's currency at today's rate. | > [!NOTE] > > This list is for Bark-handled payments only. Checkout payments over Lightning and Ark appear here, as do the on-chain payments you send and receive from the admin panel. For on-chain payments received on your checkout, you'll need to go to the Bitcoin page. ### Payment types | Badge | Used for | | - | - | | **Ark** | Ark payments and boards | | **Ark: Refresh** | [Refreshes](/docs/btcpay/vtxos) | | **Lightning** | Lightning payments | | **On-chain** | Sends to on-chain addresses, offboards, and payments into and out of the Bark on-chain wallet | | **On-chain: Exit** | [Emergency exits](/docs/btcpay/settings#danger-zone), and exit claims shown on their own row | | **On-chain: Exit fee** | Exit fee transactions shown on their own row | Each emergency exit shows as one row that includes all the exit's fee transactions and its claim transaction. ### Transaction IDs Ark sends and Lightning payments have no transaction ID and show a dash. The other rows show these IDs: | Row | Transaction ID | | - | - | | Ark receive or exit | The VTXO's [exit transaction](/docs/learn/exit#the-emergency-exit-process), the last transaction an exit broadcasts before the claim. For an Ark receive, it stays off-chain unless the VTXO is exited. | | Board or refresh | The on-chain board or round transaction | | Offboard or send to an on-chain address | The on-chain transaction that pays the address | When a row has several IDs, such as a payment that arrived as several VTXOs, it shows the first one and a button such as **+2**. The button opens the transaction details, which list every ID. ### Filter and search the list Refreshes are wallet maintenance rather than payments, so the plugin hides them by default. To see them, select the **Filters** funnel at the right of the search field and turn off **Hide refreshes**. The choice is saved for the store. The **All types** and **All Status** dropdowns, and typing in the search field, filter the current page of the list. You can also search the whole history for a transaction ID, a VTXO outpoint, a Lightning payment hash, or the payment ID that BTCPay shows for an Ark payment (`txid-vout`). Paste it into the search field and press Enter. ## Inspect a transaction Select a row to open its **Transaction details**, which shows whichever of these apply: * Where the bitcoin went or came from, as an address, an Ark address, or a Lightning invoice. * Every transaction ID in full, and the payment hash for Lightning payments, each with a copy button. Transactions of the Bark on-chain wallet also show their block height. * The Bark wallet's own number for the payment, labeled **Movement**. It matches the MovementId column of the [Bark Wallet report](/docs/btcpay/reporting). * The fee. * Created and completed timestamps. * The labels. * A **Copy raw JSON** button for troubleshooting. ![Screenshot of the Transaction details dialog, with the amount, the status and payment type badges, the destination, fee, timestamps, labels, and the Copy raw JSON button](https://mintcdn.com/second-0659a37d/oyMVF3OPOvsi31EU/images/btcpay/transaction-details.png?fit=max\&auto=format\&n=oyMVF3OPOvsi31EU\&q=85\&s=c2649e15ad2164e5edac7e9cd61258a1) Every entry carries its destination, fee, timestamps, and labels ## Label your transactions Two kinds of labels mark the rows in the list and the details dialog: * **Store labels:** Labels you attach to Ark and Lightning payments on the [Receive and Send screens](/docs/btcpay/send-receive). They are shared across the store, like BTCPay's other labels. * **Checkout labels:** The plugin tags every checkout payment it receives with an **invoice** label, plus **app** and **payment-request** labels when they apply. Each one links to the matching BTCPay invoice, app, or payment request. # BTCPay Bark plugin Source: https://second.tech/docs/btcpay/index Accept self-custodial Lightning and Ark payments in BTCPay Server with the Bark plugin. No Lightning node, channels, or liquidity management required. The Bark plugin makes processing Lightning and Ark payments on your store super simple. [Install the plugin](/docs/btcpay/install), flick a toggle, and your store is instantly Lightning and Ark enabled. There's no node to sync and no channels to open first. * **No inbound liquidity to manage:** Receive payments, large and small, without ever needing to worry about inbound capacity. * **Free to receive:** [Receiving over Lightning is free](/docs/learn/payments-lightning#receiving) for you, and your customers pay only standard Lightning routing fees. Customers with a [Bark-enabled wallet](/docs/built-with-bark) pay over Ark for free. * **Your balance, your keys:** Payments land in your store's off-chain [Ark](/docs/learn/intro) balance, which is self-custodial. You can [withdraw over Lightning, Ark, or on-chain](/docs/btcpay/send-receive#send-bitcoin) whenever you need. If the Ark server ever stops cooperating, an [emergency exit](/docs/btcpay/settings#danger-zone) moves your balance on-chain without the server's help. * **Native reporting:** The Bark plugin is tightly integrated with BTCPay's dashboards, reports, and API, so everything feels as native as possible. * **Supports nanopayments:** Lightning and Ark payments can go down to one sat, for those that need it. ## Where checkout payments land After you activate the plugin, your customers see one QR code at checkout that offers on-chain, Lightning, and Ark. Most modern wallet apps pick the most efficient way to pay. Payments land in one of two wallets: * **Lightning and Ark payments:** Arrive in your store's Bark wallet. If your store kept its own Lightning node, Lightning payments go to that node instead (see [Lightning settings](/docs/btcpay/settings#lightning-settings)). * **On-chain payments:** Arrive in your store's native BTCPay wallet, exactly as before the plugin. ![Screenshot of the BTCPay checkout a customer sees, with a single QR code payable over Lightning, Ark, or on-chain](https://mintcdn.com/second-0659a37d/OfW--dvR5MfSzvzn/images/btcpay/checkout.png?fit=max\&auto=format\&n=OfW--dvR5MfSzvzn\&q=85\&s=c4b33935ab25b5983d105dc5acb1d934) One QR code and payment link, payable over Lightning, Ark, or on-chain > [!TIP] > > Prefer a classic checkout, with a separate tab for each payment method? Turn off [Unify on-chain and lightning payment URL/QR code](/docs/btcpay/settings#unify-on-chain-and-lightning-payment-url/qr-code) in your store's Lightning settings. ## Set up and run your store's wallet > **[Install the plugin](/docs/btcpay/install)** > > Install the plugin from the Plugin Directory and set up a Bark wallet for your store. > **[Back up your wallet](/docs/btcpay/backups)** > > Write down the recovery phrase and set up continuous backups of the wallet. > **[Understand your balances](/docs/btcpay/dashboard)** > > Read the Bark wallet page, including off-chain and on-chain balances. > **[Manage your Bark wallet](/docs/btcpay/send-receive)** > > Move bitcoin in and out of the wallet from the admin panel. > **[Manage your VTXOs](/docs/btcpay/vtxos)** > > Inspect, refresh, offboard, and exit individual VTXOs. > **[Export your Bark activity](/docs/btcpay/reporting)** > > Download every Bark payment and maintenance operation as a CSV. > **[Use the wallet through the API](/docs/btcpay/api)** > > Read Bark transactions and the balance over the Greenfield API, and pay Lightning invoices. > **[Configure the plugin](/docs/btcpay/settings)** > > Payment toggle, refresh behavior, Branta verification, and the emergency exit. # Install the plugin Source: https://second.tech/docs/btcpay/install Install the Bark plugin from the BTCPay Server Plugin Directory, set up a Bark wallet for your store, and start accepting Lightning and Ark payments. ## Before you start You need: * A self-hosted [BTCPay Server](https://docs.btcpayserver.org/Deployment/) on version 2.4.4 or later, running on Linux x86-64. Installing plugins requires server admin access, so accounts on [third-party hosts](https://docs.btcpayserver.org/Deployment/ThirdPartyHosting/) won't work. * A [store](https://docs.btcpayserver.org/CreateStore/) on that server. > [!NOTE] > > You don't need to set up a Lightning node. If your store has no Lightning node connected, the Bark plugin takes over your store's Lightning functionality. If it already has one, the plugin leaves it in place. See [Lightning settings](/docs/btcpay/settings#lightning-settings). ## Install the plugin from the Plugin Directory **1. Open the Plugin Directory** Sign in to BTCPay Server as a server admin. At the top right of the interface, select the plugins icon to open its dropdown menu, then select **Plugin Directory**. **2. Select Bark** Search the directory for **Bark**, then select it in the results. A panel opens with the plugin's details. ![Screenshot of the Plugin Directory page with the Bark plugin selected, its details panel open, and the Install in BTCPay Server button](https://mintcdn.com/second-0659a37d/oyMVF3OPOvsi31EU/images/btcpay/plugin-directory-bark.png?fit=max\&auto=format\&n=oyMVF3OPOvsi31EU\&q=85\&s=bb4a20aae44b944d148ce932bee5c6cd) **3. Select Install in BTCPay Server** Confirm with **Install** in the dialog that opens. BTCPay Server schedules the install. **4. Select Restart now** BTCPay Server loads the plugin during startup. > **Install from the plugin file instead** > > If your server can't reach the directory, install the plugin from its file. > > **1. Download the plugin file** > > Download `BTCPayServer.Plugins.Bark.btcpay` from the plugin's [page](https://plugin-builder.btcpayserver.org/public/plugins/bark) on the BTCPay Plugin Builder website. > > **2. Open Installed Plugins** > > Open the plugins menu at the top right of the interface, then select **Installed Plugins**. > > **3. Select Upload Plugin** > > The button sits at the bottom of the page. > > **4. Upload the file** > > Browse to the file, then select **Upload**. > > **5. Select Restart now** ## Set up a Bark wallet for your store After the restart, your store's sidebar gains a **Bark** entry under Wallets. Opening it for the first time takes you to the **Set up Bark** screen. ![Screenshot of the Set up Bark screen, with the plugin toggled on, Create new wallet selected, and the Ark Server and Chain Source fields set to the default values](https://mintcdn.com/second-0659a37d/oyMVF3OPOvsi31EU/images/btcpay/setup-bark.png?fit=max\&auto=format\&n=oyMVF3OPOvsi31EU\&q=85\&s=47dd0fd4557cdc274e05304f87b5a9ee) The Set up Bark screen, with the payments toggle, the wallet choice, and the pre-filled Ark Server and Chain Source fields **1. Select Bark in your store's sidebar** **2. Leave the Accept Lightning & Ark payments toggle on** You can change this later in the plugin's [settings](/docs/btcpay/settings). **3. Leave Create new wallet selected** To bring back a wallet you already have instead, select **Import existing wallet** and enter its 12 words in the **Seed phrase** field, in order. You can paste the whole phrase into any field. [Restoring from the phrase](/docs/btcpay/backups#restore-a-wallet-from-its-recovery-phrase) relies on the Ark server, and brings back the balance without the payment history. **4. Review the Ark Server and Chain Source** Both fields come pre-filled for mainnet: `https://ark.second.tech`, the Ark server that manages your VTXOs, and `https://mempool.second.tech/api`, the chain source that verifies on-chain activity. See [Ark server and chain source](/docs/btcpay/settings#ark-server-and-chain-source) for the available options. > [!NOTE] > > You can't change the Ark server and chain source you confirm here later. **5. Select Confirm & Enable** The button reads **Restore & Enable** when you import a wallet. The plugin checks that both endpoints serve the right network, asks you to confirm any custom address, creates or restores the wallet, and opens the wallet page. > [!NOTE] > > The plugin creates and manages your store's wallet keys on the server. See [Back up your wallet](/docs/btcpay/backups) to keep them recoverable. ## Check that Bark drives Lightning Completing setup enables two new payment methods on your store's checkout, Ark and Lightning: * The sidebar shows green status lights for Lightning and Bark. * The Lightning page shows **Custom Node** with `bark` as the node. * Checkout now shows a QR code and payment link that combines on-chain, Ark, and Lightning payment methods. After installing the plugin, the first thing to do is [back up your wallet](/docs/btcpay/backups). # Export your Bark activity Source: https://second.tech/docs/btcpay/reporting Export every Bark payment and maintenance operation of your store from the BTCPay Server Reporting page, with the columns your accountant needs. The plugin feeds a **Bark Wallet** report into your store's **Reporting** page, alongside BTCPay's own reports. **1. Open Reporting** Select **Reporting** in your store's sidebar. **2. Select the Bark Wallet report** Open the report dropdown and select **Bark Wallet**. **3. Pick a date range** The date filter works as for any other BTCPay report. **4. Select Export** BTCPay downloads the rows as a CSV file. ![Screenshot of the BTCPay Reporting page with the Bark Wallet report selected: two summary tables above a list of Ark, Lightning, and on-chain receives and sends, with all twelve columns](https://mintcdn.com/second-0659a37d/QEtGcwXwye7frlKu/images/btcpay/reporting.png?fit=max\&auto=format\&n=QEtGcwXwye7frlKu\&q=85\&s=5d6a0a45257c2262831f4cda50021015) One row per payment, received VTXO, or maintenance operation, oldest first, with the fee it paid On the Reporting page, two summary tables sit above the rows. One totals BalanceChange by Crypto and Confirmed, and the other totals BalanceChange and Fee by Type and Status. The CSV export contains only the rows. ## Read the columns The first eight columns match BTCPay's own **Wallets** report (without its fiat Rate columns). The Bark Wallet report adds four columns: Type, Status, MovementId, and PaymentHash. An Ark receive that arrives as several VTXOs gets one row per VTXO, as BTCPay records one payment per VTXO on invoices. > [!NOTE] > > This is in contrast to the Bark plugin dashboard, which bundles multiple VTXOs into their associated payment rows. | Column | What it contains | | - | - | | Date | When Bark created the payment or operation. Transactions of the Bark on-chain wallet use the time the plugin first saw them, or a time estimated from the block height if they were already confirmed. | | Crypto | Always BTC. | | TransactionId | The ID of the underlying on-chain or Ark transaction, if there is one. The [table of transaction types](/docs/btcpay/api#transaction-types) on the API page lists which ID each type carries. Several rows can share one. | | InvoiceId | The BTCPay invoice an Ark or Lightning receive paid. | | Confirmed | Whether the row's amount can no longer change. A failed or canceled payment counts as confirmed too, so read Status for how the payment ended. A row that isn't confirmed can still change its amount, gain its TransactionId, or disappear (a failed refresh, for example). | | BalanceChange | The row's net effect on the wallet's total balance, in BTC, after its fee: positive for bitcoin in, negative for bitcoin out. Over the wallet's full history, BalanceChange adds up to its total balance. A board or an offboard to the Bark on-chain wallet changes the balance only by its fees. An exit changes the balance by 0, unless its bitcoin is claimed to an address outside the Bark wallet. | | Fee | What the wallet paid for the row, in BTC, already included in BalanceChange. Zero when the row cost nothing. On On-chain Receive rows, any fee shown was paid by the sender and isn't part of BalanceChange. | | FeeRate | The feerate in sat/vB, for transactions of the Bark on-chain wallet, when known. Empty on other rows. | | Type | Lightning Receive, Lightning Send, Ark Receive, Ark Send, Refresh, Board, Offboard, Send On-chain, Exit, Exit Fee, Exit Claim, On-chain Receive, On-chain Send, or On-chain Internal. Send On-chain is a payment from your off-chain balance to an on-chain address. On-chain Send is a payment from the Bark on-chain wallet to an on-chain address. The [table of transaction types](/docs/btcpay/api#transaction-types) on the API page explains each type. | | Status | successful, pending, failed, or canceled. Transactions of the Bark on-chain wallet are only successful or pending. | | MovementId | The Bark wallet's own number for the payment or operation. Rows share a number when a payment arrived as several VTXOs, and an exit's Exit Fee and Exit Claim rows carry the Exit row's number. Empty on transactions of the Bark on-chain wallet that belong to no Bark payment. If the wallet is [restored from its recovery phrase](/docs/btcpay/backups#restore-a-wallet-from-its-recovery-phrase), Bark numbers new payments from 1 again. An export from before the restore and one from after it can then show the same MovementId for different payments. | | PaymentHash | On Lightning rows, the payment hash. | > [!NOTE] > > Failed or canceled payments, sent or received, appear only when they still moved bitcoin, with their real amount. Refreshes still in progress appear only if they moved bitcoin or cost a fee. The [Bark wallet page](/docs/btcpay/dashboard#transactions) lists every failed or canceled payment. To read the wallet's transactions from your own tools, use the [Greenfield API endpoint](/docs/btcpay/api). # Manage your Bark wallet Source: https://second.tech/docs/btcpay/send-receive Send and receive bitcoin from your store's Bark wallet in BTCPay Server and manage Bark's separate on-chain balance (used as an emergency exit reserve). Use **Send** and **Receive**, under Bark in your store's sidebar, to move bitcoin in and out of the wallet as an admin. ## Receive bitcoin The Receive screen generates a payment link and QR code with two options: **All networks** One QR code a sender can pay over on-chain, Ark, or Lightning. The Lightning option activates once you enter an amount. Select **Generate another payment link** for fresh addresses. ![Screenshot of the Receive screen on the All networks tab, with an amount, the labels field, the payment link, a QR code payable over on-chain, Ark, and Lightning, and the Generate another payment link button](https://mintcdn.com/second-0659a37d/oyMVF3OPOvsi31EU/images/btcpay/receive-all-networks.png?fit=max\&auto=format\&n=oyMVF3OPOvsi31EU\&q=85\&s=1a2424f8a234d902570d20a171466d2b) **Ark only** A payment link that only carries an Ark address, for payments from wallet apps on the same Ark server. Select **Generate another address** for a fresh one. ![Screenshot of the Receive screen on the Ark only tab, with the amount and labels fields, an Ark address QR code, and the Generate another address button](https://mintcdn.com/second-0659a37d/oyMVF3OPOvsi31EU/images/btcpay/receive-ark-only.png?fit=max\&auto=format\&n=oyMVF3OPOvsi31EU\&q=85\&s=bd3d9fa9ad2aebcfe511ee7cc2418845) *** Where the bitcoin lands depends on how the sender pays: * Ark and Lightning payments arrive in your off-chain balance as [VTXOs](/docs/learn/vtxo). * On-chain payments arrive in the [Bark on-chain balance](/docs/btcpay/dashboard#the-bark-on-chain-balance-is-a-separate-wallet). This is how you fund the emergency exit reserve. You can attach labels while the link is on screen. The plugin adds them to the resulting Ark or Lightning payment in the [transactions list](/docs/btcpay/dashboard#transactions). When the payment arrives, the screen confirms it with the amount and the network it came through. ## Send bitcoin To send from your off-chain balance: **1. Enter the destination** Paste or scan an Ark address, a Lightning address, a BOLT11 invoice, an on-chain address, or a BIP-321 payment link. **2. Enter the amount** Enter the amount in sats that you'd like to send. If you scan or paste a payment link that includes an amount, the amount field fills in automatically. **3. Leave the From selector on Ark balance** You will rarely need to change this. The on-chain balance is reserved for emergency exit activities only. **4. Select Send** The Send screen shows the result, and the transaction appears in the [transactions list](/docs/btcpay/dashboard#transactions) with its status. If a send ever fails, check the transactions list before you send again, to avoid double payments. ![Screenshot of the Send screen with a destination, an amount in sats, and the From selector showing the Ark balance](https://mintcdn.com/second-0659a37d/oyMVF3OPOvsi31EU/images/btcpay/send-form.png?fit=max\&auto=format\&n=oyMVF3OPOvsi31EU\&q=85\&s=785d68a074f31bda6c8b5ee7fe57ce0c) > [!NOTE] > > A send to an on-chain address delivers exactly the amount you enter, with the fee on top. To move chosen VTXOs on-chain instead, [offboard](/docs/btcpay/vtxos#refresh-offboard-or-exit-manually) them from the VTXOs page. An offboard takes its fee out of the VTXOs, enabling you to empty the balance more easily. ## Confirm the recipient with Branta When the destination you enter is registered with [Branta](https://branta.pro), a verification line under the field names the platform it belongs to. You can then confirm the payment details match who you think you're paying. If a payment link carries a Branta signature that doesn't match its destination, the plugin shows a tamper warning instead. Recipients opt in to Branta on their side: no line simply means the destination isn't registered, not that anything is wrong. You can turn the lookup off in the plugin's [settings](/docs/btcpay/settings#verify-send-destinations-with-branta). ## Fund and withdraw the on-chain balance You're likely to use Bark's on-chain balance very little. You should only need to receive bitcoin to your [Bark on-chain balance](/docs/btcpay/dashboard#the-bark-on-chain-balance-is-a-separate-wallet) when adding a reserve for emergency exits. You should only need to send bitcoin from your Bark on-chain wallet after you perform an offboard or emergency exit. Moving bitcoin in and out of the Bark on-chain wallet mirrors the off-chain **Receive** and **Send** flows above: * **Add bitcoin to the Bark on-chain wallet:** Go to **Bark** > **[Receive](/docs/btcpay/send-receive#receive-bitcoin)** and send an on-chain payment to the QR code or payment link shown. * **Move bitcoin out of Bark's on-chain wallet:** Go to **Bark** > **[Send](/docs/btcpay/send-receive#send-bitcoin)**, set **From** to **Bark on-chain balance**, and enter an on-chain address. This source only pays on-chain addresses. ## Bark wallet fees * **Off-chain balance:** Sends to an Ark address are free. Lightning sends, sends to on-chain addresses, and offboards carry a fee that scales with the amount and your VTXOs' remaining lifetime. For sends to on-chain addresses and offboards, the fee also covers the on-chain transaction. See [Second's pricing](https://second.tech/pricing). * **On-chain wallet:** Standard on-chain fees. # Configure the plugin Source: https://second.tech/docs/btcpay/settings Configure the Bark plugin in BTCPay Server: the payments toggle, refresh behavior, Branta verification, backups, the emergency exit, and Lightning settings. Most configuration settings for the Bark plugin are available on **Bark** > **Settings**. There are also a few Lightning-specific settings available on **Lightning** > **Settings**. ## Bark settings ![Screenshot of the Bark Settings page, with the payments, refresh, and Branta toggles, the auto-refresh threshold dropdown, the Backup section, and the Danger Zone holding the Emergency exit all button](https://mintcdn.com/second-0659a37d/oyMVF3OPOvsi31EU/images/btcpay/settings.png?fit=max\&auto=format\&n=oyMVF3OPOvsi31EU\&q=85\&s=f830b1fc31fab9e7d1149725ee051b8c) ### Accept Lightning & Ark payments This toggle enables the Lightning and Ark payment methods at checkout. When turned off, your checkout falls back to your native BTCPay on-chain wallet, and to your own Lightning node if the store kept one. Your Bark balances and settings remain untouched, and you can still send and receive from the admin panel. ### Refresh on receive Off by default. When enabled, the plugin refreshes each VTXO you receive in the next available [round](/docs/learn/rounds), rather than waiting until it approaches expiry. > [!NOTE] > > Refreshing on receive provides maximum security, but it significantly increases the cost of receiving payments over Bark. See the [Ark receive](/docs/learn/payments#the-payment-security-trade-off) and [Lightning receive](/docs/learn/payments-lightning#trust-model-for-lightning-receive) trust models, and [Second's pricing](https://second.tech/pricing). ### Verify send destinations with Branta On by default. When enabled, the Send screen looks up each Lightning and Ark destination with [Branta](https://branta.pro) and names the platform it belongs to, as described in [Confirm the recipient with Branta](/docs/btcpay/send-receive#confirm-the-recipient-with-branta). When turned off, the Send screen shows no verification line. ### Auto-refresh threshold The plugin automatically refreshes any VTXO whose remaining lifetime drops below this threshold. Every option in the dropdown is labeled with its cost on your Ark server. The default, one day before expiry, keeps automatic refreshes free on Second's server, while wider thresholds trade [liquidity fees](/docs/learn/rounds#round-economics) for a larger safety margin before expiry. See [Second's pricing](https://second.tech/pricing) for the fee tiers. > [!WARNING] > > Wide thresholds can result in significant costs and drain an off-chain balance. The plugin caps the options at half a VTXO's lifetime, 14 days on Second's server, and rejects anything above it. ### Backup Select **View Recovery Phrase** to display the wallet's 12 words. The field beneath shows the wallet data directory to include in a continuous backup. See [Back up your wallet](/docs/btcpay/backups). ### Danger Zone **Emergency exit all** begins a process that reclaims your entire off-chain balance on-chain without the Ark server's cooperation, as described in [emergency exits](/docs/learn/exit). The section only appears while the wallet holds spendable VTXOs, and shows a disabled **Emergency exit in progress** button while an exit runs. To exit only some VTXOs, use the [VTXOs page](/docs/btcpay/vtxos#refresh-offboard-or-exit-manually) instead. > [!WARNING] > > Use this only when the Ark server is unresponsive and you can no longer spend your VTXOs. To complete an exit, each VTXO requires multiple on-chain transactions, so fees can be significant. If the server is still responding, an [offboard](/docs/btcpay/vtxos#refresh-offboard-or-exit-manually) is faster and cheaper. **1. Check the cost estimate** The confirmation dialog shows the estimated on-chain fee at the current feerate. One part the plugin pays now from your Bark on-chain wallet to broadcast the exit transactions. The other part it deducts later when it claims the exited bitcoin. The actual cost depends on feerates while the exit completes. **2. Select Start emergency exit** The plugin starts broadcasting the exit transactions, and BTCPay notifies you when the exit completes or fails. Before you can start, your [Bark on-chain balance](/docs/btcpay/dashboard#the-bark-on-chain-balance-is-a-separate-wallet) needs enough confirmed, spendable bitcoin to cover the broadcast part of the estimate. If it doesn't, the plugin shows what is spendable and the minimum it needs, and sends you to [Receive](/docs/btcpay/send-receive#receive-bitcoin) to top it up with an on-chain payment. Once started, the exit broadcasts its transactions in sequence, which takes time. You can follow progress on the [VTXOs page](/docs/btcpay/vtxos#track-exits). When the exit outputs unlock, the plugin claims them into the Bark on-chain balance automatically. Withdraw them with [Send](/docs/btcpay/send-receive#fund-and-withdraw-the-on-chain-balance), using the on-chain source. ## Ark server and chain source [You confirm these two endpoints at setup](/docs/btcpay/install#set-up-a-bark-wallet-for-your-store), and they can't be changed afterwards: * **Ark Server:** Second runs two servers: `https://ark.second.tech` on mainnet (the default) and `https://ark.signet.2nd.dev` on signet, for test deployments. Second doesn't run any other servers. * **Chain Source:** Any public endpoint exposing the Esplora HTTP API. Esplora and mempool instances both work, while servers that only speak the Electrum protocol, such as a bare electrs, don't. The plugin checks that the endpoint serves the right network. The default is Second's `https://mempool.second.tech/api`. > [!NOTE] > > The plugin runs on mainnet unless your BTCPay Server sets the `BARK_NETWORK` environment variable to `signet` before you set up a store. On signet, the fields come pre-filled with Second's signet server and chain source. ## Lightning settings A few Lightning-specific options live on the Lightning page: select **Lightning** in your store's sidebar, then **Settings** beneath it. With Bark driving Lightning, the page shows **Custom Node** with `bark` as the node, and only part of that page applies. > [!NOTE] > > If your store already had a Lightning node connected when you set up Bark, the plugin left it in place. Lightning payments keep going through that node rather than Bark. Every option on the Lightning page then applies to that node as usual. To switch Lightning to Bark: > > 1. Select **Change connection**. > 2. Select **Use custom node**. > 3. Expand **Bark - Ark Lightning**. > 4. Copy the connection string shown into the field. > 5. Select **Save**. ### Enabled This toggle enables the Lightning payment method at checkout on its own. Turn it off to stop offering Lightning at checkout (checkout QR codes and payment links stop including Lightning invoices). Ark and on-chain payments are unaffected. This setting is connected to the **Accept Lightning & Ark payments** setting. Turning off **Accept Lightning & Ark payments** turns **Enabled** off too, unless your store kept its own Lightning node (disabled while Bark is active). ### Display Lightning payment amounts in Satoshis A checkout display preference: amounts show in sats instead of BTC. Works as usual with Bark. ### Unify on-chain and lightning payment URL/QR code This setting, combined with **Checkout Appearance** > **Default payment method on checkout**, defines how the checkout appears to your customers. When you turn on **Accept Lightning & Ark payments**, the plugin switches on the unified QR and makes Ark the default. Customers then get one QR code that any Ark, Lightning, or on-chain wallet can pay. > [!TIP] > > This setting also appears on the **Checkout Appearance** page. It's the same setting, so changing it on one page changes it on the other. | Settings | What customers see | | - | - | | Unify on, Ark as the default | One QR code for Ark, Lightning, and on-chain wallets | | Unify on, Bitcoin or Lightning as the default | One QR code for Lightning and on-chain wallets, without Ark | | Unify off, any default | Separate Ark, Bitcoin, and Lightning tabs. The checkout opens on the default payment method's tab. | > [!NOTE] > > You'll still see a separate Bitcoin tab whenever your store [adds a network fee to an on-chain payment](https://docs.btcpayserver.org/FAQ/Stores/#add-network-fee-to-invoice-vary-with-mining-fees). ### Settings that have no effect Options tied to running your own Lightning node do nothing with Bark. The plugin requests invoices from the Ark server with only an amount, so **Description template of the lightning invoice** and **Add hop hints for private channels to the Lightning invoice** are ignored. # Update or uninstall the plugin Source: https://second.tech/docs/btcpay/uninstall Keep the Bark plugin up to date in BTCPay Server, or remove it safely: withdraw or keep your bitcoin, uninstall, and reconnect your store's Lightning setup. ## Update the plugin New versions carry the latest fixes, so update as soon as one ships. **1. Open Installed Plugins** At the top right of the interface, select the plugins icon to open its dropdown menu, then select **Installed Plugins**. **2. Select Update on the Bark card** The button appears when a newer version is available, shown in a badge next to the installed version. **3. Select Restart now** BTCPay Server loads the new version during startup. ## Uninstall the plugin Uninstalling the Bark plugin removes it for every store on the server. Your bitcoin doesn't move: keys and wallet data stay in [BTCPay Server's data directory](/docs/btcpay/backups), and reinstalling the plugin restores access to the same wallets. > [!WARNING] > > If you don't plan to reinstall, empty the wallet first: > > * [Offboard](/docs/btcpay/vtxos#refresh-offboard-or-exit-manually) your VTXOs to a wallet you control, or [send](/docs/btcpay/send-receive#send-bitcoin) your off-chain balance to an Ark or Lightning destination. > * [Withdraw the on-chain balance](/docs/btcpay/send-receive#fund-and-withdraw-the-on-chain-balance) the same way. > > Bitcoin left behind remains spendable only through the keys on that server. **1. Open Installed Plugins** **2. Uninstall Bark** Find **Bark** in the list and select **Uninstall**. ![Screenshot of the Installed Plugins page, with the Bark plugin card and its Uninstall button](https://mintcdn.com/second-0659a37d/oyMVF3OPOvsi31EU/images/btcpay/uninstall-bark.png?fit=max\&auto=format\&n=oyMVF3OPOvsi31EU\&q=85\&s=2a3adecd64cb413e5b869b4dc61730bd) **3. Select Restart now** BTCPay Server removes the plugin during startup. ## Lightning and Ark stop working After uninstalling, your checkout accepts neither Ark nor Lightning payments through Bark. To accept Lightning again, reinstall the Bark plugin, or connect the store to another Lightning setup from the Lightning page. If your store kept its own Lightning node when you [set up Bark](/docs/btcpay/settings#lightning-settings), that node keeps working. # Manage your VTXOs Source: https://second.tech/docs/btcpay/vtxos Inspect the VTXOs behind your Bark wallet's off-chain balance in BTCPay Server, refresh, offboard, or exit them manually, and track exit progress. The VTXOs page shows a list of the [VTXOs](/docs/learn/vtxo) that make up your off-chain balance, each with its expiry block height, an estimated expiry time, and its status. ![Screenshot of the VTXOs page listing spendable VTXOs with their expiry block heights and estimated expiry times, the auto-refresh badge, and the next round countdown](https://mintcdn.com/second-0659a37d/oyMVF3OPOvsi31EU/images/btcpay/vtxos.png?fit=max\&auto=format\&n=oyMVF3OPOvsi31EU\&q=85\&s=9661f92bddc190d552c6fbe56db61ea7) A VTXO shows as **Spendable** most of its life, as **Locked** while an operation uses it, and as **Exiting** or **Exited** during and after an [emergency exit](/docs/btcpay/settings#danger-zone). Use the status filter above the list to show one kind at a time. ## The plugin refreshes VTXOs for you VTXOs have a limited [lifetime](/docs/learn/lifetime): your wallet must periodically refresh them before expiry. A badge at the top of the list shows the current auto-refresh threshold. By default, the plugin refreshes any VTXO whose lifetime drops below one day, which keeps automatic refreshes free. You can widen the threshold, or set the wallet to refresh every VTXO right after it's received, in [settings](/docs/btcpay/settings#refresh-on-receive). The plugin submits queued refreshes to [rounds](/docs/learn/rounds). The countdown at the top of the page shows when the next round starts, and how often the Ark server runs them. If an automatic refresh fails, or a VTXO gets within half the threshold of expiry before the plugin refreshes it, BTCPay sends you a **VTXO refresh alert** notification. It asks you to refresh manually. ## Refresh, offboard, or exit manually You may sometimes want granular control over your VTXOs. For example, if you receive a particularly large VTXO, you might prefer to refresh it before it reaches the refresh threshold, or to bring its bitcoin on-chain. To act on individual VTXOs, select one or more in the list, then select an action in the bar that appears at the bottom of the page: * **Refresh:** Mark the selected VTXOs for refresh in the next [round](/docs/learn/rounds). You forfeit the selected VTXOs and receive fresh ones. * **Offboard:** Make an on-chain payment from the selected VTXOs. Leave **Destination address** empty to deliver the bitcoin to your [Bark on-chain wallet](/docs/btcpay/dashboard#the-bark-on-chain-balance-is-a-separate-wallet). Select **Use BTCPay Server wallet** to deliver it to your store's regular wallet instead, or paste any on-chain address. Once an address is in the field, the dialog quotes the fee and the amount you receive. BTCPay notifies you when the payment completes. * **Emergency Exit:** Reclaim the selected VTXOs' bitcoin on-chain without the Ark server's cooperation: the per-VTXO version of the [emergency exit](/docs/btcpay/settings#danger-zone), with the same warnings. ![Screenshot of the VTXOs page with one VTXO selected and the action bar at the bottom showing the Refresh, Offboard, and Emergency Exit buttons](https://mintcdn.com/second-0659a37d/oyMVF3OPOvsi31EU/images/btcpay/vtxos-selected.png?fit=max\&auto=format\&n=oyMVF3OPOvsi31EU\&q=85\&s=72c7676eceb949798af8957429a4620a) Selecting VTXOs brings up the Refresh, Offboard, and Emergency Exit actions > [!NOTE] > > On Second's server, refreshing is free during a VTXO's final two days of lifetime. Refreshing earlier costs [liquidity fees](/docs/btcpay/settings#auto-refresh-threshold). The plugin deducts the [offboard fee](/docs/btcpay/send-receive#bark-wallet-fees), on-chain fee included, from the offboarded amount. The plugin only acts on VTXOs that the current filter shows and that are spendable. If it can't confirm that against the wallet, it refuses the action and asks you to check the BTCPay Server logs. ## Track exits If an [emergency exit](/docs/btcpay/settings#danger-zone) is in progress, this page is where you follow it. Exiting VTXOs show an **Exiting** status with the count of confirmed transactions, then switch to **Exited** once the plugin claims their bitcoin into the Bark on-chain wallet. A **Pending exit** sub-balance appears under the main balance until every VTXO has been claimed. An exit can also end without a claim: when its VTXO was already spent, the Ark server [swept](/docs/learn/lifetime#what-happens-when-vtxos-expire) it, or the exit was canceled. The plugin then stops showing the VTXO as **Exiting**, and the exit no longer counts as in progress. ## Refresh an expired VTXO If a VTXO has [expired](/docs/learn/lifetime#what-happens-when-vtxos-expire), the **Expiry block height** column shows **Expired** next to its height. The plugin refreshes it when the next round starts, as long as BTCPay Server is running. Let the refresh complete before you send an Ark payment: 1. After the **Next round in** countdown reaches zero, reload the page. The VTXO's status shows **Locked**. 2. If it still shows **Spendable**, tick the VTXO and select **Refresh**. A banner confirms that the plugin queued it for the next round. 3. About one block after the round, reload the page. A fresh VTXO has replaced the expired one. ![Screenshot of the VTXOs page with one VTXO whose expiry block height is marked Expired while its status still shows Spendable](https://mintcdn.com/second-0659a37d/sWpp6Y7pxlHxdWXE/images/btcpay/vtxos-expired.png?fit=max\&auto=format\&n=sWpp6Y7pxlHxdWXE\&q=85\&s=452e3330e8f21870cec00d3080db0778) An expired VTXO stays Spendable until the plugin refreshes it in the next round # Built with Bark Source: https://second.tech/docs/built-with-bark Real apps shipping bitcoin payments on Ark, Lightning, and on-chain. Built by teams using the Bark SDK and Barkd. ## Mobile wallets > **[Noah](https://github.com/smolcars/noah)** > > A full-stack mobile Ark wallet, pairing a React Native app with its own Rust backend for account flows and Lightning integration. > > React Native · Rust · iOS · Android > **[Arké](https://github.com/GBKS/arke)** > > A design-led native iOS wallet that brings bitcoin.design's open-source UX to life, and forges new ground for Ark-native patterns. > > Swift · iOS > **[Rebel](https://github.com/benthecarman/rebel-wallet)** > > A native iOS wallet from Mutiny's Ben Carman, built with Rust Multiplatform to bring Ark, Lightning, and Nostr together in a single app. > > Swift · Rust · iOS > **[Cypher Box](https://github.com/CypherBoxLLC/Cypher-Box)** > > A three-tier wallet that scales with you: Lightning Accounts on Coinos and Strike, hot self-custody, and air-gapped cold storage. > > React Native · iOS · Android > **[Satsigner](https://github.com/satsigner/satsigner)** > > A Sparrow-style mobile signer with visual UTXO control, full multisig PSBT workflows, and Nostr-based label sync across devices. > > TypeScript · Expo · iOS · Android > **[Ibis Wallet](https://github.com/aeonBTC/IbisWallet)** > > A power-user Android wallet with coin control and built-in Tor, adding Ark to its modular layer 2 lineup through the Bark SDK. > > Kotlin · Android > **[Zappin](https://zappin.online)** > > A map-based social app from Japan: pin posts and shop reviews to places, then tip them in bitcoin from a self-custodial Ark wallet. > > Android · Closed beta > **[Thârk](https://github.com/Praphakan/Thark)** > > A Noah fork for Thailand: scan any PromptPay QR and pay in sats, while a peer-to-peer taker settles the merchant in baht. > > React Native · Android · Beta ## Web wallets > **[Hal](https://github.com/asoltys/halwallet)** > > A whole wallet in a single HTML file, from Coinos creator Adam Soltys, speaking MuSig2 and gRPC directly to the Ark server. > > JavaScript · PWA · Nostr > **[Bark Wallet](/docs/bark-wallet)** > > Second's reference wallet app: one balance spendable over Ark, Lightning, and on-chain, backed by Barkd on your node or desktop, or by Wasm in the browser. > > Umbrel · Start9 · Docker · Wasm · Built by Second ## Swaps > **[Swaptopia](/docs/swaptopia)** > > Swap between on-chain bitcoin and Lightning from a self-custodial wallet app that runs in your browser, with no account and no counterparty holding your sats. > > Web · Bark SDK · Built by Second ## API and CLI > **[Bark](https://gitlab.com/ark-bitcoin/bark)** > > The reference Rust implementation of the Ark protocol. Includes a CLI wallet, and the engine inside Barkd and every Bark SDK. > > Rust · CLI · Built by Second > **[Barkd](https://gitlab.com/ark-bitcoin/bark)** > > Bark as a long-lived daemon, exposing a REST API for backend services and integrations. > > Rust · Daemon · Built by Second ## Payment processing > **[BTCPay Server plugin](/docs/btcpay)** > > Add self-custodial Lightning payments to your BTCPay checkout without running a Lightning node or managing channel liquidity. > > BTCPay Server · Built by Second > **[Bark Pay](/docs/bark-pay)** > > A self-hosted payment processor with a charges API, webhooks, and a hosted checkout page. Customers pay over Lightning, Ark, or on-chain into a wallet you control. > > Self-hosted · Barkd · Built by Second > **[ArkAPI](https://arkapi.dev)** > > A pay-per-call API gateway for AI agents. Sats-metered sessions over Ark or Lightning, with no signup or API keys. > > Go · Web · Telegram bot > **[arkzap-me](https://github.com/benthecarman/arkzap-me)** > > A self-hostable LNURL server that gives any Bark or Arkade address a deterministic Lightning address, with Nostr zap support built in. > > Rust · LNURL · Nostr · Signet > **[qpayd](https://github.com/earonesty/qpayd)** > > Bitcoin payments without the heavy box: a small Rust daemon that locks fiat prices, tracks invoices, and dispatches signed webhooks. > > Rust · Self-hosted · Barkd > **[AuthenticDoc](https://authenticdoc.online)** > > A DocuSign alternative for tamper-proof document signing over Nostr, with a custom Bark-powered checkout for Lightning payments. > > Web · Nostr *** Built something on Bark? We'd love to feature it. Tell us about your app on the [community forum](https://community.second.tech) or in our [community chat](https://chat.second.tech). # Changelog Source: https://second.tech/docs/changelog/index Updates to Bark, our implementation of the Ark protocol. Including the SDK, wallet, server, and developer tools. #### Update categories Wallet    Server    Protocol    Upstream *** **22 October 2026** 0.8.0 ![A hand-drawn arrow snaking through rows of small cells, the cells behind it outlined in solid blue and those ahead still dashed, representing a wallet restore that works through every VTXO in one scan](https://mintcdn.com/second-0659a37d/PXun1NLypxJ30fKI/images/restore-sweep-grid-light.svg?fit=max\&auto=format\&n=PXun1NLypxJ30fKI\&q=85\&s=5db508e56dd081e727289e24fc0e0b93) > [!WARNING] > > **Breaking changes** > > * **[SDK types](#blockheight-and-blockdelta-types-replace-raw-integers):** heights and deltas are typed, not integers. > * **[Wallet API](#wallet-balance-is-now-more-accurate):** balance, exit estimate, send and action signatures changed. > * **[captaind](#the-server-builds-transactions-at-the-chunk-feerate):** `min_trusted_confs` must be at least 1. > * **[bark-json](#sends-and-offboards-return-their-movement-id):** `OffboardResult` and send requests gained required fields. > * **[SDK traits](#additional-improvements):** custom on-chain wallets must implement `sign_psbt`. ### Restore from mnemonic recovers VTXOs by xpub A wallet restored from its mnemonic now asks the Ark server for the VTXOs of its xpub first. A restore no longer depends on the key gap limit or on a backup posted by the old wallet. The mailboxes are now read afterwards, only for VTXOs the lookup missed. Spent VTXOs now skip validation, and bodies and spend states now arrive 1000 per request, so a restore that took 210 seconds now takes 60. \[[2609](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2609)] \[[2633](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2633)] \[[2618](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2618)] \[[2617](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2617)] \[[2593](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2593)] \[[2594](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2594)] ### Barkd serves the bark-web wallet UI The release builds of `barkd` now serve the [bark-web](https://gitlab.com/ark-bitcoin/bark-web) wallet UI at the root of the HTTP listener, port 3000 by default. Pass `--no-ui` to disable it. A `cargo` build includes the UI only with the `barkd-web-ui` feature. \[[2221](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2221)] ### Wallet balance is now more accurate `Wallet::balance` now reports the sats held by an Ark send or an offboard in progress. Expired VTXOs and those at the server's exit-depth limit now move out of `spendable` into the new `needs_refresh` field, so an app can show a lower spendable balance after upgrading. Round inputs and boards now count once each. \[[2509](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2509)] ### Emergency exit fee estimate is now deterministic The emergency exit fee estimate now comes from transaction weight at the requested feerate, scaled by a `fee_margin` (default 1.2), instead of a randomised coin-selection walk. It no longer touches the on-chain wallet, so it works with any wallet. The REST and CLI `fundable` field is now deprecated: compare the estimate with your on-chain balance instead. \[[2511](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2511)] \[[2656](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2656)] ### Interrupted refresh no longer strands locked VTXOs Joining a round no longer locks the input VTXOs. A participation now locks them only once a round attempt starts. Interrupting `bark refresh` while it waits now leaves no locks behind, and `bark round cancel` can always clear the leftover participation. A participation that loses inputs to another operation now shrinks instead of failing. \[[2443](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2443)] ### Sends and offboards return their movement ID An Ark send now returns its `MovementId`, and `send_onchain` and the offboard methods now return an `OffboardResult` that includes it. An app can now attach a label or a contact to the payment it just made. Previously, it had to match on destination, amount and time, which fails for repeated payments of the same amount. \[[2610](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2610)] ### Choose how long the server retries a Lightning send A Lightning send now takes a retry time. `bark send --retry-for` and `retry_for_secs` in REST set how many seconds the server keeps trying, up to the server's maximum (default five minutes). A value of 0 makes a single attempt. The server also no longer fails a send when its connection to Core Lightning drops mid-payment. \[[2580](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2580)] \[[2582](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2582)] ### Wallet actions no longer lock VTXOs forever after a crash Lightning and Ark sends now lock their inputs inside the action, so a crash no longer leaves VTXOs locked forever. Each step now classifies a failure as retry or abort, so a rejected offboard or a double-spent board now fails instead of retrying forever. The Lightning receive now returns errors where it used to panic. \[[2615](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2615)] ### Exits report when the server swept their VTXO An emergency exit whose VTXO the server swept after expiry now ends in a new `vtxo-swept` state listing the inputs that were taken, instead of retrying its broadcast forever without telling the user. Fee estimation now returns a distinct error for such a VTXO. A refresh may still produce a fresh VTXO. \[[2542](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2542)] ### `BlockHeight` and `BlockDelta` types replace raw integers Block heights and deltas across the SDK, `ark-lib` and the server config are now typed `BlockHeight` and `BlockDelta` instead of plain integers. The two can no longer be mixed up, and arithmetic on them saturates instead of overflowing. The JSON, REST and config file formats are unchanged, so only Rust consumers need to update. \[[2499](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2499)] ### The server builds transactions at the chunk feerate `captaind` now builds round, offboard and VTXO pool transactions so that the whole chunk, unconfirmed ancestors included, pays the target feerate. Previously, `captaind` priced only the new transaction, which left it stuck behind low-fee change. `min_trusted_confs` must now be at least 1 or `captaind` refuses to start, since an unconfirmed third-party deposit counted as trusted. \[[2503](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2503)] ### Additional improvements * A wallet restored from its mnemonic now recovers the outputs of delegated round participations that completed while the wallet was gone. \[[2536](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2536)] * Recovery now reads each mailbox to the end instead of stopping after ten pages, and a page boundary no longer skips part of a message group. \[[2616](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2616)] \[[2552](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2552)] \[[2567](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2567)] * `bark send` now accepts `lightning:` URIs and LUD-17 `lnurlp://` links, which some wallets show in their QR codes. \[[2629](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2629)] * New `_with` variants of the SDK's Lightning payment methods take a `LightningSendOptions` with the retry time. \[[2582](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2582)] * A board that fails after signing no longer leaves its funding transaction in the on-chain wallet. Custom on-chain wallets must now implement `sign_psbt`. \[[2614](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2614)] * Ark sends now split change off the VTXO that coin selection chose instead of the largest one, which cuts failed sends and dust. \[[2579](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2579)] * An on-chain send no longer fails on a broadcast error: Bark now records the transaction and rebroadcasts it on the next sync, so a retry cannot pay twice. \[[2496](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2496)] * A finished emergency exit no longer updates its history entry on every sync, which pinned old cancelled exits to the top of a history sorted by completion. \[[2610](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2610)] * A Lightning receive claim is no longer refused when Bark's chain tip is one block ahead of the server's. \[[2632](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2632)] * Lightning send progress now reports a new `inputs-locked` phase between `start` and `htlc-received`. \[[2615](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2615)] * The new `bark debug-info` command prints the network, mailbox ID and VTXO xpub as JSON to share in support requests. \[[2578](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2578)] * `bark create` now refuses to run while `barkd` or another creation holds the data directory lock. Thanks to external contributor [Ignacio Porte](https://github.com/IgnacioPorte) for this fix. \[[2583](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2583)] * The nix flake now builds `captaind` on Apple Silicon macOS. Thanks to external contributor [Godefroid Chapelle](https://github.com/gotcha) for this work. \[[2605](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2605)] * The server now caps `RegisterVtxoTransactions` at 1000 VTXOs per request, matching the other bulk RPCs, and Bark now registers in batches. \[[2646](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2646)] * A broad server hardening pass closed several issues that a misbehaving client could trigger. * `captaind` no longer writes Lightning preimages to its logs or telemetry. \[[2625](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2625)] \[[2627](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2627)] * The server now records why a Lightning send failed and reports the reason to the client. Bark logs it for now. \[[2572](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2572)] * `bark-rest` now serves a vendored Swagger UI, and the release bumps rustls and webpki for recent RUSTSEC advisories. \[[2642](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2642)] \[[2655](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2655)] * The server crate now builds only on 64-bit targets. \[[2587](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2587)] [Full release notes in the repo](https://gitlab.com/ark-bitcoin/bark/-/blob/master/CHANGELOG.md?ref_type=heads). **11 September 2026** 0.7.1 ![A hand-drawn row of keys stretching into the distance, the first few crossed out and one distant key picked out in blue, representing a wallet recovery that scans further for its VTXOs](https://mintcdn.com/second-0659a37d/Ke4swV1QmVyWHnEz/images/recovery-key-corridor-light.svg?fit=max\&auto=format\&n=Ke4swV1QmVyWHnEz\&q=85\&s=34532e4842dfdce7c1b165153bea1134) > [!WARNING] > > **Breaking changes** > > * **[Bitcoin Core v31](#captaind-requires-bitcoin-core-v31):** captaind will not start on older nodes. > * **[VTXO import](#vtxo-import-checks-the-server-before-storing):** arguments, errors and expiry handling changed. > * **[SDK recovery](#recovery-scans-further-for-missing-vtxos):** new `Config` field, and `recover_vtxos` takes an override. ### Recovery scans further for missing VTXOs When a wallet is restored from its mnemonic, Bark now checks 250 unused keys in a row before it stops looking for VTXOs, up from 50, so a restore that used to stop too early now reaches VTXOs further along. `bark create --gap-limit` raises the limit further for a wallet that needs it. A restored wallet also no longer counts VTXOs it had already spent as spendable balance. In the SDK, `Config` gained `vtxo_key_gap_limit` and `Wallet::recover_vtxos` takes a gap limit override. \[[2510](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2510)] \[[2531](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2531)] ### VTXO import checks the server before storing Importing a VTXO now asks the server whether it is still unspent. An already-spent VTXO is recorded as spent instead of counting as spendable balance, one still in flight (neither spendable nor spent yet) is refused, and an expired one is no longer refused. In the SDK, `Wallet::import_vtxo` now takes `ImportVtxoArgs` and returns a typed error. \[[2510](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2510)] ### One emergency exit no longer forces other Lightning receives on-chain The server now adds a checkpoint to each Lightning receive it issues from its shared VTXO pool, so one user's emergency exit no longer pulls other users' Lightning receives on-chain with it. The cost is one more transaction in the exit chain, so an emergency exit of a Lightning receive now pays a little more in fees. \[[2528](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2528)] ### `captaind` requires Bitcoin Core v31 `captaind` now requires Bitcoin Core v31 and refuses to start on an older node. It uses v31's chunk feerate, the rate Bitcoin Core would mine a transaction at, to report on stuck server transactions in `captaind rpc nursery list` and the missed-target warning, so operators can distinguish between an underpaying transaction and one waiting behind a full mempool. \[[2526](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2526)] ### Additional improvements * Apps using delegated refreshes now lock the handed-over VTXOs once they see the server has built the round, so they no longer show as spendable in the meantime. \[[2516](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2516)] * An incoming Ark payment that repeats a VTXO the wallet already holds no longer marks it spendable again. \[[2531](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2531)] * Bark no longer assumes a transaction it just broadcast has dropped from the mempool when syncing through Esplora, which could leave a board or an exit stuck. \[[2505](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2505)] * Watchmand no longer keeps retrying a transaction the network will not relay when the VTXO behind it is too small to be worth it, ending a recurring warning. \[[2528](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2528)] * The `--vtxo` flag of `bark dev vtxo import` is now deprecated: pass the VTXOs as bare arguments instead. \[[2524](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2524)] * Operators should raise `fixed_additional_vb` from 212 to 221 in their captaind config: the default now prices the three-output transaction the server builds, and upgrading does not change it. \[[2521](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2521)] * The server now records every Lightning HTLC VTXO in its own table for a later release to use. Existing deployments should run `captaind data backfill-htlc-vtxos` once after upgrading. \[[2495](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2495)] * When Bark cannot fetch the transaction a VTXO is anchored to, the error now includes the underlying cause rather than only the top-line message. \[[2532](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2532)] * Nursery log lines now say which kind of transaction they are about (`round`, `offboard`, `vtxopool` or `internal`), so operators can filter by kind. \[[2543](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2543)] * The VTXO pool expiry histogram now extends to 1008 blocks. The new buckets are additive and need no dashboard changes. \[[2533](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2533)] [Full release notes in the repo](https://gitlab.com/ark-bitcoin/bark/-/blob/master/CHANGELOG.md?ref_type=heads). **7 September 2026** 0.7.0 ![A hand-drawn server rack with a riveted armour plate being bolted onto its side, representing a release that hardens Bark and the Ark server](https://mintcdn.com/second-0659a37d/p2LUwJmKpSU8Kefm/images/server-hardening-plate-light.svg?fit=max\&auto=format\&n=p2LUwJmKpSU8Kefm\&q=85\&s=1b9e91caa5c222f127818ad0974f530f) This is mainly a server hardening update, focusing on security and reliability. Thanks to [Project Loupe](https://x.com/ProjectLoupe) and [Greg Sanders](https://x.com/theinstagibbs) for the responsible disclosures behind several of the updates. > [!WARNING] > > **Breaking changes** > > * **[Watchmand](#watchmand-runs-as-a-separate-process):** must run as a separate process. > * **[Nursery config](#transaction-nursery-guarantees-follow-up):** one new required key, two removed. > * **[SDK](#recovery-scan-reports-its-outcome):** recovery callback, VTXO unlock, new trait methods, more signatures. > * **[Cancel Lightning receive](#cancel-lightning-receive-disabled):** RPC disabled. ### Ark payments to an offline receiver are no longer lost Bark no longer drops Ark payments that arrive and expire while the receiver is offline, instead keeping the received VTXO and refreshing it once the wallet comes back online. The server also no longer accepts expired VTXOs as inputs to an Ark payment, but will continue to accept them in refreshes, offboards, or Lightning sends. \[[2501](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2501)] \[[2500](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2500)] ### Stricter checks before forfeiting in a round Bark now validates the new VTXOs in a round before it hands over its forfeit signatures, so a forged VTXO is caught early. It also refuses a round that would not leave enough time for an emergency exit. On mainnet, Bark now refuses servers whose advertised parameters would make an exit unsafe. \[[2410](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2410)] \[[2494](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2494)] \[[2492](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2492)] ### Safer Lightning receives Bark now checks the tree behind an incoming Lightning payment's HTLC VTXOs against the server's advertised parameters before it reveals the preimage. A claim no longer fails because a new block was mined during a retry, and a claim that fails after the preimage is revealed now backs off before retrying. \[[2441](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2441)] \[[2469](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2469)] ### Sends to undeliverable Ark addresses fail fast A send to an Ark address Bark cannot deliver to now fails immediately, before it locks any VTXOs. An address that lists no delivery mechanism is a deliberate choice by the receiver, so Bark now completes that send without delivery instead of rejecting it. \[[2468](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2468)] ### Malformed offboard responses no longer stall the wallet Bark now rejects an offboard response with the wrong number of nonces before it writes a checkpoint, so a bad response from the server no longer stalls on-chain and round syncing. In `ark-lib`, the offboard forfeit signing functions now return a `Result`. \[[2470](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2470)] ### Recovery scan reports its outcome The `on_recovery_finished` callback now receives a `RecoveryStatus` of not run, failed, or completed, and fires exactly once per wallet open, so a wallet app can flag a failed scan to the user. A recovery also no longer makes the next mailbox sync skip unread payments and Lightning notifications. \[[2506](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2506)] \[[2455](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2455)] ### Retry-safe VTXO locks A retried operation no longer releases a VTXO lock that another operation has taken in the meantime: `Wallet::unlock_vtxos` now takes the lock holder and ignores a mismatch. For custom persisters, this adds a required `release_vtxo_lock` method, and every backend now treats a repeated state transition that has already been applied as a success. \[[2475](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2475)] \[[2440](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2440)] ### Pending board balance excludes unbroadcast boards A board funded by someone else's transaction, such as a Payjoin board, now counts toward the pending balance only once that transaction is seen in the mempool or in a block. If the funding input turns out to be spent by a confirmed transaction, Bark now tears the board down instead of trying to broadcast it. \[[2438](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2438)] ### Barkd wallet deletion is safe to retry Barkd no longer refuses to create a new wallet after deleting the previous one. Deletion now waits for the wallet's background tasks to stop before wiping the data directory, and a retried deletion completes an interrupted one. The response now includes the deleted wallet's fingerprint, and the SDK gains `Wallet::stop_daemon_wait`. \[[2415](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2415)] ### List pending round participations The new `bark round list` command shows the round participations still pending after an interrupted refresh, with the IDs that `bark round cancel` takes, and works without contacting the server. Pending round info now also reports each participation's lifecycle state and, for a delegated participation, the block height it is waiting for. \[[2487](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2487)] ### Emergency exit frees replaced fee-bump inputs When a fee-bump transaction in an emergency exit is replaced, its inputs now return to coin selection immediately instead of waiting out the on-chain wallet's grace period. Custom on-chain wallet implementations must add an `evict_tx` method. \[[2508](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2508)] ### Watchmand runs as a separate process Every deployment must now run `watchmand` as a separate process alongside `captaind`, so a `captaind` outage no longer takes the watchman down. The `captaind` process now refuses to start if its config contains a `[watchman]` section or `watchman_min_balance`, and no longer tops up the watchman wallet. The `trigger_sweep` RPC has moved to `watchmand`. \[[2259](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2259)] ### Transaction nursery guarantees follow-up The server now rebroadcasts its transactions until they confirm and always keeps a change output for fee-bumping. When one misses the new required `nursery_confirm_target_blocks` target, the server warns on every block, and the operator can abandon it with `captaind rpc nursery`. The `transaction_rebroadcast_interval` and `txindex_check_interval` keys are gone. Transactions stuck before the upgrade are not picked up. \[[2478](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2478)] \[[2305](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2305)] \[[2502](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2502)] ### Per-action amount limits New `max_*_amount` config options cap or switch off boards, offboards, Ark sends, round participations, and Lightning sends individually. Unset means no limit, and zero disables the operation. The offboard limit may not exceed the Ark send limit. Set `max_round_amount` with care: clients cannot see it, so a balance above the limit cannot be refreshed. \[[2426](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2426)] \[[2446](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2446)] ### Cancel Lightning receive disabled The RPC for cancelling a pending Lightning receive is now disabled and always returns an error, which shrinks the Lightning attack surface. It had no known users. Pending receives are still cleared by the server's own timeouts, as before. \[[2456](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2456)] ### Release builds via nix Release binaries for `bark`, `barkd`, and the server are now built with nix from pinned inputs, so the exact build can be re-run. New static `linux-x86_64-musl` builds of `bark` and `barkd` are available, the ARM builds are now static too, and the release `barkd` binaries now include the Swagger UI. \[[2413](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2413)] ### Additional improvements * A broad server hardening pass closed several issues that a misbehaving client could trigger. * Two concurrent registrations of overlapping VTXO chains no longer hit a deadlock that failed one of them. \[[2488](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2488)] * Mailbox messages are now stand-alone records, so a pending Lightning receive reads correctly for as long as it stays in the mailbox. \[[2423](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2423)] * VTXO pool issuance now runs after sync completes, closing a race that left the pool unreplenished. \[[2448](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2448)] * The server now detects accepted Lightning receives faster. \[[2484](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2484)] * VTXO pool telemetry now uses Prometheus histogram-style gauges with fixed buckets. The old `vtxo_pool_*_gauge` metric names are gone, so dashboards need updating. \[[2447](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2447)] * The server now records protocol fees per operation type and ships Postgres views for telemetry. The fees charged have not changed. \[[2192](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2192)] \[[2275](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2275)] * Mailbox blinding is now fallible: `MailboxIdentifier::to_blinded` and `from_blinded` now return a `Result` instead of panicking on invalid input. \[[2456](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2456)] * Decoding a length-prefixed vector of a zero-sized type now returns an error instead of panicking, as reported by Project Loupe. \[[2466](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2466)] * The exit driver no longer panics when a chain-tip lookup for its trace log fails. \[[2464](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2464)] * A chain-source error while checking a board's funding input for a conflict now parks the board for retry instead of failing it. \[[2454](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2454)] * The board salvage trigger now uses the wallet app's own exit margin instead of the server's confirmation requirement. \[[2490](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2490)] * For anyone embedding `bark-rest`, `RestServer::start` now takes an `Arc` and the builder hooks now take a `Box` instead of an `Arc`. \[[2439](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2439)] * The wallet config field `vtxo_refresh_expiry_threshold` is now a `BlockDelta`. \[[2479](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2479)] * The `bip321` crate now puts its Lightning dependencies behind a `lightning` feature that is on by default, so consumers that only need URI parsing can opt out. \[[2476](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2476)] * The bark crates now build from a fresh lockfile again, on the stable `secp256k1-musig` 0.33.0 after the betas were yanked. Wire and nonce formats are unchanged. \[[2474](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2474)] [Full release notes in the repo](https://gitlab.com/ark-bitcoin/bark/-/blob/master/CHANGELOG.md?ref_type=heads). *** **25 August 2026** 0.6.2 ![A hand-drawn shape-sorter box with one hole that a lightning bolt, a pyramid, and a ball all fit through, representing one payment call that pays any destination](https://mintcdn.com/second-0659a37d/a_FRL1ohFYqasQlv/images/shape-sorter-light.svg?fit=max\&auto=format\&n=a_FRL1ohFYqasQlv\&q=85\&s=a841fd4492b5ef84a16cd867a6f66f15) Thanks to the [bitcoin Red Team](https://opensats.org/funds/red) and [Project Loupe](https://www.projectloupe.org/) for the responsible disclosures behind several of this release's fixes. > [!WARNING] > > **Breaking changes** > > * **[Version floor](#a-new-protocol-version-floor):** Clients on bark 0.4.0 or older can no longer connect, and bark refuses servers on protocol versions below 4. > * **[Watchman config](#watchman-reactions-and-sweeps-run-on-separate-schedules):** `watchman.process_interval` is replaced by the required `reaction_interval` and `sweep_interval`. The server won't start without them. > * **[Barkd auth](#barkd-refuses-unauthenticated-remote-access):** `BARKD_NO_AUTH` is no longer read, and `--no-auth` refuses to start on a non-loopback bind. > * **[Exit errors](#estimate-emergency-exit-fees):** The dust-limit exit error's `vtxo` field is now the VTXO ID, and the sub-dust value moved to `amount`. ### A unified payment API Earlier releases enabled Bark to request payment over any rail with one BIP 321 QR code. This release completes the paying side: the new `Wallet::send_payment` pays whatever string a user pastes, an Ark or on-chain address, any Lightning destination, or a multi-rail BIP 321 URI, all from the same off-chain balance. When a destination can be paid more than one way, Bark lists each option with a fee estimate, and its default pick prefers Ark, then Lightning, then on-chain. \[[1998](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1998)] \[[2422](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2422)] ### Better high-frequency payment support Frequent successive payments used to build long chains of change, quickly hitting the server's depth limit and forcing a disruptive refresh of the whole wallet. Change larger than the amount paid now splits in two across Ark, Lightning, and on-chain sends, keeping exit depth manageable. Input selection skips VTXOs at the limit instead of failing the payment. \[[2322](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2322)] \[[2397](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2397)] ### Payjoin boards enabled The new `Wallet::board_psbt` co-signs a board funded by a transaction someone else builds and broadcasts, enabling Payjoin boarding: a wallet app that supports Payjoin can fund the Ark board directly, saving the user an on-chain transaction. It also opens up some interesting interoperability with Cashu mints (keep an eye on the blog). \[[2419](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2419)] ### Stricter validation of server responses Bark now verifies more of what the server sends before bitcoin moves. Round results are checked for the expected server key, exit delta, and a safe expiry before Bark forfeits its inputs; incoming payments must be final, self-custodial VTXOs from the right server; and a BOLT12 invoice fetched by the server must match the authorized amount. \[[2384](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2384)] \[[2390](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2390)] \[[2398](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2398)] ### Estimate emergency exit fees You can now estimate what an emergency exit will cost before committing to one, and whether the wallet's confirmed on-chain balance covers the up-front broadcast fees (the claim fee comes out of the recovered value). The estimate is available across the SDK, CLI, and REST API. \[[2218](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2218)] ### Smaller downloads for mobile and wasm clients The server now compresses gRPC responses with zstd for clients that advertise support, which Bark now does. Batched mailbox reads, which matter most to a wallet app restoring or syncing, shrink by roughly half. It works over gRPC-Web too, so wasm clients benefit, and older clients are unaffected. \[[2310](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2310)] ### Sign messages with an Ark address A wallet app can now sign a message with the key behind one of its Ark addresses, and anyone can verify the signature statelessly against the address or public key, no wallet needed. That gives mobile-wallet backends a way to authenticate requests from the clients they serve. \[[2323](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2323)] ### Lightning receives no longer stall on an aging VTXO pool The server draws on its VTXO pool to fund Lightning receives, and a pool of aging VTXOs could read as empty, failing inbound payments for hours until the pool refilled. Selection no longer over-filters near-expiry VTXOs, and issuance now runs on every new block, so the `vtxopool.issue_interval` config option is gone (a leftover key is ignored). \[[2435](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2435)] \[[2437](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2437)] ### Watchman reactions and sweeps run on separate schedules Time-critical watchman work, like progressing exits and claiming before a counterparty's timelock matures, now runs on its own `reaction_interval`, separate from deadline-free sweeping on `sweep_interval`. Both keys are required: `captaind` and `watchmand` will not start without them, though a leftover `process_interval` is ignored. The new `captaind check-config` command validates a config file before you restart. \[[2326](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2326)] \[[2427](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2427)] ### ZMQ block notifications A Barkd running against its own bitcoind can now set `bitcoind_zmq_address` to hear about new blocks the moment they arrive, instead of waiting out the poll interval. A new block triggers a daemon sync pass, so confirmations that gate boards and exits are picked up right away. Polling stays as the default and the fallback. \[[2356](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2356)] ### Barkd refuses unauthenticated remote access Running Barkd unauthenticated on an address other machines can reach hands the wallet to anyone on that network. Barkd now refuses to start that way: the `BARKD_NO_AUTH` environment variable is gone, `--no-auth` works only on a loopback bind, and deliberate remote exposure takes the explicit `--dangerously-allow-remote-no-auth`. Auth tokens are also compared in constant time. \[[2361](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2361)] \[[2367](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2367)] ### A new protocol version floor The legacy per-VTXO fee calculations are gone, raising the minimum protocol version to 4: clients on bark 0.4.0 or older can no longer connect. Clients on 0.5.0 still connect, but remain unable to refresh or use Lightning since 0.6.0. Regardless, please update to the latest version of Bark to get the latest security fixes. \[[2373](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2373)] ### Additional improvements * The server no longer stops syncing blocks when an error interrupts a reorg. \[[2359](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2359)] * An emergency exit no longer deadlocks when successive fee-bumps race the on-chain wallet's sync: it rebuilds the fee-bump and self-heals. \[[2387](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2387)] * A board funded by someone else's transaction is failed once a funding input is double-spent by a confirmed transaction, instead of staying pending forever. \[[2419](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2419)] * Check an outgoing Lightning payment with `GET /lightning/sends/{identifier}`. Send responses now return the payment hash to query with. \[[2324](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2324)] * Only one Barkd can run per data directory, a failed wallet create no longer wipes a running Barkd's files, and `--port 0` is rejected. \[[2289](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2289)] \[[2414](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2414)] * The debug log drops full-block dumps and gRPC noise, and now follows the stderr level. Pass `--verbose` for trace detail. \[[2417](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2417)] \[[2418](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2418)] \[[2429](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2429)] * New `--logfile` and `--no-logfile` options on `bark` and `barkd` control where the debug log goes. \[[2436](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2436)] * Bark now requires `txindex=1` on a bitcoind chain source at startup, instead of failing later on the first call that needs it. \[[2375](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2375)] * New nix build definitions produce reproducible binaries for seven platforms, verified bit-identical across NixOS, Ubuntu, and Fedora. \[[2124](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2124)] * The server creates its data directory and mnemonic file owner-only, and warns at startup when existing files are readable by others. \[[2391](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2391)] * The bitcoind RPC password no longer appears in `bark config` output or debug logs. \[[2392](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2392)] * Lightning preimages no longer appear in the server's structured logs. Correlate on the payment hash instead. \[[2434](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2434)] * Various further server security and hardening fixes. \[[2404](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2404)] \[[2409](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2409)] * Servers can announce their terms of service with the new `tos_link` config option, surfaced to clients in `ArkInfo`. \[[2396](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2396)] * The `ArkInfo` field `vtxo_expiry_delta` is renamed to `vtxo_lifetime`. Both names interoperate for now, and the old one goes away in a future release. \[[2385](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2385)] [Full release notes in the repo](https://gitlab.com/ark-bitcoin/bark/-/blob/master/CHANGELOG.md?ref_type=heads). *** **8 August 2026** 0.6.1 ### Fee disagreements no longer fail on-chain sends and offboards An on-chain send or offboard no longer fails because the server priced the fee differently from the wallet app. The server now calculates ppm-expiry fees in the same VTXO order the wallet app uses. It also accepts a payment whose fee comes out a few sats high, as happens when the wallet app priced it against a different chain tip. \[[2372](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2372)] ### Delegated refreshes scheduled before 0.6.0 now complete The hash-lock script change in 0.6.0 left delegated refreshes scheduled before the upgrade unable to finish. The wallet app and server now handle rounds built with the old scripts, so those refreshes complete as scheduled. \[[2378](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2378)] *** **5 August 2026** 0.6.0 ![A hand-drawn open-ended spanner, representing a maintenance release every client needs to pick up](https://mintcdn.com/second-0659a37d/hu7QIB0w-Esfpufo/images/spanner-light.svg?fit=max\&auto=format\&n=hu7QIB0w-Esfpufo\&q=85\&s=f522aa25b543e0ce921b6d33222cff05) Two releases in two days...we hope you'll understand given the emerging security environment in bitcoin. This release has some breaking changes you're going to want to pay attention to. Please update as soon as possible. And thanks to [Philipp Hoenisch](https://x.com/bonomat) of Lendasat for the report behind a fix. > [!WARNING] > > **Breaking changes** > > * **[Refreshes and Lightning payments](#refreshes-and-lightning-payments-need-an-updated-client):** Clients on 0.5.0 or older can no longer refresh VTXOs or send and receive Lightning. Update to 0.6.0 to restore service for your users. > * **Hash-lock policy types:** The old policy and clause types now carry a `_v0` suffix, and the new versions take their former names. > * **[Barkd request models](#barkd-catches-up-with-the-cli):** `CreateWalletRequest` gains `force` and `LightningInvoiceRequest` gains `token`. > * **Server config:** In `[vtxopool]`, rename `max_vtxo_arkoor_depth` to `max_vtxo_exit_depth` or `captaind` won't start. ### Refreshes and Lightning payments need an updated client Lightning HTLC and hArk round scripts now check that the preimage is 32 bytes, matching Lightning's own on-chain check. That bumps the protocol version, so a 0.6.0 server turns away refreshes and Lightning payments from anything older. We've already reached out to all integrators we're aware of, but if we haven't been in touch, you'll need to update your wallet app. Existing VTXOs keep validating against their original scripts. \[[2358](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2358)] ### Depth limits no longer strand Lightning payments Lightning claims and payment revocations are now exempt from the limit on how deep a VTXO sits in its exit chain, and the pool stops the chain growing. Previously a receive could land too deep to claim, leaving settled payments unclaimable and failed ones unrevocable, with an emergency exit the only way out. \[[2331](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2331)] ### Freshly signed transactions survive a sync On-chain transactions now get a 30-second grace period after signing, so a sync can't treat one as dropped before it reaches the mempool. Previously a board could be evicted in that window, handing its inputs back to coin selection and double-spending your own transaction. Genuinely dropped transactions are still evicted, one sync later. \[[2353](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2353)] ### Cap the size of a Lightning receive Operators can now cap a single Lightning receive with `max_ln_receive_amount`, which is a useful lever while an update rolls out. It's checked when the invoice is issued, not at claim time, so nobody is left holding a payment they can't claim. Unset by default. \[[2358](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2358)] ### Barkd catches up with the CLI Two new request fields bring Barkd in line with the CLI. A `token` on invoice generation lets a fresh wallet app receive Lightning against a server that requires one. A `force` flag on wallet create clears a datadir that still holds files, deleting the old wallet with it. \[[2325](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2325)] [Full release notes in the repo](https://gitlab.com/ark-bitcoin/bark/-/blob/master/CHANGELOG.md?ref_type=heads). *** **4 August 2026** 0.5.0 ![A hand-drawn server rack beaming a stream of colorful doodles across to a smartphone, representing a wallet restored from its mnemonic](https://mintcdn.com/second-0659a37d/4xPNFXW16YzoUVX0/images/server-beaming-phone-light.svg?fit=max\&auto=format\&n=4xPNFXW16YzoUVX0\&q=85\&s=d62c8778ebf63e6eb1230d22d4c65662) > [!WARNING] > > **Breaking changes** > > * **Boarding requires 0.5.0:** Ark servers on 0.5.0 refuse boards from older clients. Mainnet server configs must also add `require_board_funding_tx = true` or `captaind` won't start. > * **Mnemonic endpoint:** barkd's `GET /api/v1/wallet/mnemonic` returns 404 unless started with `--expose-mnemonic`. > * **[Lightning receives](#deliver-lightning-receives-to-any-ark-address):** `LightningReceive` gains a public `claim_destination` field. ### Restore a wallet from its mnemonic A Bark wallet's off-chain balance can now be restored from its mnemonic. The wallet posts the IDs of VTXOs it creates or receives to a seed-derived mailbox on the server; a restore re-derives that mailbox, fetches the VTXOs back, and validates each one before accepting it. This has been one of the most demanded features, and it complements local, trustless backups. Existing wallets are covered from their first sync on 0.5.0. \[[2193](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2193)] \[[2309](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2309)] ### Deliver Lightning receives to any Ark address A wallet can now claim an incoming Lightning payment to another wallet's Ark address, letting the recipient get paid over Lightning while offline. The forwarder never has custody and cannot redirect the payment, but until it delivers, no one else can claim it. That unlocks non-custodial Lightning address servers. Thanks to external contributor [Ben Carman](https://x.com/benthecarman) for this work. \[[2146](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2146)] ### Schedule a refresh ahead of time A delegated refresh previously joined the next round; it can now be scheduled for a future block height. Scheduling ahead is cheaper: the liquidity fee for a refresh (not its on-chain cost) falls as a VTXO nears expiry, and the server prices it at the scheduled height. The refresh joins the first round after that height. \[[2304](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2304)] ### More reliable Lightning receives A Lightning receive no longer fails when the wallet proves ownership with a VTXO whose signed transaction chain the server has not received yet. The receive now goes through; spent or banned VTXOs are still rejected. \[[2307](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2307)] ### Security improvements Bitcoin's security environment is heating up, so this release puts a heavy focus on hardening across both the server and the wallet. We're grateful to [@0xaudron](https://x.com/0xaudron), [@benthecarman](https://x.com/benthecarman) and [@theinstagibbs](https://x.com/theinstagibbs) for the testing behind several of this release's security fixes. [Full release notes in the repo](https://gitlab.com/ark-bitcoin/bark/-/blob/master/CHANGELOG.md?ref_type=heads). *** **20 July 2026** 0.4.0 ![A payment card showing a single QR code with chain, Lightning, and Ark icons beneath it, representing one payment request covering on-chain, Lightning, and Ark](https://mintcdn.com/second-0659a37d/nxUUZpMRXA-Zuljp/images/bip321-qr-card-light.svg?fit=max\&auto=format\&n=nxUUZpMRXA-Zuljp\&q=85\&s=37e4a8f317806c857239ae8d30632c9a) > [!WARNING] > > **Breaking changes** > > * **[On-chain wallet integration](#one-trait-for-on-chain-wallets):** a single `OnchainWalletTrait` replaces the previous trait set, and board and daemon calls drop their `onchain` argument. > * **[Exit APIs](#cancel-an-emergency-exit-before-it-commits):** `ExitState` and `ExitError` gain variants, and status listings split into live and finished. > * **[Custom persisters](#crash-safe-offboards-and-on-chain-sends):** `BarkPersister` gains required methods; the pending-offboard methods are removed. > * **[Crash-safe Lightning receives](#crash-safe-lightning-receives):** the receive-status API is reshaped and the receive token moves to invoice generation. ### One payment request for every rail Bark can now build a single BIP 321 payment request that a payer's wallet app can pay over whichever rail it supports. One string or QR code always carries a fresh Ark address, plus a BOLT11 invoice when you give an amount and an on-chain address when you ask for one. The new `POST /api/v1/wallet/bip321` endpoint can also return the URI upper-cased, which packs into a smaller QR code. \[[2242](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2242)] ### Estimate fees for on-chain payments A new `POST /api/v1/fees/offboard` endpoint quotes the cost of an on-chain payment (an offboard) funded by a chosen set of VTXOs before you commit. Each VTXO is spent in full to the destination address, and the response reports both the gross value of the selected VTXOs and the net amount that lands on-chain after fees. \[[2250](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2250)] ### Wallet notifications without a websocket Clients that can't hold a persistent websocket can now long-poll for wallet events. The new `GET /api/v1/notifications/wait` endpoint holds the request open until a notification arrives and returns a resume timestamp, so polling continues without gaps or busy loops. \[[1960](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1960)] ### Control which VTXOs a payment spends A new `InputSelection` builder lets SDK integrators steer which VTXOs a payment spends: limit how many inputs it uses, exclude specific VTXOs, and cover a fee that depends on the chosen set. On-chain sends now use it to honor the server's offboard-input limit. \[[2249](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2249)] ### One trait for on-chain wallets Integrating your own on-chain wallet is now one trait instead of eleven: `OnchainWalletTrait` replaces the patchwork of single-method traits. The wallet supplied at open also lives inside `Wallet` from then on, so board and daemon calls no longer thread it through every signature. \[[2121](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2121)] ### Wallet files locked down to user The bark CLI and barkd now create a wallet's data directory, mnemonic, and database readable only by the operating-system user that created it, so other accounts on a shared machine can't read your mnemonic. Existing wallets are untouched: Bark warns on open when their files are readable by others, rather than changing permissions itself. \[[2194](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2194)] ### Recovery mailbox posts are authenticated Posting recovery VTXO IDs to the server now carries a signed proof that you own the mailbox, verified the same way as reads, so a third party can no longer write entries into a mailbox that isn't theirs. The check stays optional for now so older clients keep working. \[[2234](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2234)] ### Filter wallet history server-side The `GET /api/v1/history` endpoint now takes optional `type` and `value` parameters identifying a payment method. Supply both and the response includes only movements involving that method, for example every payment sent to one address, so integrators no longer fetch the whole history and filter it client-side. \[[2227](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2227)] ### Crash-safe offboards and on-chain sends Offboards and on-chain sends now run as checkpointed wallet actions, so an interrupted offboard resumes on the next sync instead of being lost. A wallet that missed the server's response recovers the broadcast transaction from chain, retries with a fresh session, or cancels and releases the bitcoin. That completes the set: every payment operation now survives a crash. \[[2085](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2085)] ### Crash-safe Lightning receives An incoming Lightning payment now survives a restart: receives run through the same checkpointed machinery as Ark sends and resume where they left off, and a settled receive is stored permanently with its preimage. The receive-status API is reshaped around this lifecycle, and its token now belongs at invoice generation, not at claim. \[[2148](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2148)] ### Boarding rides out crashes and double-spends Boarding is now driven as a checkpointed wallet action, so a board survives a crash, resumes on the next sync, and re-broadcasts its funding transaction if it drops from the mempool. If that transaction is double-spent by a confirmed conflict, the board is now marked failed instead of being retried forever. \[[2236](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2236)] \[[2263](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2263)] ### Cancel an emergency exit before it commits An emergency exit can now be canceled while its final transaction is still unbroadcast. The VTXO stays spendable in Ark, and a fresh exit can be started later if needed. Cancellation is available across the SDK, the CLI (`bark exit cancel`), and the REST API. \[[2270](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2270)] ### No wasted fees on a doomed exit Before starting an emergency exit, Bark now checks the exit transactions for sub-dust or non-standard outputs that the bitcoin relay network would reject. A doomed exit is refused before any state is saved, so you don't burn fee-bump fees on transactions the network will never propagate. \[[2198](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2198)] ### Offboard sessions retry safely Offboard sessions are now safely retryable: a client that lost the response to `prepare_offboard` or `finish_offboard` can re-send it and get the same session replayed, instead of being blocked by its own VTXO locks. Abandoned sessions also expire rather than pinning VTXOs and wallet UTXOs, which could previously starve round funding. \[[2252](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2252)] \[[2085](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2085)] ### Ark server access token deprecated The Ark server doesn't enforce access tokens, so all of the access-token plumbing is now deprecated: the `--access-token` CLI flag, the SDK and REST create fields, and the `rpc.access_token` telemetry attribute. Everything still works for now, but configs, integrations, and dashboards relying on it should plan to drop it. \[[2171](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2171)] ### Additional improvements * A maintenance refresh where every due VTXO is unusable now returns an error instead of silently reporting success. \[[2246](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2246)] * Recovery VTXO IDs are now posted, and accepted by the server, in batches of at most 20 per request. \[[2267](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2267)] * The server now targets a 1-block confirmation for the round funding transaction. \[[2256](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2256)] * A new `bitcoin_address_blocklist_refresh_interval` server option sets how often the address blocklist file reloads (default 1 hour). \[[2169](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2169)] * A database race on the server can no longer mark VTXOs spent for a Lightning payment attempt whose success was never recorded. \[[2241](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2241)] * Removed the unused `GetFreshRounds` and `GetRound` gRPC methods. \[[2265](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2265)] * Manually refreshing specific VTXOs no longer pulls other refresh-due VTXOs into the same round; you get exactly the inputs you asked for. \[[2271](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2271)] * Exit status queries split into live and finished listings across the SDK and REST API; the old status endpoints are deprecated. \[[2270](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2270)] \[[2278](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2278)] * An exit fee-bump transaction's confirmation is now persisted, so exit status reads correctly immediately after a restart, even offline. \[[2299](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2299)] * Block-height arithmetic is hardened against overflow: exit status refresh no longer stalls on young chains, and confirmation counts survive reorg races. \[[2276](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2276)] * The server now validates CLN HTLC expiry heights instead of silently truncating them. \[[2276](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2276)] * Fixed `send_onchain` failing whenever the payment produced change. \[[2085](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2085)] [Full release notes in the repo](https://gitlab.com/ark-bitcoin/bark/-/blob/master/CHANGELOG.md?ref_type=heads). *** **26 June 2026** 0.3.0 ![A glowing EXIT sign frozen in a melting ice cube, representing bitcoin that stays spendable while queued for exit](https://mintcdn.com/second-0659a37d/7vz3-vtFbgxMiLvB/images/exit-ice-cube-light.svg?fit=max\&auto=format\&n=7vz3-vtFbgxMiLvB\&q=85\&s=0282e3651ac0cdf4861acd3863d02865) > [!WARNING] > > **Breaking changes** > > * **[Spend VTXOs queued for exit](#spend-vtxos-queued-for-exit):** Finish any in-progress mainnet exit on a non-sqlite backend before upgrading. > * **[Simpler wallet setup API](#simpler-wallet-setup-api):** the `Wallet::open` / `Wallet::create` variants are unified and `WalletSeed` / `Config` construction changed. > * **[Maintenance refresh survives a rejected VTXO](#maintenance-refresh-survives-a-rejected-vtxo):** `Wallet::maybe_schedule_maintenance_refresh` was removed. ### Spend VTXOs queued for exit Starting an emergency exit no longer freezes the bitcoin behind it. A VTXO stays spendable (you can refresh it, send it, or otherwise use it) right up until its exit transactions confirm on-chain, and if you spend it off-chain first the queued exit notices and cancels itself cleanly. This removes the old trap where queuing an exit locked up bitcoin you hadn't committed to moving on-chain yet. \[[2117](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2117)] ### Lightning receives protected from forced exit A Lightning receive can no longer be force-exited by the server. Bark now claims incoming payments behind a checkpoint that gives the server's watchman a place to stop, so a parent VTXO being dragged on-chain no longer takes your freshly claimed bitcoin with it. \[[2214](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2214)] ### Automatic recovery of force-exited VTXOs VTXOs that get pushed on-chain by the watchman progressing a shared exit tree or another exit dragging a parent on-chain no longer get stuck. Each sync now detects forced exits and automatically routes them into the claim flow. \[[2208](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2208)] ### Pay LNURL links Bark can now pay bech32 LNURL-pay links (`lnurl1…`) anywhere it already accepts a Lightning address, across the SDK, the CLI (`bark pay`), and the REST API. `Wallet::parse_payment_request` recognises them and resolves the link to an invoice before paying; as with Lightning addresses, an amount is required. \[[2176](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2176)] ### Maintenance refresh survives a rejected VTXO A single unusable input no longer sinks an entire maintenance refresh. Previously one VTXO the server rejected failed the whole atomic batch every run, so healthy VTXOs nearing expiry never refreshed and slid into exit-only territory. Maintenance now drops the rejected inputs and retries with the rest. Explicit developer-initiated refreshes still fail wholesale rather than dropping a caller's selection. \[[2217](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2217)] ### Simpler wallet setup API Opening and creating wallets is now a single, consistent flow. The many `Wallet::open*` and `Wallet::create*` variants collapse into one `Wallet::open` and one `Wallet::create` taking optional arguments, persistence picks a per-platform default (sqlite natively, IndexedDB on wasm), and seed construction splits into clearer `new_from_seed` and `new_from_mnemonic`. \[[2076](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2076)] ### Per-client server metrics Operators can now break server traffic down by client. Bark sends an `x-user-agent` header on every Ark RPC, and the server tags its gRPC metrics with the originating client, so board, Lightning, and round volume can be split per app on a dashboard. Integrators can set their own identifier via the new `Config.user_agent` field. \[[2170](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2170)] ### Additional improvements * Arkade addresses now produce a clear "Ark address is for different server" message instead of a generic failure. \[[2220](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2220)] * An Ark payment receive processed by several consumers at once is now recorded exactly once in wallet history instead of being double-counted. \[[2168](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2168)] * Streaming connections to the Ark server now stay open for up to an hour, fixing a disconnect every 10 minutes. \[[2213](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2213)] * REST VTXO listings regained their `exit_depth` field. \[[2225](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2225)] * The server now allows a 5-second leeway on mailbox auth expiry, so a client with minor clock skew is no longer rejected. \[[2199](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2199)] [Full release notes in the repo](https://gitlab.com/ark-bitcoin/bark/-/blob/master/CHANGELOG.md?ref_type=heads). *** **12 June 2026** 0.2.5 ### Security hardening This release fixes several privately disclosed vulnerabilities and hardens bark against malformed data from a misbehaving server: out-of-range VTXO output indices are now rejected, bad round data can no longer panic the wallet or bring down the daemon, and a failed save after round signing can no longer lead to nonce reuse. We're grateful to [instagibbs](https://x.com/theinstagibbs/status/2065776599727841413) and [Floppy](https://x.com/1440000bytes/status/2065704186982154704) for responsibly disclosing these in private. \[[2181](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2181)] \[[2182](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2182)] \[[2183](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2183)] ### Additional improvements * The server now correctly validates the user-provided HTLC expiry on Lightning receives. \[[2184](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2184)] * Several feerate fixes on the server: correct max-fee-rate clamping, no double update on fallback, and economical rather than conservative estimates. \[[2185](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2185)] [Full release notes in the repo](https://gitlab.com/ark-bitcoin/bark/-/blob/master/CHANGELOG.md?ref_type=heads). *** **11 June 2026** 0.2.4 ### Address blocklist Server operators can now block bitcoin moving to or from specific addresses. New `bitcoin_address_blocklist` options on `captaind` and `watchmand` point at a file of addresses loaded at startup; offboards to a blocked address, and boards funded from one, are rejected. \[[2155](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2155)] ### Run barkd as a web app barkd can now run without authentication via `--no-auth`, which, paired with the CORS setting, makes it practical to ship barkd inside a container as a web application. \[[2157](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2157)] ### Lightning receives stay retryable A Lightning receive whose claim fails, for example after transient server errors exhaust the retry budget, no longer triggers an automatic on-chain exit. The receive stays pending so it can be retried, and you can still fall back to an explicit on-chain exit with `Wallet::attempt_lightning_receive_exit` when you choose to. \[[2174](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2174)] ### Claimable exits visible in balance Emergency exits that have reached the claimable stage now count toward the reported pending-exit balance, so that bitcoin stays visible to users until it's actually spent on-chain. \[[2161](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2161)] ### Additional improvements * Added a `max_fee_rate` server option to guard against fee estimators returning absurd rates. \[[2154](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2154)] * Fixed multi-input offboards, including a fixup for older clients that got stuck. \[[2175](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2175)] * Oversized BOLT11 invoice descriptions are now rejected with `badarg` instead of logging a spurious error. \[[2164](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2164)] [Full release notes in the repo](https://gitlab.com/ark-bitcoin/bark/-/blob/master/CHANGELOG.md?ref_type=heads). *** **9 June 2026** 0.2.3 > [!WARNING] > > **Breaking changes** > > * **[Developer control over Lightning auto-exits](#developer-control-over-lightning-auto-exits):** the Lightning send state machine gains a `Progress::RevocationStuck` variant and `LightningSend` an `allow_exit_of_htlcs` field. ### Developer control over Lightning auto-exits Bark no longer force-exits the HTLC VTXOs behind an unfinished Lightning receive or a failed Lightning send on its own; that decision now sits with you. Stuck receives and sends stay put so they can be inspected and retried, with `Wallet::attempt_lightning_receive_exit` and `Wallet::allow_lightning_send_to_exit` to opt an individual payment into exiting on your terms. This follows a few cases where incoming payments were exited unnecessarily. \[[2152](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2152)] \[[2153](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2153)] ### Smoother exit claims Exit claim transactions are now standard v2 transactions rather than v3 (TRUC). The v3 form added restrictions to the claim process that weren't needed, and dropping it makes claiming an exit simpler and less constrained. \[[2149](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2149)] ### Additional improvements * Added a `sqlite-bundled` compile feature to build bark with SQLite bundled in. \[[2122](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2122)] [Full release notes in the repo](https://gitlab.com/ark-bitcoin/bark/-/blob/master/CHANGELOG.md?ref_type=heads). *** **4 June 2026** 0.2.2 ![A seatbelt buckled across a Lightning bolt, representing crash-safe Lightning sends](https://mintcdn.com/second-0659a37d/NQAV5SiWmpS7hL7Y/images/lightning-seatbelt-light.svg?fit=max\&auto=format\&n=NQAV5SiWmpS7hL7Y\&q=85\&s=9d987e2ac56a4ee445f9c52330904918) > [!WARNING] > > **Breaking changes** > > * **[Lightning send API](#crash-safe-lightning-sends):** `Wallet::check_lightning_payment` now takes a `wait` parameter and returns `LightningSendState`, and the pay methods take a new `wait` parameter. > * **[REST server construction](#wallet-mnemonic-backup-endpoint):** `RestServer::start` now takes a `ServerState` built via its builder. > * **[Onchain transactions JSON](#flag-internal-fee-bump-transactions):** `bark onchain transactions` output changes to the richer `WalletTxInfo` shape. ### Crash-safe Lightning sends Outgoing Lightning sends are now checkpointed, so a crash mid-send no longer leaves a payment stuck. Settled invoices are also recorded permanently, so the wallet can always confirm whether an invoice was already paid (`Wallet::is_invoice_paid`) without asking the server, and won't pay it twice. Paying now takes a `wait` flag: block until the send finishes, or return immediately and poll `Wallet::lightning_send_state`. \[[2062](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2062)] ### Wallet mnemonic backup endpoint A new `GET /api/v1/wallet/mnemonic` endpoint returns the wallet's BIP-39 mnemonic, so a wallet built on barkd can show it to the user to write down instead of making them dig it out of the filesystem. It's on by default; set `BARKD_EXPOSE_MNEMONIC=false` to disable it (the endpoint then returns 404). Embedders that mount bark-rest themselves now build the server with `ServerState::builder()`. \[[2114](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2114)] ### Resilient emergency exit progress One transaction failing to update its on-chain status no longer aborts the whole emergency exit run: the rest carry on and the next sync retries the failed one. Broader failures, like the chain source going unreachable, now come back as a clear `error` field in the exit progress response instead of an error printed to the console, so your app can spot a temporary problem and decide whether to retry. \[[2120](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2120)] ### Just-in-time refresh rounds Wallet maintenance now locks VTXOs only once a refresh round actually starts, so bitcoin stays spendable during the wait instead of being tied up early. Any stuck pending round is cleared first. \[[2113](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2113)] ### Flag internal fee-bump transactions Transaction listings now carry an `is_cpfp` flag marking the wallet's own fee-bump transactions, the internal children that speed up an emergency exit. Use it to hide or label them so they don't show up as confusing stray entries in a user's history. The flag is on `GET /api/v1/onchain/transactions`, and `bark onchain transactions` now returns the same richer shape. \[[2119](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2119)] ### Additional improvements * Swagger UI can now be compiled out via the `barkd-swagger-ui` feature, though it stays on by default. \[[2123](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2123)] * The bitcoind client (`bitcoind_async_client`) log level is now set to DEBUG. \[[2126](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2126)] [Full release notes in the repo](https://gitlab.com/ark-bitcoin/bark/-/blob/master/CHANGELOG.md?ref_type=heads). **29 May 2026** 0.2.1 ![An emergency exit door with a network port for plugging in your own wallet](https://mintcdn.com/second-0659a37d/n4ZI5y_rTKWaCO_M/images/emergency-exit-agnostic-light.svg?fit=max\&auto=format\&n=n4ZI5y_rTKWaCO_M\&q=85\&s=47a76f37a2447808a19abf1e80d7eb37) > [!WARNING] > > **Breaking changes** > > * **[Wallet-agnostic emergency exit](#wallet-agnostic-emergency-exit):** Exit status, error, and origin types are reshaped; integrators driving exits must adopt the new CPFP request flow. ### Wallet-agnostic emergency exit Third-party wallets can now drive an emergency exit with their own fee policy and signer, rather than relying on bark's bundled on-chain wallet. The exit state machine pauses at each fee-bumping (CPFP) boundary and hands control back to the caller, so emergency exit fits a wallet that already manages its own UTXOs and broadcasting. Integrators on bark's bundled BDK wallet keep the previous one-shot behaviour. Thanks to external contributor [Íñigo Aréjula Aísa](https://github.com/arejula27) for this work. \[[2032](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2032)] ### BIP 321 payment URI builder Building on the `bip321` crate from 0.2.0, Bark wallets can now assemble a single `bitcoin:` payment URI that bundles Ark, Lightning, and on-chain destinations into one request via `Wallet::bip321_uri`. A new `GetAddress` trait abstracts on-chain address generation, so you can plug in any on-chain wallet backend. \[[1997](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1997)] ### Additional improvements * Exit CPFP RBF no longer silently downgrades a freshly broadcast high-fee replacement to a stale lower-fee child returned by a lagging esplora-electrs indexer. \[[2032](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2032)] * Terminal log timestamps now include the UTC offset. \[[2083](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2083)] * Fixed a panic when an exit transaction failed to download. \[[2087](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2087)] * Corrected the OpenAPI spec for `GET /api/v1/history`, which previously advertised a trailing-slash path and broke generated clients. \[[2099](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2099)] [Full release notes in the repo](https://gitlab.com/ark-bitcoin/bark/-/blob/master/CHANGELOG.md?ref_type=heads). **27 May 2026** 0.2.0 ![Slim VTXO storage](https://mintcdn.com/second-0659a37d/Qt0tuwylqYkC_GbL/images/thin-vtxo-storage-light.svg?fit=max\&auto=format\&n=Qt0tuwylqYkC_GbL\&q=85\&s=48afd1ba8a20ee2709437f7095518586) > [!WARNING] > > **Breaking changes** > > * **[Slim VTXO storage](#slim-vtxo-storage):** `WalletVtxo` now holds `Vtxo`; a migration splits existing VTXO storage. > * **[Custom metadata on wallet history](#custom-metadata-on-wallet-history):** `Movement.metadata` changes type and the history endpoint moves. > * **[LockManager](#lockmanager-for-cross-process-locks):** wallet constructors gain a `lock_manager` parameter. > * **[Wallet API ergonomics](#wallet-api-ergonomics):** constructors return a `Wallet`, no longer an `Arc`. ### Slim VTXO storage Bark now keeps each VTXO in a slim "bare" form and loads only that for listings, balance, coin selection, and refresh checks: around 200 bytes per VTXO regardless of exit depth, a 20–100x cut in memory for wallets with many or deep VTXOs. `WalletVtxo` now holds `Vtxo`; reach for `Wallet::get_full_vtxo` when you need the full exit chain. The release ships a migration that splits existing storage into bare and genesis blobs. \[[2050](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2050)] ### Custom metadata on wallet history You can now attach custom JSON to any movement (refund references, customer or order IDs, internal notes) without maintaining a parallel store keyed by movement ID. Use `Wallet::update_history_metadata` or `POST /api/v1/history/{id}/metadata`, which take a JSON merge patch. The history listing also moves to `GET /api/v1/history`; the old path stays but is deprecated. \[[2079](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2079)] ### Split board flow for external wallets External wallets can now build and sign the board funding transaction themselves, then complete the board by submitting a pre-signed PSBT, which the server validates before broadcast. The flow splits into `board_funding_address` and `board_tx`. \[[1766](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1766)] ### Lightning receive claims retry before falling back to on-chain A transient failure during an inbound Lightning claim (a server restart or brief network blip) no longer forces an immediate on-chain exit of the HTLC VTXOs. Bark now retries the claim with backoff before falling back on-chain, with the budget set by `Config::lightning_receive_claim_retries`. Retrying is safe because the server's claim is idempotent. \[[2061](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2061)] ### Push notifications for Lightning send completion The server now notifies Bark clients via the mailbox when a Lightning send completes, success or failure, so the wallet handles the result without polling. \[[1889](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1889)] ### VTXO policy decoding hardened against malicious servers `Vtxo::decode` and `VtxoPolicy::decode` now reject out-of-range expiry and delta values that a malicious server could previously use to panic or overflow the client. The same bounds are exposed in `ark::vtxo::policy` for reuse at other deserialization boundaries, and the server applies the same checks at its gRPC and Postgres boundaries. \[[2046](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2046)] ### BIP 321 crate for bitcoin payment URIs A new `bip321` crate parses and serializes `bitcoin:` payment URIs for encoding payment instructions in clickable links and QR codes. It covers the standard payment parameters and exposes a pluggable `ExtensionHandler` trait for custom or wallet-specific parameters. \[[1921](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1921)] ### Graceful reconnection on idle stream timeouts Mailbox and round-event streams killed by a proxy idle timeout are now silently reconnected instead of treated as server failures, so the daemon no longer gives up on the mailbox after prolonged idle periods. \[[2040](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2040)] ### LockManager for cross-process locks A new `LockManager` provides named cross-process locks so two tasks or processes can't race on the same wallet. `lock_manager::platform_default` picks a sensible implementation per platform, including a Web Locks-backed manager that stops multiple browser tabs racing each other, and integrators can supply their own. Wallet constructors gain a `lock_manager` parameter, replacing the removed `pid-lock` feature. \[[2042](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2042)] ### Wallet API ergonomics `Wallet` now wraps an `Arc` internally, so it is cheap to clone and constructors return a `Wallet` directly rather than an `Arc`. A few public fields move to getter methods (`chain()`, `exit_mgr()`, `movements_mgr()`). \[[2052](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2052)] ### Additional improvements * Bark can fetch the current mempool feerate via a dedicated `GetOffboardFeeRate` RPC instead of re-fetching all of `ArkInfo`. \[[2029](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2029)] * `GET /onchain/transactions` now returns `onchain_fee_sat`, `balance_change_sat`, and `confirmation` alongside `txid` and `tx`. \[[2060](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/2060)] [Full release notes in the repo](https://gitlab.com/ark-bitcoin/bark/-/blob/master/CHANGELOG.md?ref_type=heads). **28 April 2026** 0.1.4 > [!WARNING] > > **Breaking changes** > > * **[Wallet owns its daemon handle](#wallet-owns-its-daemon-handle):** `Wallet::open` no longer returns the `DaemonHandle`. > * **[Lightning invoice descriptions](#lightning-invoice-descriptions):** `Wallet::bolt11_invoice` gains a `description` parameter. > * **[`RegisterVtxos` RPC renamed](#registervtxos-rpc-renamed):** `register_vtxos_with_server` is now `register_vtxo_transactions_with_server`. ### Websocket gateway for real-time notifications `bark-rest` exposes a websocket gateway for the `WalletNotification` stream introduced in 0.1.0. Clients request a short-lived ticket, then upgrade to a long-lived connection to receive notifications as they're emitted instead of polling REST endpoints. \[[1929](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1929)] ### Lightning invoice descriptions `bark lightning invoice` accepts a `--description` flag (and the REST endpoint a `description` field) that is embedded in the generated BOLT11 invoice as its memo, giving senders context about the payment. `Wallet::bolt11_invoice` gains a `description` parameter; pass `None` to preserve previous behaviour. \[[1950](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1950)] ### `bark address` works offline The server public key and mailbox public key are persisted in the local database after the first connection, so address generation no longer requires a live connection to the Ark server. \[[1868](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1868)] ### Wallet owns its daemon handle The `DaemonHandle` is now kept inside the `Wallet`, so the background daemon stops automatically when the wallet is dropped. `Wallet::stop_daemon` shuts it down explicitly, and the idempotent `Wallet::start_daemon` replaces the deprecated `run_daemon`. As a result, `Wallet::open` no longer returns the handle. \[[1971](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1971)], \[[1974](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1974)] ### `RegisterVtxos` RPC renamed The `RegisterVtxos` RPC is renamed to `RegisterVtxoTransactions`: the old name implied it created VTXOs server-side, but it only attaches signed transaction chains to existing ones. The old method path stays as a deprecated alias, and the Bark wrapper `register_vtxos_with_server` becomes `register_vtxo_transactions_with_server`. \[[1972](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1972)] ### Type-sharing crates compile without a transport backend `bark-wallet`, `bark-json`, `bark-rest`, and `bark-server-rpc` no longer implicitly select a transport backend, so consumers that just want the shared types can depend on them cleanly. Server-backed operations return a clear error pointing to the right feature flag when no transport is compiled in. \[[1872](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1872)] [Full release notes in the repo](https://gitlab.com/ark-bitcoin/bark/-/blob/master/CHANGELOG.md?ref_type=heads). **20 April 2026** 0.1.3 ![Wasm support](https://mintcdn.com/second-0659a37d/DAkXBVOix6pE6vb6/images/wasm-support.svg?fit=max\&auto=format\&n=DAkXBVOix6pE6vb6\&q=85\&s=4d70181f79d19273d7d9d39afae61480) ### IndexedDB persistence adaptor Bark ships a new `IndexedDb` `StorageAdaptor`, the missing piece for browser-based wallets. Combined with the Wasm compilation and gRPC-web support added in 0.1.0, integrators can now build Ark wallets that run entirely in the browser with persistent state. \[[1776](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1776)] ### Private server access tokens Bark can now connect to access-controlled Ark servers by sending a bearer token on every request. Set `server_access_token` in config, pass `--access-token` to `bark create`, or configure the `ark-access-token` HTTP header directly. You know what this means. \[[1927](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1927)] ### Cancel pending Lightning receives A new `Wallet::cancel_lightning_receive` method (and `bark lightning receive cancel` CLI command) cancels an in-flight inbound Lightning payment before it settles. \[[1824](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1824)] ### Additional improvements * Fee estimation methods now return an error when the requested amount falls outside the server's allowed range, instead of quoting a fee for an unachievable operation. \[[1932](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1932)] * New `bark watch` command subscribes to `WalletNotification` events and streams them to stdout, useful for debugging event-driven integrations. \[[1809](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1809)] [Full release notes in the repo](https://gitlab.com/ark-bitcoin/bark/-/blob/master/CHANGELOG.md?ref_type=heads). **4 April 2026** 0.1.0 ![A notification bell ringing](https://mintcdn.com/second-0659a37d/L_nNx3I4J5d_HUSW/images/2026-notifications.svg?fit=max\&auto=format\&n=L_nNx3I4J5d_HUSW\&q=85\&s=ff382b577eaea31d8677664682f8865f) You know we're getting closer to mainnet when the "beta" tag is dropped. This changelog update covers two releases—0.1.0-beta.9 and 0.1.0. > [!WARNING] > > **Breaking changes** > > This release includes several breaking changes: Barkd's REST API now requires auth tokens, CORS defaults to deny-all, the `StorageAdaptor` trait has renamed and new methods, arkoor attestation is mandatory, and Cargo feature flags have been restructured for Wasm support. See below for details. ### Event-driven notifications Bark replaces polling with push-based notifications. The wallet gains `Wallet::subscribe_notifications`, returning a stream of `WalletNotification` events (`MovementCreated` and `MovementUpdated`) so your app can react to balance changes in real time. \[[1793](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1793)], \[[1807](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1807)] On the server side, Lightning receive events and non-interactive round completions now flow through the mailbox system. Bark subscribes to the server mailbox stream for real-time arkoor delivery, and the daemon processes `RoundVtxos` messages to progress delegated round participations automatically. \[[1792](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1792)], \[[1779](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1779)], \[[1613](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1613)], \[[1845](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1845)] ### Fee estimation API New `/api/v1/fees/` endpoints let integrators estimate fees for all operation types—boarding, on-chain sends, offboards, and Lightning—and query current network feerates. Estimation also works when the wallet has no balance, returning a worst-case estimate so your app can display fees before the user has funded their wallet. \[[1787](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1787)], \[[1790](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1790)] ### Tor connectivity A new `socks5-proxy` feature routes traffic through a SOCKS5 proxy for Tor connectivity, covering Ark gRPC connections, Esplora HTTP calls, and bitcoind RPC. Local addresses automatically bypass the proxy. \[[1720](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1720)] ### Barkd security hardening Barkd now generates an auth token on first start and requires it for all REST API calls. Use `barkd secret refresh` to regenerate or set a custom token. Cross-origin requests are also denied by default—configure `--allowed-origins` or `BARKD_ALLOWED_ORIGINS` to whitelist specific origins for browser-based clients. \[[1756](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1756)], \[[1808](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1808)] ### HTLC preimage recovery from on-chain exits When a user performs an emergency exit of an HTLC VTXO, the preimage is revealed in the on-chain spending witness. The server now extracts this preimage and settles the corresponding CLN hold invoice automatically, preventing stuck invoices in Lightning-to-Ark payment flows. \[[1706](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1706)] ### Mandatory arkoor ownership attestation Arkoor and Lightning send co-sign requests now require a signed ownership attestation, preventing a malicious user from locking someone else's VTXOs. The previously optional `ArkoorCosignRequest.attestation` field is now required, and the deprecated `PaymentStatus` enum and `LightningPaymentResult` gRPC message have been removed. \[[1735](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1735)], \[[1834](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1834)] ### Wasm and browser support progress Bark now compiles to `wasm32-unknown-unknown`, which is a key step towards enabling browser-based Ark wallets. The server gains a gRPC-web layer so browser clients can connect directly without a proxy. \[[1709](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1709)], \[[1749](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1749)] `sqlite` is no longer a default feature—enable it explicitly if needed. The `onchain_bdk` feature has been renamed to `onchain-bdk`. Once persistence is solved, you'll be able to start shipping Bark wallets in browsers! ### StorageAdaptor trait changes `StorageAdaptor::query` is renamed to `query_sorted` and now requires an explicit sort key range. A new `get_all` method retrieves all unordered records in a partition. Custom `StorageAdaptor` implementations must be updated. \[[1786](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1786)] ### Additional improvements * VTXOs can now be retrieved in hex-serialized form via `GET /vtxos/{id}/encoded` for export and import between wallets. \[[1800](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1800)] * Movement lookup by payment method via `Wallet::history_by_payment_method()` and by Ark address via CLI `bark address lookup --address `. \[[1798](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1798)] * Wallet deletion via `DELETE /api/v1/wallet` stops background tasks and wipes the wallet directory. \[[1663](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1663)] * Configurable daemon sync intervals via `config.toml` or `BARK_` environment variables. \[[1810](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1810)] * `try_claim_all_lightning_receives` now returns the list of claimed receives instead of `()`. \[[1773](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1773)] * Offboard movements now remain pending until the transaction confirms on-chain, allowing recovery if the transaction fails to confirm. \[[1618](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1618)] * `ln status` split into `ln pay status` (outgoing) and `ln receive status` (incoming) with dedicated output types. \[[1466](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1466)] * Operators can ban/unban VTXOs by duration or block count via `captaind rpc ban`. \[[1733](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1733)] [Full release notes in the repo](https://gitlab.com/ark-bitcoin/bark/-/blob/master/CHANGELOG.md?ref_type=heads). **9 March 2026** 0.1.0-beta.8 ![Fees](https://mintcdn.com/second-0659a37d/Z3_V3Q8tQFA902bN/images/2026-fees.jpg?fit=max\&auto=format\&n=Z3_V3Q8tQFA902bN\&q=85\&s=4cc1bfd791556482b02ec6f0691f48f1) > [!WARNING] > > **Breaking changes** > > There are several breaking changes in this update, including fee schedule restructuring, removed legacy address delivery and gRPC methods, renamed balance and feerate fields, and Lightning receive nullability changes. See below for details. ### Fee schedule for all operations The Bark server now includes a granular fee configuration system that lets server operators define fee schedules using a combination of flat fees, percentage-based rates, and dynamic rates tied to VTXO lifetime. Second has also published the [fee schedule](/docs/learn/fees) for the Ark server we operate. And a new fee estimation API lets your app calculate and display fees before users commit to an operation. \[[1500](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1500)] ### Dynamic fees for on-chain sends and offboards Fees for on-chain sends and offboards now adjust based on current network conditions. The server communicates the applicable feerate via `ArkInfo` and accepts any feerate valid within a recent historical window, so clients aren't penalized for brief fluctuations between quote and submission. \[[1509](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1509)] ### Introducing the Watchman A new Watchman component unifies coin sweeping and forfeit handling into a single, block-synchronized process. It maintains a continuously updated view of all VTXOs that need monitoring and decides the appropriate action for each: wait, CPFP, or claim to the round wallet. This replaces the previous forfeit watcher and sweeper. \[[1560](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1560)], \[[1698](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1698)] ### Server pubkey pinning The wallet now stores the server's public key on first connection and verifies it on every subsequent connection. If the pubkey changes unexpectedly, the wallet blocks further interaction and advises the user to recover their bitcoin via an emergency exit. \[[1611](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1611)] ### Resilient maintenance with exit progression Maintenance tasks no longer bail on the first error—all steps now run to completion regardless of individual failures. Each maintenance run also actively progresses pending exits, broadcasting TRUC packages instead of merely syncing state. \[[1592](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1592)] ### Idempotent Lightning receive claims The server's `claim_lightning_receive` is now idempotent—if a claim is interrupted by a network failure or timeout, Bark can safely retry without risking duplicate state or forced on-chain exits. This is a meaningful reliability improvement for mobile integrations where transient connectivity issues are common. \[[1605](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1605)] ### Round event replay for late subscribers Clients subscribing to round events now receive the current `Attempt` event if sign-up is still open, fixing a race condition that caused mobile wallets to miss rounds. When a push notification wakes a phone and triggers a refresh, the wallet can now join rounds that are already in progress rather than waiting for the next one. \[[1572](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1572)] ### VTXO import for recovery You can now manually import serialized VTXOs into a wallet via `bark dev vtxo import` or the `/import-vtxo` REST endpoint. This is useful for recovering VTXOs that were lost from a wallet database but still exist on-chain—for example, after a database corruption or when migrating between wallet instances. \[[1607](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1607)] ### Exclusive datadir access with PidLock A new `PidLock` utility prevents multiple processes from operating on the same wallet datadir concurrently. When `barkd` or `bark` starts, it writes a lock file that blocks other instances from accessing the same data, preventing the subtle corruption that can occur when two processes modify wallet state simultaneously. Available behind the `pid_lock` feature flag. \[[1651](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1651)] ### Smarter refresh with dust detection The refresh strategy gains two new variants—`should_refresh_exclusive` and `should_refresh_if_must`—for more granular control over which VTXOs participate in a round. VTXOs with amounts below the P2TR dust threshold are now automatically flagged for refresh, preventing tiny outputs from accumulating and causing issues during transaction construction. \[[1614](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1614)] ### Recursive trust model for balance reporting The server now walks the full transaction ancestry to classify unconfirmed UTXOs, replacing BDK's shallow heuristic that only checked immediate inputs. This prevents external deposits from being incorrectly treated as trusted across balance reporting, telemetry, and CPFP balance checks. \[[1705](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1705)], \[[1692](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1692)] ### Legacy address delivery removed All VTXO delivery now uses `ServerMailbox`, completing the migration started in beta.7. Addresses generated with the old delivery method are no longer valid. The legacy gRPC methods `PostArkoorPackageMailbox` and `EmptyArkoorMailbox` have also been removed. \[[1502](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1502)] ### Feerate field renames All feerate fields in CLI and REST JSON output have been renamed with a `_sat_per_kvb` suffix and now express values in sats per kilovirtual byte. The old field names are still present but deprecated. \[[1654](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1654)] ### Lightning receive nullability The `htlc_vtxos` field in `LightningReceive` (and `LightningReceiveInfo` in the REST API) is now always a list. Previously it was nullable—`null` when no VTXOs were present—which required special handling in client code. It now returns `[]` instead. \[[1669](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1669)] ### Additional improvements * Round states are now locked in memory during processing, fixing a race condition that could cause concurrent tasks to interfere with each other. \[[1671](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1671)] * Lightning receive overpayment from the server is now accepted instead of rejected, improving reliability. \[[1685](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1685)] * Lightning send and receive movements now include the preimage when known. \[[1579](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1579)] * `received_on` field is now populated for arkoor receive movements, showing which addresses received bitcoin. \[[1610](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1610)] * Dust VTXOs are rejected early during refresh and exit, providing immediate feedback instead of waiting for round rejection. \[[1576](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1576)], \[[1580](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1580)] * Zero-sat Lightning invoices are now rejected at creation and payment time. \[[1577](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1577)] * `bark --version` now returns `DIRTY` with the commit hash when not built from a release tag. \[[1653](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1653)] * Round failures and cancellations are now properly reported as errors in the CLI. \[[1640](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1640)] * Server no longer schedules a round immediately after startup, waiting for the first interval to pass. \[[1643](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1643)] * Default required confirmations for round transactions reduced to 2 (1 on signet). \[[1586](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1586)] * All Bark crates have been relicensed from their previous license to the MIT license, making it easier to integrate Bark into commercial and open-source projects alike. \[[1621](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1621)] [Full release notes in the repo](https://gitlab.com/ark-bitcoin/bark/-/blob/master/CHANGELOG.md?ref_type=heads). **28 January 2026** 0.1.0-beta.7 ![Unified mailbox](https://mintcdn.com/second-0659a37d/8VZedF7eKiQd6Pfy/images/2026-mailbox.jpg?fit=max\&auto=format\&n=8VZedF7eKiQd6Pfy\&q=85\&s=4dcee4210934e758d30f000cc3bd1020) > [!WARNING] > > **Breaking changes** > > This release includes multiple low-level protocol encoding changes that require upgrading both `captaind` and `bark` together with fresh databases. Wallets and server databases from previous versions are not compatible—you must create new instances before upgrading. See the related changes: \[[1396](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1396)], \[[1550](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1550)], \[[1551](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1551)], \[[1552](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1552)], \[[1412](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1412)] ### Unified mailbox for VTXO delivery Bark now uses a unified mailbox system for receiving VTXOs, consolidating multiple delivery paths into a single, reliable channel. Incoming VTXOs now arrive at your mailbox address regardless of source—arkoor payments, Lightning receives, or round outputs. For app integrators, this is a foundational step toward push notifications. With all incoming VTXOs flowing through a single mailbox, you can build notification infrastructure that alerts users when they receive bitcoin. \[[1412](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1412)] ### Non-blocking maintenance and refresh We've added delegated variants of the maintenance and refresh APIs that return immediately instead of blocking until round completion. The new methods—`maintenance_delegated`, `refresh_vtxos_delegated`, and `join_next_round_delegated`—return a pending movement you can track via `sync()`. This is useful for mobile apps where blocking during round participation hurts UX. Kick off a refresh, let users continue interacting, and update the UI when the round completes. The CLI also gains a `--delegated` flag for `maintain` and `refresh`. \[[1566](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1566)] ### Environment variable configuration Bark configuration values can now be set via `BARK_*` environment variables, with a clear priority hierarchy: CLI args > env vars > `config.toml` > defaults. Useful for containerized deployments and CI/CD pipelines. \[[1558](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1558)] ### Query next round timing The server now exposes a `NextRoundTime` endpoint, and Bark's `Wallet` gains a `next_round_start_time()` method. Build UIs that show users when the next round occurs, or schedule background operations around round timing. \[[1559](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1559)] ### Improved Lightning invoice monitoring Lightning invoice status tracking has migrated from polling to stream-based monitoring using TrackAll. This provides real-time updates with automatic recovery after disconnections, reducing latency and resource consumption. \[[1453](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1453)] [Full release notes in the repo](https://gitlab.com/ark-bitcoin/bark/-/blob/master/CHANGELOG.md?ref_type=heads). **23 January 2026** 0.1.0-beta.6 ![hArk protocol](https://mintcdn.com/second-0659a37d/8VZedF7eKiQd6Pfy/images/2026-hark.jpg?fit=max\&auto=format\&n=8VZedF7eKiQd6Pfy\&q=85\&s=fd579d584898a681d1b6643926be6479) > [!WARNING] > > **Breaking changes** > > * **[Wallet migration required](#wallet-seed-security-upgrade):** Wallets created before this release will not load. Create a new wallet and transfer your bitcoin before upgrading. > * **[Custom BarkPersister implementations](#crash-recovery-for-vtxo-storage):** Update `store_vtxos` to be idempotent. > * **[Server configuration](#dynamic-fee-estimation):** Fee-related config options replaced with `[fee_estimator]` section. > * **[gRPC API](#grpc-api-changes):** Multiple endpoints added, renamed, or removed. ### Introducing hArk—non-interactive rounds We've implemented hArk (Hash-lock Ark), a major protocol evolution that eliminates synchronous interactivity during rounds. In the standard Ark protocol, all round participants receiving new VTXOs must be online simultaneously to sign intermediate transactions in the VTXO tree. hArk removes this requirement through a secret-based mechanism: the server generates a unique secret for each new VTXO, and participants can claim their VTXOs asynchronously by signing a forfeit transaction and receiving their secret from the server. This change brings several benefits: * Round participants no longer need to coordinate their online presence—the round can complete without requiring synchronous signing from all parties * Enables efficient consolidation of multiple VTXOs into a single output, addressing a significant constraint in the previous design where multi-input operations were problematic * Reduces server costs during malicious exit scenarios, eliminating attacks that were cheap for adversaries but expensive for the server to counter \[[1440](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1440)] ### Wallet seed security upgrade We've replaced `VtxoSeed` with `WalletSeed` to support deriving dedicated keys for mailbox functionality. As part of this change, normal key derivations have been replaced with hardened derivations, which provide stronger security guarantees by preventing parent key exposure from compromising child keys. Wallets created before this release will not load—you must create a new wallet and transfer your bitcoin before upgrading. \[[1452](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1452)] ### Offboard and send-onchain restored After temporarily disabling offboard functionality during the hArk transition, we've re-enabled it with improvements. The `bark send-onchain` command now returns the offboard transaction ID, and using offboard swaps, the transaction is broadcast instantly. The REST API endpoints for `offboard_vtxos` and `offboard_all` are also restored, now returning a simple `TxId`. \[[1531](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1531)], \[[1534](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1534)] ### Crash recovery for VTXO storage VTXO storage operations are now idempotent, enabling reliable crash recovery. Previously, if your wallet crashed during `persist_round_success`—after storing new VTXOs but before cleanup—subsequent sync attempts would fail on duplicate database inserts, leaving your wallet stuck. Now, `store_vtxos` succeeds without modification if a VTXO already exists, and `mark_vtxos_as_spent` succeeds if a VTXO is already spent. If you've implemented a custom `BarkPersister`, you must update `store_vtxos` to be idempotent. \[[1528](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1528)] ### Full async API The entire `BarkPersister` API is now async, and most of Bark's API has become async as a result. This enables non-blocking I/O operations for better resource utilization and scalability, particularly beneficial for applications handling concurrent wallet operations. \[[1485](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1485)] ### Dynamic fee estimation The server now uses a centralized `FeeEstimator` that queries bitcoind for current fee estimates instead of relying on hardcoded fallback rates. The estimator provides three fee tiers: fast (1-block target), regular (3-block target), and slow (6-block target), falling back to configurable rates when estimation fails. The `round_tx_feerate`, `[vtxo_sweeper] sweep_tx_fallback_feerate`, `[forfeit_watcher] claim_fallback_feerate`, and `[vtxopool] issue_tx_fallback_feerate` config options have been removed. Replace them with the new `[fee_estimator]` section: \[[1496](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1496)] ```toml theme={"theme":{"light":"github-light","dark":"github-dark"}} [fee_estimator] update_interval = "60s" fallback_fee_rate_fast = 10 # sat/vB for 1-block target fallback_fee_rate_regular = 5 # sat/vB for 3-block target fallback_fee_rate_slow = 2 # sat/vB for 6-block target ``` ### Dust VTXO support Bark now supports sending and receiving dust VTXOs (very small amounts), with dust isolation ensuring these small outputs don't cause issues with transaction construction. This applies to both direct sends and Lightning operations. The server adds a new `max_arkoor_fanout` config option to control the maximum number of arkoor outputs. \[[1440](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1440)] ### Board registration security The server now validates the board server pubkey during registration, rejecting boards signed with a different server pubkey. This prevents potential double-spend attacks where a malicious party could register boards from a different server. The `BoardBuilder::new_from_vtxo` method also validates that server pubkey, funding txid, and VTXO ID match expected values. \[[1472](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1472)] ### Improved Lightning receive claiming The `Wallet::try_claim_all_lightning_receives` behavior has been improved to be more resilient. Previously, it would bail on the first error; now it continues attempting to claim all pending receives. It returns success if at least one pending receive is claimed (or if there are none to claim), only returning an error if all claims fail. \[[1516](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1516)] ### Block-based sync infrastructure We've introduced `SyncManager` and `BlockIndex` utilities for block-based synchronization, replacing the previous `TipFetcher`. Configure how frequently the sync manager polls with the new `sync_manager_block_poll_interval` config option. The `bitcoin-ext` crate also adds `get_block_by_height` for fetching blocks by height from bitcoind. \[[1471](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1471)] ### Configuration naming consistency We've renamed `hodl` references to `hold` throughout configuration and code, fixing the inconsistent spelling that could cause confusion. Update any configuration or code that uses `hodl` terminology. \[[1478](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1478)] ### gRPC API changes The hArk transition introduces new gRPC endpoints for non-interactive round participation: * `SubmitRoundParticipation` * `RoundParticipationStatus` * `RequestLeafVtxoCosign` * `RequestForfeitNonces` * `ForfeitVtxos` The existing `SubmitPayment` endpoint now returns an `unlock_hash`. Several methods and types have also been renamed: * `CheckpointedCosignOor` → `RequestArkoorCosign` * `CheckpointedPackageCosignRequest` → `ArkoorPackageCosignRequest` * `CheckpointedPackageCosignResponse` → `ArkoorPackageCosignResponse` * `VtxoRequest` → `ArkoorDestination` (in arkoor context) * `RequestLightningPayHtlcCosign` now returns `ArkoorPackageCosignResponse` * `RequestLightningPayHtlcRevocation` now takes `ArkoorPackageCosignRequest` * `ClaimLightningReceiveRequest` now includes `ArkoorPackageCosignRequest` The following have been removed: * `PostArkoorPackageMailbox` gRPC method * `start_lightning_payment`, `finish_lightning_payment`, `revoke_lightning_payment` methods * `wait` field from `InitiateLightningPaymentRequest` * `max_arkoor_depth` field from `ArkInfo` \[[1440](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1440)], \[[1499](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1499)], \[[1501](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1501)] [Full release notes in the repo](https://gitlab.com/ark-bitcoin/bark/-/blob/master/CHANGELOG.md?ref_type=heads). **8 January 2026** 0.1.0-beta.3 to beta.5 ![Barkd](https://mintcdn.com/second-0659a37d/8VZedF7eKiQd6Pfy/images/2026-20250108-barkd.jpg?fit=max\&auto=format\&n=8VZedF7eKiQd6Pfy\&q=85\&s=8bb46e71ab5db50811ff7a01592cece1) Highlights from our recent beta releases, including a daemon-based wallet with REST API, browser compatibility for ark-lib, and a comprehensive wallet history system. ### Introducing Barkd—a daemon wallet with REST API We've launched Barkd, a wallet that runs as a daemon with a RESTful API. This is the solution for node runners or business owners who want to implement simple automation on their wallet. Client libraries are available in [multiple languages](https://gitlab.com/ark-bitcoin/barkd-clients) to get you started quickly. \[[1297](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1297)], \[[1291](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1291)] ### ark-lib now runs in the browser We've made ark-lib Wasm-compatible, enabling address inspection and VTXO hex deserialization directly in web environments. \[[1363](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1363)] ### Checkpoints replace arkoor-depth limitation The arkoor-depth limitation was necessary to protect the server but resulted in bad UX. We've replaced it with checkpoints—a new protection mechanism that removes the depth restriction while maintaining security. \[[1310](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1310)], \[[1342](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1342)], \[[1343](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1343)], \[[1394](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1394)] ### Comprehensive wallet history The new `bark history` command provides a complete overview of all cases where bitcoin goes in or out of your wallet—boards, arkoor transactions, round participation, and Lightning payments. \[[1455](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1455)], \[[1362](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1362)], \[[1355](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1355)], \[[1354](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1354)], \[[1414](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1414)], \[[1275](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1275)] ### More control over round participation You can now pick into ongoing rounds and control when they finish, with better status reporting through typed enums. We've also worked hard to ensure that when a round goes wrong, you won't feel any pain. \[[1328](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1328)], \[[1445](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1445)] ### Lightning payment reliability Lightning sends and receives are *even faster and more robust*. We've stress-tested the implementation and fixed various edge cases including overpaying invoices, HTLC timeout handling, and users not appearing to claim their bitcoin. \[[1401](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1401)], \[[1331](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1331)], \[[1419](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1419)], \[[1398](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1398)], \[[1414](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1414)] You can find more detailed release notes in the [repo](https://gitlab.com/ark-bitcoin/bark/-/blob/master/CHANGELOG.md?ref_type=heads). **4 November 2025** 0.1.0-beta.2 ![Byte at work](https://mintcdn.com/second-0659a37d/8VZedF7eKiQd6Pfy/images/2025-byte-at-work.jpg?fit=max\&auto=format\&n=8VZedF7eKiQd6Pfy\&q=85\&s=73d3c4081ef12d9f738631233c8e0c89) Our second beta release simplifies VTXO state management, enhances the user experience with immediate VTXO availability, and makes wallet integration easier with non-mutable API methods. > [!WARNING] > > **Breaking changes** > > The VTXO state simplification and `BlockRef` representation changes may require code updates if you're building on the bark API or CLI. ### Immediate VTXO usage in rounds Bark now uses newly issued VTXOs within the same round they're created, eliminating the previous requirement to wait for funding transaction confirmations. No more frustrating waits between receiving bitcoin and being able to spend it. Your users can participate in the next action immediately, making Ark feel more responsive and intuitive. \[[1261](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1261)] ### Streamlined VTXO state management We've dramatically simplified the VTXO state system. Previously, the number of VTXO states started exploding and it was hard to keep track of them. We've reduced them down to just three: `Spendable`, `Locked`, and `Spent`. This makes it much easier to reason about which VTXOs can be used in your app, reducing cognitive load and potential bugs. \[[1222](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1222)] ### Non-mutable wallet API methods The bark API now makes nearly all methods on the `Wallet` struct non-mutable, letting the library handle internal locking and state management for you. This is a major ergonomic improvement—you no longer need to juggle mutable references or worry about concurrent access patterns. The API is now more intuitive and less error-prone, making integration significantly smoother. \[[1194](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1194)], \[[1161](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1161)], \[[1152](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1152)], \[[1171](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1171)] ### Enhanced Lightning receive security and speed The Lightning receive functionality received a comprehensive security audit and makeover. We now ensure all timeouts are sensible and valid, eliminating potential edge cases that could compromise safety. A key benefit is support for shorter `min_final_cltv_delta` values on invoices without sacrificing security—your users get faster Lightning receives while maintaining the same safety guarantees. \[[832](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/832)] ### Minimum board amount Servers can now enforce a minimum board amount, giving operators better control over liquidity management and preventing dust-sized boards that create operational inefficiencies. App developers can retrieve this limit from the `ArkInfo` structure, allowing you to provide appropriate feedback to users before they attempt to board. \[[1257](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1257)] ### Intelligent on-chain spends that refresh VTXOs automatically On-chain spends now include `should_refresh_vtxos` by default, making the process more efficient. When you make an on-chain spend from your Ark balance, Bark automatically refreshes any VTXOs that are uneconomical to exit or soon-to-expire within the same round participation. This should reduce the need for separate, dedicated refresh operations. \[[1224](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1224)] ### Reorganized crate structure for cleaner dependencies The `bark` binary has moved to the `bark-cli` crate, which now contains all CLI binaries. If you're a Rust developer using the `bark-wallet` crate, you'll benefit from a more minimal and focused set of default features—smaller compile times, cleaner dependency trees, and less bloat in your final binaries. \[[1233](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1233)] ### Simplified VTXO filtering The VTXO filter trait has been streamlined, making it significantly easier to implement custom VTXO filters. The interface is now more focused and intuitive, reducing the boilerplate needed to control which VTXOs your application considers for spending. \[[1250](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1250)] ### Network-specific timeouts for faster development Bark API defaults are now network-aware, automatically using shorter timeouts on test networks. This makes development and testing cycles faster and more responsive, while maintaining conservative timeouts on mainnet for production safety. \[[1167](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1167)] ### Re-exported essential crates The `bdk` and `bip39` crates are now re-exported directly from Bark, eliminating version mismatches and making integration smoother. You no longer need to manually ensure you're using compatible versions of these dependencies. \[[1241](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1241)], \[[1205](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1205)] ### Improved CLI usability Several CLI improvements enhance day-to-day development workflows: * **Readable block references:** `BlockRef` is now displayed as `` in bark-cli, making output far more readable for humans. Note this is a breaking change for scripts parsing bark-cli output. \[[1232](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1232)] * **Cleaner VTXO display:** `bark vtxos` now shows only unspent VTXOs by default, reducing visual noise. Run `bark vtxos --all` when you need comprehensive information. \[[1214](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1214)] * **Complete transaction history:** `bark onchain transaction` lists all on-chain transactions with pagination removed for a streamlined view. \[[1148](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1148)] * **Safer VTXO management:** The command to drop VTXOs from the database has been moved to `bark dev` with explicit danger warnings—you must acknowledge the risk of bitcoin loss before proceeding. \[[1215](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1215)] ### Standardized Lightning invoice queries APIs for querying Lightning invoice status now uniformly accept a `PaymentHash`, providing a consistent interface across all Lightning-related operations and eliminating confusion about which identifier to use. \[[1164](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1164)] ### Better error messages for chain source issues When Esplora is misconfigured, Bark now provides clear, actionable error messages instead of dumping invalid hex values. This makes troubleshooting connection issues significantly faster and less frustrating. \[[1211](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1211)] **14 October 2025** 0.1.0-beta.1 ![Ark is now in beta](https://mintcdn.com/second-0659a37d/8VZedF7eKiQd6Pfy/images/2025-now-in-beta.jpg?fit=max\&auto=format\&n=8VZedF7eKiQd6Pfy\&q=85\&s=472084c1a13b10823dc1beb102cf059a) Here comes our **first beta release**—reflecting our switch from "move fast and break things" mode to "move fast and break less things" mode as we get closer to having our Ark implementation ready for you on mainnet. From here out, the API should be a lot more stable for you to build on. This release also marks our first publication on [crates.io](https://crates.io/crates/bark-wallet) and [docs.rs](https://docs.rs/bark-wallet/latest/bark/), providing production-ready tooling and comprehensive documentation for developers building on the Ark protocol. > [!WARNING] > > **Breaking changes** > > `bark-0.1.0-beta.1` is only compatible with `captaind-0.1.0-beta.1`. There is no upgrade path from alpha versions—you must drain your wallet and create a new one. ### Enhanced Lightning receive functionality We've significantly improved the reliability and efficiency of Lightning receives, rebuilding the feature from the ground up. Instead of requiring an inbound Lightning payment to be confirmed in-round (resulting in a long "pending" status for senders), we now use arkoor, ensuring senders get fast confirmations while HTLCs ensure the received sats are under the receiver's control. It results in a bit more temporary trust, but we think it's worth it to yield a much better UX for users. \[[974](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/974)] ### Lightning receive CLI improvements We've added two QOL improvements for managing Lightning receives. First, you can now claim all outstanding Lightning receives with a single command by omitting the invoice argument from `bark lightning claim`—perfect for batch processing and wallet maintenance scripts. Second, the new `--wait` flag lets you await invoice payment upon creation, eliminating the need to poll for payment status and enabling more responsive payment flows in your applications. \[[1119](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1119)], \[[984](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/984)] ### Wallet liveness management for mobile apps Understanding when your wallet needs to wake up is critical for mobile apps. We've added methods that determine precisely when the next refresh is required, enabling mobile wallet developers to meet Ark's liveness requirements efficiently without draining battery life. \[[1096](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1096)] ### Comprehensive wallet state inspection We've expanded wallet inspection capabilities far beyond basic balance checking. Developers can now view the complete state of their wallet, including not only spendable VTXOs but also those that are already spent or currently being processed. \[[1107](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1107)] ### Developer tooling and debugging capabilities We've added a dedicated `dev` CLI command that provides deep visibility into wallet status and operations. This developer-focused tooling facilitates even deeper monitoring and debugging during integration and testing phases. \[[1082](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1082)] ### Explicit wallet maintenance operations Ark wallets require periodic maintenance—syncing with the chain, refreshing VTXOs, and checking for new bitcoin. We've consolidated these operations into a clear, explicit `maintain` command that makes wallet upkeep straightforward and predictable. This is particularly valuable for systems that need deterministic maintenance scheduling. \[[1088](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1088)] ### Streamlined Lightning commands For developers working extensively with Lightning, we've introduced the `bark ln` alias as a shorthand for `bark lightning` commands. \[[1114](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1114)] ### Optimized development network defaults We've configured sensible defaults for development networks, including a default Esplora backend and optimized refresh thresholds. These improvements reduce configuration overhead and help developers get up and running quickly. We've also added support for [Mutinynet](https://github.com/MutinyWallet/mutiny-net), expanding your testing options. \[[1092](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1092)], \[[1031](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1031)] ### Customizable logging and verbosity Environment flags now control verbosity levels, giving developers precise control over logging output during development and debugging. This makes it easier to diagnose issues without being overwhelmed by unnecessary log noise. \[[1014](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1014)] ### Critical bug fixes Several important bug fixes enhance the reliability of core operations: * **Deterministic VTXO ordering:** Input VTXOs are now ordered deterministically when passed to arkoor packages, ensuring consistent transaction processing across all platforms \[[1094](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1094)] * **Faster wallet initialization:** Creating new wallets with bitcoind no longer triggers unnecessary full syncs, dramatically reducing setup time \[[1063](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1063)] * **Safer board registration:** Boards are only registered after achieving sufficient confirmations, preventing premature registrations that could cause issues \[[1069](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1069)] * **Sub-dust change handling:** The wallet now properly discards sub-dust change outputs, preventing transaction inefficiencies \[[1043](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1043)] ### Improved code clarity through refactoring We've made several naming improvements to enhance code readability and maintainability: * Renamed `ChainSourceClient` to `ChainSource` for clearer semantics \[[1099](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1099)] * Renamed `round_tx` to `funding_tx` to better reflect its purpose \[[991](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/991)] ### Comprehensive documentation In addition to publishing on crates.io and docs.rs, we've significantly expanded our inline documentation across all major components: * Wallet struct \[[1059](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1059)] * On-chain wallet \[[1058](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1058)] * Persist module \[[1056](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1056)], \[[1055](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1055)] * Round module \[[1057](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1057)] * Server module \[[1022](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1022)] * Config struct \[[1020](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1020)] * VtxoState \[[1019](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1019)] * Exit module \[[1018](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1018)] * VTXO selection \[[1017](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/1017)] **10 September 2025** 0.0.0-alpha.19 ![A captain's hat (aspd got renamed to captaind)](https://mintcdn.com/second-0659a37d/8VZedF7eKiQd6Pfy/images/2025-captains-hat.png?fit=max\&auto=format\&n=8VZedF7eKiQd6Pfy\&q=85\&s=c9dcb6272e1aceec40d6b235c5cf239f) We've moved to numbered releases to provide better version tracking and compatibility guarantees. This changelog covers updates from `captaind-0.0.0-alpha.19` and `bark-0.0.0-alpha.19`. > [!WARNING] > > **Breaking changes** > > These releases include significant breaking changes: > > * `aspd` has been renamed to `captaind` with no migration path from alpha.18 > * `bark-0.0.0-alpha.19` is only compatible with `captaind-0.0.0-alpha.19` > * If you're using older versions, you must drain your wallet and create a new one > * The bark crate has been renamed from `bark-client` to `bark-wallet` ### Major rename—aspd is now captaind We've renamed `aspd` to `captaind` to better reflect the Ark server's role as the captain of your Ark operations. **Important:** There is no migration path from `aspd-0.0.0-alpha.18`—it's recommended to drain bitcoin from old instances and start fresh with `captaind`. In addition, all instances of `asp` have been renamed to `ark_server` throughout the codebase, and the bark crate has been renamed from `bark-client` to `bark-wallet`. This provides better clarity on what each component is doing! \[[900](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/900)] ### Support for BOLT-12 offers Ark now supports paying BOLT12 offers, bringing you improved privacy and reusability on Lightning. This addition makes Ark compatible with the next generation of Lightning invoices, providing better user experiences for recurring payments and static payment codes. \[[867](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/867)], \[[807](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/807)] ### RBF support for stuck exits We've implemented Replace-By-Fee (RBF) functionality in the exit system, allowing you to increase feerates if an exit transaction gets stuck in the mempool. This gives you more control over your exit timing and ensures your bitcoin is never trapped due to low feerates during high-traffic periods. \[[896](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/896)] ### Enhanced Ark addresses with delivery mechanisms Ark addresses now include delivery mechanisms, providing more flexibility with various wallet interfaces and payment flows when sharing payment information. \[[894](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/894)] ### Bulletproof round participation Bark now responds defensively when an Ark server misbehaves during a round. This critical reliability improvement ensures your bitcoin remains safe even if the server encounters issues or acts maliciously during round processing. \[[564](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/564)] ### Opt-in on-chain wallet The BDK wallet is now optional, allowing developers using alternative on-chain wallet solutions to integrate Ark without compiling BDK dependencies. This reduces binary size and compilation time for projects that already have their own wallet infrastructure. \[[923](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/923)] ### Enhanced mobile wallet support The server now returns the last round on subscription, helping mobile wallets participate in rounds after being woken up by notification servers. This improvement ensures mobile users don't miss rounds due to background app limitations and provides better overall mobile experience. \[[898](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/898)] ### Granular admin control with gRPC service separation We've split up the admin gRPC services and provided tighter control over which services to expose, giving server operators more flexibility in managing access to administrative functions. This security enhancement allows for more granular permission management. ### Significant CLI improvements The `bark` CLI now includes several developer-friendly enhancements: * Support for `BARK_DATADIR` environment variable for easier config management \[[946](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/946)] * `bark wallet create --force` command to create wallets when the Ark server isn't available \[[922](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/922)] * Added more details to the display of on-chain balances for improved visibility \[[870](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/870)] ### Faster round synchronization We've parallelized the round-sync process, significantly improving sync performance and reducing the time needed to catch up with the latest Ark state. This enhancement is particularly beneficial for wallets that have been offline for extended periods. \[[912](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/912)] ### Enhanced operational reliability Several improvements enhance server stability and observability: * Consistent use of `DateTime` over `DateTime` for better handling of (the dreaded) timezones \[[861](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/861)] * Various telemetry fixes and improvements for better monitoring \[[890](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/890)] * Better error messages throughout the system \[[914](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/914)] * Removal of secrets from logs for improved security \[[915](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/915)] ### Improved wallet reliability Additional fixes ensure better wallet behavior: * Fixed early bailout issues in sync process \[[884](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/884)] * Correct fee application when claiming exits \[[887](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/887)] * Support for Lightning payments requiring multiple input VTXOs * `bark config` now outputs proper JSON format \[[911](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/911)] * Various fixes to the exit system for improved reliability \[[896](https://gitlab.com/ark-bitcoin/bark)] **5 August 2025** ![Byte scanning a QR code using our new Ark address format with a smartphone](https://mintcdn.com/second-0659a37d/8VZedF7eKiQd6Pfy/images/2025-ark-address-scan.jpg?fit=max\&auto=format\&n=8VZedF7eKiQd6Pfy\&q=85\&s=10fdd411561f334806e04dd324c0f05d) ### Finally, an Ark address format! We've introduced a new address format specifically designed for payments within the Ark. This makes it much easier to send and receive bitcoin using Ark, providing a familiar address-based experience similar to regular bitcoin transactions. This was also an opportunity to launch [our new BOAT (Basis Of Ark Technology) specifications](https://github.com/ark-protocol/boats/). \[[842](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/842)] ### Hefty Lightning receive fees eliminated We've removed the default 350 sat fee that was previously charged for every Lightning receive operation. Lightning receives now use child-pays-for-parent (CPFP) to confirm transactions instead of requiring direct fees. This makes receiving Lightning payments through Ark completely free until we implement our fee schedule (WIP). Make those free signet payments while you still can! ### Lightning invoice management Bark now allows you to request and view all generated Lightning invoices through both the API and CLI. This gives you complete visibility into your Lightning payment history, making it easier to track incoming payments. \[[850](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/850)] ### Protocol version negotiation Our implementation of the Ark protocol now has a proper version system that allows bark and Ark servers to negotiate compatibility automatically. This ensures smooth communication between different versions and provides a foundation for future protocol upgrades. \[[847](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/847)], \[[837](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/837)] ### Enhanced error reporting for missing VTXOs The Ark server now provides comprehensive error reporting, showing all missing VTXOs instead of stopping at the first one. This makes debugging and troubleshooting much more efficient for both developers and server operators. \[[819](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/819)] ### Simplified wallet architecture We've split the on-chain wallet from the Ark wallet, making it easier to integrate Ark into applications that already have existing on-chain wallet functionality. Developers can now use the `OffchainWallet` as a default implementation while maintaining full control over their on-chain operations. Note that you must now explicitly sync both wallets. ### Cleaner API naming conventions We've standardized on using `lightning_receive` consistently throughout the codebase and API, replacing the previous mix of `bolt11_board` and `offchain_board` terminology. Less confusing and more intuitive! \[[852](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/852)] ### Enhanced type safety for payments Bark now uses proper `PaymentHash` and `PaymentPreimage` types instead of generic byte arrays, providing better type safety and making the codebase more maintainable for developers building on Ark. ### Simplified keychain management We've removed the internal/external keychain concept that provided limited benefits for Ark wallets, streamlining the wallet architecture and reducing complexity for developers. \[[840](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/840)] ### Improved chain source configuration The `ChainSourceClient` now supports network configuration and validation, with built-in fee caching and memory functionality. This provides more reliable chain interactions and better resource management. ### Optimized binary sizes for API users When building bark, the resulting binaries are now significantly smaller, reducing deployment overhead and making it easier to integrate Ark into resource-constrained environments. \[[832](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/832)] ### Reduced memory footprint for transaction indexing We've optimized the memory usage of the TxIndex system, making Ark servers more efficient and capable of handling larger transaction volumes with less resource consumption. \[[817](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/817)] ### Telemetry stability improvements Fixed an issue that occasionally caused the telemetry system to crash, improving the overall stability and observability of Ark server operations. \[[853](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/853)] > [!WARNING] > > **Breaking changes** > > This release is only compatible with aspd-0.0.0-alpha.18 and requires upgrading both bark and the Ark server in lockstep. There is no smooth upgrade path from bark-0.0.0-alpha.17—you must drain your wallet and create a new one. **4 July 2025** ![Pay2Anchor has dropped on Ark](https://mintcdn.com/second-0659a37d/8VZedF7eKiQd6Pfy/images/2025-pay2anchor.jpg?fit=max\&auto=format\&n=8VZedF7eKiQd6Pfy\&q=85\&s=8bdb308c638f55419e0435759b785c67) ### Cheaper emergency exits with Pay2Anchor Leaning on our addition of Pay2Anchor support to the rust-bitcoin dependency, we've now integrated P2A directly into Ark itself, switching from P2WSH OP\_TRUE outputs. This significantly reduces the cost of emergency exits, making it cheaper and more efficient when you need to exit the Ark in an emergency. \[[565](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/565)] ### More ergonomic bark API We've made the bark API more developer-friendly, providing a better experience for wallet developers using the Rust crate to build on Ark. \[[623](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/623)], \[[615](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/615)] ### Enhanced security with single-input arkoor We've removed support for multi-input arkoor transactions, reducing the liquidity burden on Ark servers and implementing important mitigations against partial exit attacks. \[[658](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/658)], \[[707](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/707)] ### Simplified arkoor and Lightning payments We've done a major cleanup of arkoor and Lightning payment code, making it much easier to read and maintain while providing a cleaner API for external developers building on Ark. \[[686](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/686)], \[[682](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/682)] ### Advanced Lightning payment infrastructure We've implemented sophisticated fail-over mechanisms and enhanced error recovery logic for Lightning payments. This goes beyond our previous send implementation fixes, providing comprehensive infrastructure-level resilience for Lightning payment routing and execution. \[[580](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/580)], \[[625](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/625)] ### Enhanced privacy with unique public keys Bark now avoids reusing public keys when receiving bitcoin, providing similar privacy benefits to avoiding address reuse in regular bitcoin transactions. \[[586](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/586)] ### Completely rewritten emergency exit We've rewritten the emergency exit functionality from the ground up, providing better debugging tools, status reporting, and more granular control over the exit process. \[[729](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/729)] ### VTXO amount limits for better liquidity management We've implemented limits on VTXO amounts to prevent a single user from consuming all of the server's liquidity, ensuring fair access and better resource distribution across all users. \[[583](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/583)] ### Streamlined boarding flow architecture Beyond our May improvements to boarding reliability and recovery mechanisms, we've now refactored the board flow architecture to make the process even more reliable. \[[718](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/718)] ### Enhanced Docker deployment experience across architectures We've significantly improved the Docker deployment experience across all supported platforms. These enhancements make it much easier for developers to spin up an Ark server locally for testing and development purposes, regardless of their hardware architecture. \[[717](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/717)], \[[711](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/711)], \[[680](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/680)], \[[653](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/653)] ### More efficient transaction indexing We've improved the efficiency of our TxIndex system, reducing resource consumption and fixing a bug that prevented the Ark server from shutting down gracefully in certain scenarios. \[[710](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/710)], \[[647](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/647)] ### Updated to bitcoin 29.0 We've updated our dependencies to support bitcoin 29.0, ensuring Ark stays current with the latest bitcoin protocol improvements. \[[559](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/559)] ### Cleaner dependency management We've eliminated our reliance on custom forks and are now using published and peer-reviewed dependencies, making Ark more stable and easier to maintain. \[[705](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/705)] ### Enhanced testing infrastructure We've introduced flake\_finder to handle intermittent test failures and split up our test directory for better organization when running tests with different chain backends. \[[592](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/592)], \[[661](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/661)] **6 May 2025** ![Lightning payments being blasted out from a mobile device using Ark](https://mintcdn.com/second-0659a37d/8VZedF7eKiQd6Pfy/images/2025-mobile-lightning.jpg?fit=max\&auto=format\&n=8VZedF7eKiQd6Pfy\&q=85\&s=a314e553d3bbacc698300f21b3502561) ### Enhanced Lightning payment reliability We've significantly improved our Lightning send implementation with more robust logic and implemented revocation of failed Lightning payments, making the entire Lightning payment process more reliable and secure. \[[533](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/533)], \[[434](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/434)] ### Lightning command for invoice payments Bark now includes a dedicated Lightning sub-command that can be used to pay Lightning invoices directly, making it easier than ever to use Ark for Lightning payments. \[[540](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/540)] ### Improved on-chain wallet management We've completely restructured the Ark server's on-chain wallet management to address unexpected challenges with conflicting transactions. By splitting the wallet into different parts, we've eliminated these issues for good. \[[523](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/523)] ### Runtime task management system A new runtime manager was introduced to coordinate all background tasks such as VTXO sweeping and round creation, bringing more stability and reliability to Ark server operations. \[[521](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/521)] ### Docker images for multiple architectures We've released Docker images for various architectures, making it significantly easier to spin up an Ark server locally for development and testing. \[[525](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/525)] ### Fixed round participation issue We resolved a bug where the server would incorrectly refuse to serve a VTXO because it falsely believed the VTXO was already participating in another round, improving overall reliability. \[[527](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/527)] ### Enhanced transaction confirmation checks The Ark server now performs more thorough checks on chain confirmations and will not accept board VTXOs for which the funding transaction hasn't been confirmed on-chain, improving security. \[[519](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/519)], \[[534](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/534)] ### Graceful shutdown handling Ark server now captures and handles SIGTERM correctly, ensuring a graceful shutdown when the server is stopped or restarted using systemctl. \[[524](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/524)] ### Improved boarding reliability Bark can now recover from partially registered boards and re-attempt on failure, making the boarding process more resilient. \[[518](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/518)] ### Improved VTXO registration resilience When a user boards the Ark it will register the newly created VTXO with the server. The registration command has been made idempotent. \[[518](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/518)] ### Enhanced wallet balance telemetry We've added improved telemetry for node operators about wallet balance, making it easier to monitor and manage Ark server operations. \[[531](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/531)] **8 April 2025** ![Byte the dog connecting an Ark server to a signet testnet server](https://mintcdn.com/second-0659a37d/8VZedF7eKiQd6Pfy/images/2025-signet-launch.jpg?fit=max\&auto=format\&n=8VZedF7eKiQd6Pfy\&q=85\&s=fd7b7fd10af611717cdbc99e80c67b90) ### Launch on signet We're excited to announce that Ark is now available on signet! You can use bark to send signet coins to friends and family, making it easier than ever to test and experiment with the protocol. ### Enhanced server-client communication We've implemented a connection handshake between bark and the Ark server that ensures version compatibility and enables public service announcements. \[[384](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/384)], \[[514](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/514)] ### Forfeit transaction management The Ark server now automatically handles forfeit transactions when clients refresh sats in a round. We've implemented chain monitoring and automated publishing of forfeit transactions through an updated TxIndex system. \[[416](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/416)], \[[417](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/417)], \[[423](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/423)], \[[415](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/415)], \[[449](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/449)], \[[450](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/450)], \[[512](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/512)] ### Improved observability We've enhanced visibility into Ark's internal operations with structured logging and comprehensive telemetry. Track wallet balances, client versions, and other key metrics in a dedicated log file. \[[442](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/442)], \[[441](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/441)], \[[433](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/433)] ### Stability improvements Several critical fixes have been implemented to improve system stability: * Graceful handling of insufficient offboard amounts \[[471](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/471)] * Eliminated panics during rounds \[[495](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/495)] * Support for repeated client boarding \[[516](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/516)] ### Bark usability enhancements We've made bark more intuitive and user-friendly: * Simplified wallet creation by removing explicit HTTPS requirement \[[382](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/382)] * Added `ark-info` command to query server settings \[[412](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/412)] * Improved amount and unit specification hints \[[487](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/487)] * New utilities for draining on-chain wallets \[[472](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/472)] ### Lightning payment improvements We've resolved several Lightning-related issues, including prevention of duplicate invoice payments and implementation of intermediate state exits. \[[389](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/389)], \[[409](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/409)], \[[459](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/459)], \[[470](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/470)], \[[490](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/490)] **6 March 2025** ![Ark's latest alpha version: 0.0.0-alpha.1](https://mintcdn.com/second-0659a37d/8VZedF7eKiQd6Pfy/images/2025-alpha1.jpg?fit=max\&auto=format\&n=8VZedF7eKiQd6Pfy\&q=85\&s=87c5cdf7db155c0203369db6841ec085) ### Ark in alpha We have released version 0.0.0-alpha.1 of bark and aspd. Note, that this is an alpha version with known bugs and vulnerabilities that will result in loss of bitcoin. ### Smoother Ark server configurations Configuring an Ark server is now a breeze, with the option of using toml file or environment variables. This will help developers who want to quickly spin up an Ark server for testing purposes (and Ark server operators!). \[[380](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/380)] ### Ark server database got an upgrade We migrated the Ark server database from RocksDB to Postgres. Postgres is proven to be a reliable database that powers many critical systems in various industries. \[[314](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/314)] \[[358](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/358)] \[[368](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/368)] \[[372](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/372)] \[[373](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/373)] \[[383](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/383)] ### Sandboxed server secrets Keeping the mnemonic secret is crucial to securing an Ark server. We split the mnemonic from the database to ensure operators have full control on how and where their mnemonic is stored. \[[366](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/366)] ### Network validation Connecting a mainnet Ark server to a signet network is a bit of a footgun. The Ark server will now validate the network before connecting. We reduced the binary size of aspd from 200MB to 30MB. \[[325](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/325)] ### Improved error messages As a developer you deserve proper error messages when things go wrong. We made various improvements to ensure that you will get error messages that help you out. \[[334](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/334)] \[[345](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/345/commits)] \[[350](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/350)] ### A couple of exit improvements We simplified the API and ensured that the exit works if Esplora is used as a chain source. \[[362](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/362)] \[[385](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/385)] ### Multi-threading support The bark API now works in multi-threaded applications (it didn't previously). \[[378](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/378)] ### Reducing the cost of emergency exits with Pay2Anchor A new output type called Pay2Anchor was introduced in bitcoin 28.0. It is more efficient than a traditional fee anchor which helps to reduce the cost of an emergency exit. We have implemented the PayToAnchor output in rust-bitcoin. \[[4111](https://github.com/rust-bitcoin/rust-bitcoin/pull/4111)] ### Preventing double-spends We have implemented a new feature in BDK that allows us to spend only confirmed UTXOs. This will help us to ensure we never double-spend a counterparty by accident. \[[1855](https://github.com/bitcoindevkit/bdk/pull/1855)] **9 February 2025** ![Byte bowing to all three desktop operating systems: Windows, macOS, and Linux](https://mintcdn.com/second-0659a37d/8VZedF7eKiQd6Pfy/images/2025-multi-os.jpg?fit=max\&auto=format\&n=8VZedF7eKiQd6Pfy\&q=85\&s=88e04867bb330e3fcb8212848c5133fc) ### First major release of BDK Bark's on-chain wallet got even more stable thanks to the release of BDK 1.0.0. We've been excited (and waiting!) for this for a long time—huge thanks to the BDK team for rolling it out, and to new contributor [@jirijakes](https://github.com/jirijakes) for adding it to bark! 👏 \[[252](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/252)] ### No Linux, no problem Bitcoin works on any desktop device and now so does our Ark client, bark. A few adjustments have been made by our non-Linux colleagues to ensure that bark works across Linux, macOS, and Windows. \[[203](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/203)],\[[275](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/275)],\[[276](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/276)] ### Track your regret Want to know where you spent all your sats? Bark will now maintain a history of all transactions in and out of your wallet. \[[212](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/212)] ### All the JSON, all the time Bark will now always return outputs in JSON format. A consistent output format makes it much easier to develop scripts on bark. \[[305](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/305)] **18 December 2024** ![Arkoor is now the standard](https://mintcdn.com/second-0659a37d/8VZedF7eKiQd6Pfy/images/2024-arkoor-standard.jpg?fit=max\&auto=format\&n=8VZedF7eKiQd6Pfy\&q=85\&s=30d5361cfcc582e134ce43744cca5890) ### All payments are now arkoor by default We've made a big shift in Ark payment policy: all payments will now be arkoor, and in-round transactions are reserved for refreshing VTXOs only. This took a massive refactor, but the payoff is huge: Ark rounds are now way more reliable thanks to reduced interactivity requirements, and Ark wallets consume fewer resources across devices (mobile users won't have to worry about killing their batteries anymore!). Importantly, the change gives users far more control over their preferred fees and security model. For a deep dive on the change, see our [recent blog article](https://second.tech/blog/the-arkoor-standard/). ### Zero-fee transactions `bitcoind` 28.0 brought zero-fee VTXOs to Ark. By using child-pays-for-parent to confirm transactions instead, your Ark payments will now be even cheaper and even more reliable—especially for exits (but hopefully you'll never need those). ### Structured logging The Ark server daemon now comes with structured logging. Parsing logs, building dashboards, testing, and setting alerts for Ark server operations will now be way easier. ### VTXOs and UTXOs stored together in the same database In October, we replaced the VTXO database with SQLite. And now, thanks to BDK's native SQLite support, your on-chain UTXOs are stored in the same database. ### Rustls encryption We've switched out OpenSSL in favour of Rustls. In our opinion, Rustls is a higher quality implementation that will make Ark more secure and easier to build upon. **31 October 2024** ### Database now running on SQLite Our biggest update this month was migrating [bark](https://gitlab.com/ark-bitcoin/bark) to an SQLite database. We chose SQLite because it's ridiculously stable, works on a wide range of hardware, and is easy for any developer to pick up because it's been around for so long. SQLite is what you use when you don't want to lose important data, and there's little data more important than bitcoin data! ![Screenshot of SQLite database in use](https://mintcdn.com/second-0659a37d/8VZedF7eKiQd6Pfy/images/2024-sqlitebrowser.png?fit=max\&auto=format\&n=8VZedF7eKiQd6Pfy\&q=85\&s=8a1409f00713d80069e5ad90f41b5f67) ### Updated to BDK beta 4 In October, we integrated two successive releases of [BDK](https://bitcoindevkit.org), going from beta2 to beta4. BDK is central to bark, our Ark client implementation. It enables us to quickly and easily build a fully-fledged bitcoin wallet, literally doing everything out-of-the-box. So we continue to look forward to the upcoming stable 1.0 release. You know what to do, Spiral! ### On-demand syncing Bark now only does an on-chain sync when it's actually required. This ensures bark loads faster and feels a lot more snappy. ### Contributor shoutouts We also want to give a shoutout to three first-time contributors: * **adbd7e7** added a very necessary fallbackfee to our demo script. \[[110](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/110)] * **Acidbunny21** made it easy to offboard specific VTXOs without leaving dust inside the Ark server. \[[87](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/87)] * **kevkevinpal** added some very helpful aspd commands to the documentation. \[[103](https://gitlab.com/ark-bitcoin/bark/-/merge_requests/103)] Thank you for your contributions! # Connection details Source: https://second.tech/docs/connection-details Second's public Ark server and Esplora endpoints for mainnet and signet. Copy them into bark, the Bark SDK, or barkd. **Mainnet** ```text Ark server theme={"theme":{"light":"github-light","dark":"github-dark"}} https://ark.second.tech ``` ```text Esplora theme={"theme":{"light":"github-light","dark":"github-dark"}} https://mempool.second.tech/api ``` **Signet** ```text Ark server theme={"theme":{"light":"github-light","dark":"github-dark"}} https://ark.signet.2nd.dev ``` ```text Esplora theme={"theme":{"light":"github-light","dark":"github-dark"}} https://esplora.signet.2nd.dev ``` ## Configure a chain source With the Bark CLI, pass only `--ark`. The CLI falls back to the Esplora endpoint for your network when you don't pass `--esplora` or `--bitcoind`. `barkd` does the same when you create a wallet without a `chain_source`. The Bark SDK requires an explicit chain source, so set the Esplora endpoint when you configure the wallet. To use your own `bitcoind` node instead, use the Bark CLI, `barkd`, or the Rust SDK. The SDK's other language bindings support Esplora only. # Advanced Bark features Source: https://second.tech/docs/getting-started/bark-cli/advanced Advanced `bark` features for power users. Learn how to board bitcoin onto Ark and perform emergency exits when the Ark server is unresponsive. There are two additional `bark` features that we don't expect most users will ever need, but that advanced users might want to try out: * **Boarding:** Taking on-chain bitcoin off-chain, onto an Ark. * **Emergency exit:** Taking off-chain bitcoin on-chain, without any cooperation from the Ark server. ## Boarding We expect most users will receive their first sats over Ark directly, in the same way you received yours from our faucet. But it is definitely possible to move your on-chain bitcoin onto the Ark as well—we call it *boarding*! Boarding is currently only possible from within Bark's internal on-chain wallet. So for you to try it out, you need to have an on-chain balance. **1. Check your on-chain balance** Check your on-chain balance using: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} bark onchain balance ``` **2. Fund your on-chain wallet** If you don't have any, [our faucet](https://signet.2nd.dev/) can help you out. Grab an on-chain address from your Bark wallet: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} bark onchain address ``` Then use the faucet to send some on-chain (signet) sats to this address. You can run `bark onchain balance` again to double-check they've arrived. **3. Board the Ark** Once you have some on-chain sats, you can board the Ark: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} # Board entire on-chain balance bark board --all # Board a specified amount bark board "10000 sat" ``` **4. Verify your VTXOs** After boarding, you should see a new VTXO holding the sats you boarded: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} bark vtxos ``` You've successfully taken your on-chain bitcoin off-chain! ## Emergency exit Finally, let's walk through performing an [emergency exit](/docs/learn/exit). This process requires broadcasting multiple transactions sequentially, so please allocate 1-2 hours to complete this test. > [!NOTE] > > We're currently addressing some known issues with emergency exits that may occur in certain edge cases. [Let us know if you need help](https://community.second.tech). ### What you'll need To get started, you will need the following: * At least one VTXO * At least 15,000 *on-chain* sats per VTXO you're exiting (just to be on the safe side!) * Make sure each on-chain UTXO has at least one confirmation. Check this using `bark onchain utxos` or at [mempool.space](https://mempool.space/signet). * Patience ### Under the hood Each of your VTXOs consists of a series of off-chain transactions that must be broadcast to retrieve your sats on-chain. The emergency exit process will work as follows: * Each of the transactions in your emergency exit will have to be broadcast and confirmed using a [child-pays-for-parent transaction (CPFP)](https://bitcoinops.org/en/topics/cpfp/). * Each child transaction has to wait an average of 10 minutes for its parent to confirm. * Once the final transaction of a VTXO's exit is confirmed, you will have to wait for a timelock to expire. The timelock is the VTXO's `exit_delta`: 12 blocks (about two hours) on signet and 144 blocks (about a day) on mainnet. > [!NOTE] > > If you are using your own bitcoin node instead of the Esplora backend, make sure `-txindex` is enabled. ### Performing the exit **1. Mark VTXOs for exit** First, you'll need to mark one or more VTXOs that you'd like to exit. **Mark a single VTXO for exit** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} bark exit start --vtxo ``` **Mark multiple VTXOs for exit** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} bark exit start --vtxo --vtxo ``` **Mark all VTXOs in your wallet for exit** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} bark exit start --all ``` **2. Initiate your exits** Run the following command to begin the exit process: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} bark exit progress --wait ``` Exits are a multi-step process that requires multiple transactions broadcast in sequence. The `--wait` flag keeps the operation running until the entire VTXO has been exited. We'd recommend going to get a coffee while you wait! > [!NOTE] > > You might see some scary logging. This does not necessarily mean that your exit will fail. Often the process recovers automatically (e.g., retrying after an additional confirmation). If you really want to dig deeper, use the `--verbose` flag to follow everything that happens under the hood. **3. Claim bitcoin from a completed exit** Once your exit has been completed—the leaf/exit transaction has been broadcast—your bitcoin is now on-chain and will not expire. However, spending this bitcoin still depends on the data held in your Bark database. If you deleted your Bark wallet data and had no [backup of your wallet data](/docs/backups) other than a seed phrase, you would permanently lose access to the exited bitcoin. To ensure your bitcoin is spendable with only your usual backup setup (e.g., a mnemonic), you'll need to spend the bitcoin to a separate on-chain wallet. This is called a *claim* and requires an additional on-chain transaction. Don't worry though, Bark makes claiming your exited bitcoin simple: **Get an on-chain address from your wallet** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} bark onchain address ``` > [!NOTE] > > You don't have to use Bark's on-chain wallet. Any on-chain wallet works. **Claim emergency exits using your on-chain address** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} bark exit claim --vtxo ``` When claiming an exit, you can either specify the `--vtxo` flag multiple times or just use the `--all` flag. ### Checking the status of an exit To check on the status of your exit(s), you can use one of the following commands: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} bark exit list ``` ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} bark exit status ``` Both commands support the `--transactions` and `--history` flags which can be extremely helpful when debugging issues. # Configure Bark Source: https://second.tech/docs/getting-started/bark-cli/configuration Configure the `bark` CLI through environment variables and `config.toml`: logging, data directory, Ark server, chain source, refresh threshold, and exit margin. ## Environment variables Available environment variables: * `BARK_VERBOSE` (`1` or `true`): set verbose logging * `BARK_QUIET` (`1` or `true`): set no logging * `BARK_DATADIR`: set the data directory to use * `BARK_LOG`: set a `env_logger`-style filter for logging (for example, `info` or `info,bark=trace`) > [!TIP] > > **Default data directory** > > To check your default data directory, run the following command: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} bark help ``` ## Configuration file Your Bark data directory contains a `config.toml` file. It supports the following configuration variables: * `server_address`: the address of your Ark server * `esplora_address`: the address of the Esplora HTTP REST server to use * `bitcoind_address`: the address of the `bitcoind` RPC server to use * `bitcoind_cookiefile`: the path to the `bitcoind` rpc cookie file * `bitcoind_user`: the `bitcoind` RPC username * `bitcoind_pass`: the `bitcoind` RPC password * `vtxo_refresh_expiry_threshold`: the number of blocks before expiry to refresh VTXOs * `vtxo_exit_margin`: an upper limit of the number of blocks we expect to need to safely exit the VTXOs * `htlc_recv_claim_delta`: the number of blocks to claim a HTLC-recv VTXO * `fallback_fee_rate`: a fallback feerate to use in sat/kWu when we fail to retrieve a feerate from the configured `bitcoind`/Esplora connection * `round_tx_required_confirmations`: the number of confirmations required before considering a round transaction fully confirmed For the full definition, see the [configuration struct](https://gitlab.com/ark-bitcoin/bark/-/blob/master/bark/src/config.rs#L75) in the bark repository. # Install Bark CLI Source: https://second.tech/docs/getting-started/bark-cli/index Step-by-step guide to installing `bark`, Second's Ark wallet client. Download binaries or compile from source to start making transactions on signet or mainnet. This step-by-step tutorial gets you started with `bark`, our command-line Ark wallet client. `bark` works on both [signet](https://bitcoinops.org/en/topics/signet/) (a bitcoin testnet) and mainnet. Once it's installed, head to [test on signet](/docs/getting-started/bark-cli/signet) or [test on mainnet](/docs/getting-started/bark-cli/mainnet). ## Installing Bark Your wallet is called `bark` and has two installation methods: * Download and install the binary releases * [Compile from source](#compile-from-source) ### Binary release Download binary releases from [GitLab](https://gitlab.com/ark-bitcoin/bark/-/releases). Below are instructions to download the binary, mark it as executable, and add it to your PATH on different platforms. **Ubuntu/Debian** **1. Download bark** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} curl -L https://gitlab.com/ark-bitcoin/bark/-/releases/bark-0.8.0/downloads/bark-0.8.0-linux-x86_64 --output bark ``` **2. Mark the binary as executable** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} chmod +x bark ``` **3. Add bark to your PATH** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} sudo cp bark /usr/local/bin/ ``` **Fedora/CentOS** **1. Download bark** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} curl -L https://gitlab.com/ark-bitcoin/bark/-/releases/bark-0.8.0/downloads/bark-0.8.0-linux-x86_64 --output bark ``` **2. Mark the binary as executable** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} chmod +x bark ``` **3. Add bark to your PATH** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} sudo cp bark /usr/local/bin/ ``` **macOS** **1. Download bark** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} curl -L https://gitlab.com/ark-bitcoin/bark/-/releases/bark-0.8.0/downloads/bark-0.8.0-apple-aarch64 --output bark ``` **2. Mark the binary as executable** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} chmod +x bark ``` **3. Add bark to your PATH** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} sudo cp bark /usr/local/bin/ ``` **macOS (Intel)** **1. Download bark** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} curl -L https://gitlab.com/ark-bitcoin/bark/-/releases/bark-0.8.0/downloads/bark-0.8.0-apple-x86_64 --output bark ``` **2. Mark the binary as executable** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} chmod +x bark ``` **3. Add bark to your PATH** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} sudo cp bark /usr/local/bin/ ``` **Windows** Download bark: ```PowerShell theme={"theme":{"light":"github-light","dark":"github-dark"}} wget https://gitlab.com/ark-bitcoin/bark/-/releases/bark-0.8.0/downloads/bark-0.8.0-windows-x86_64.exe -OutFile bark.exe ``` > [!NOTE] > > When using Windows, replace `bark` with `bark.exe` in the rest of the commands in this tutorial. ### Verify installation Verify you have the correct version installed: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} bark --version ``` You should see: `bark 0.8.0` > [!TIP] > > **Seeing an older version?** > > If you see a different version number, you likely have an older `bark` installation from previous testing. This happens due to PATH conflicts where your system finds the old binary before the new one. > > To fix this, find where the old binary is located: > > ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} > which bark > ``` > > Then remove the outdated binary: > > ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} > sudo rm $(which bark) > ``` > > After removing the old version, verify the installation again with `bark --version`. ## Compile from source **1. Clone the repository** Clone the code from the repository. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} git clone https://gitlab.com/ark-bitcoin/bark cd bark ``` **2. Install Rust** You also need a Rust compiler. The [rustup website](https://rustup.rs) offers installation instructions for almost any platform. **3. Install dependencies and build** Download additional dependencies using your package manager. **Ubuntu/Debian** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} apt update apt install build-essential clang protobuf-compiler ``` **Fedora/CentOS** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} yum install gcc make clang protobuf-compiler ``` **macOS** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} brew install gcc make llvm@14 protobuf ``` **Windows** ```PowerShell theme={"theme":{"light":"github-light","dark":"github-dark"}} winget install protobuf ezwinports.make LLVM.LLVM ``` **Nix** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} # This assumes you have enabled some experimental features in nix. nix develop ``` You can build the code using `cargo`. The `cargo build` command will only build the binary. The `cargo install` command will build the binary and add it to your path. **build** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} cargo build --bin bark ./target/debug/bark --version ``` **build and install** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} cargo install --locked --path ./bark-cli --bin bark bark --version ``` **4. Verify installation** Run `bark --version` to verify that the installation completed successfully. # Test on mainnet Source: https://second.tech/docs/getting-started/bark-cli/mainnet Connect Bark to Second's mainnet Ark server. Step-by-step guide to create a mainnet wallet, fund it over Lightning, and make real payments with `bark`. Once you've [tested on signet](/docs/getting-started/bark-cli/signet), testing on mainnet is the same flow with real bitcoin, on [Second's mainnet Ark server](/docs/connection-details). ![Bytes adventure](https://mintcdn.com/second-0659a37d/RWnzip6U_h0J6sse/images/bytes-adventure.svg?fit=max\&auto=format\&n=RWnzip6U_h0J6sse\&q=85\&s=cbf99cbab3769af24642c84c113c8446) > [!WARNING] > > Mainnet uses real bitcoin. Start with small amounts while you get familiar with the tooling. Your seed phrase alone can recover your balance with the Ark server's cooperation, but it can't restore payment history or the state of any in-progress exits. Save your seed phrase and [set up continuous backups](/docs/backups) of your wallet's data directory. Don't store more than you're willing to lose. > [!TIP] > > Building on mainnet? Head to [chat.second.tech](https://chat.second.tech) and ping Neil (982572) to get a dedicated support channel set up for your team. Slack and Signal are also available on request. ## Create your wallet **1. Verify Bark is installed** To ensure that `bark` is installed, run `bark --version`. Follow the [installation instructions](/docs/getting-started/bark-cli) if you need to. **2. Create a new mainnet wallet** Create a wallet pointed at Second's mainnet Ark server. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} bark create --mainnet --ark https://ark.second.tech ``` **3. Check your balance** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} bark balance ``` You should see all balances at zero: ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "spendable_sat": 0, "needs_refresh_sat": 0, "pending_lightning_send_sat": 0, "claimable_lightning_receive_sat": 0, "pending_in_round_sat": 0, "pending_board_sat": 0, "pending_arkoor_send_sat": 0, "pending_offboard_sat": 0, "pending_exit_sat": 0 } ``` ## Add bitcoin to your wallet The quickest way to fund your wallet is to send bitcoin from any Lightning wallet. **1. Generate a BOLT11 invoice** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} bark ln invoice "10000 sats" ``` **2. Pay the invoice** Pay the invoice from your preferred Lightning wallet, and the sats will arrive in your Ark wallet instantly. **3. Confirm your VTXOs** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} bark vtxos ``` The output will look something like: ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} [ { "id": "7d53e2c1e57c4c40dbe942c9a040c95e92db7c4486b2faf9163804097fa165bc:0", "amount_sat": 10000, "policy_type": "pubkey", "user_pubkey": "025577f6f44237f4c334b50c257c8feab6ff89d5591db2aff0ffee5c7bef7c03db", "server_pubkey": "02f0f358c1b6173ddecec1ad06b42d3762f193e6ff98a3e112292aec21129f9f6b", "expiry_height": 966276, "exit_delta": 144, "chain_anchor": "0527dd37c19a2084ab99dc8db59e5d527d9cbb62ebb535e9b1c4bf5323c8210c:0", "exit_depth": 3, "state": { "type": "spendable" } } ] ``` > [!TIP] > > You can also receive via an Ark payment or by [boarding](/docs/learn/board) instead. Learn more about [Ark payments](/docs/learn/payments). ## Make a Lightning payment **1. Get a BOLT11 invoice** Using a separate Lightning wallet, generate a BOLT11 invoice, or ask a friend or colleague to generate one. **2. Pay the invoice** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} bark send ``` Replace `` with the full invoice string. The payment is routed over Lightning, so anyone with a Lightning wallet can receive it. ## Make an Ark payment If you have a friend or colleague on the same Ark server, you can also make an Ark payment. **1. Get an Ark address** Ask them for their Ark address. **2. Send some sats** ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} bark send " sats" ``` Replace `` with their Ark address and `` with the number of sats to send. **3. Verify the payment** Run `bark vtxos` again to see your new VTXO (change from the payment). ## Refresh your VTXOs Your VTXOs have a [limited lifetime](/docs/learn/lifetime) and must be periodically refreshed in a [round](/docs/learn/rounds). Unlike our signet server, which runs a round every 5 minutes for testing, the mainnet server runs rounds much less frequently, so a refresh may take longer to confirm. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} bark refresh --all ``` The `bark` CLI requires you to refresh manually. [Wallet apps built on the Bark SDK](/docs/built-with-bark) typically automate refreshes for users. ## Getting your money out, aka offboarding You can offboard your bitcoin back to a regular on-chain UTXO. This is the cheapest and fastest way to leave Ark. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} bark offboard --all ``` If the Ark server is uncooperative, you can always perform an [emergency exit](/docs/getting-started/bark-cli/advanced) instead. For more on how offboarding works, see [Offboarding](/docs/learn/offboard) in the Learn section. ## Start building Now that you have a feel for how fast payments are across both Lightning and Ark, you're ready to start building. There are two integration paths depending on your use case: > **[Bark SDK](/docs/bark-sdk)** > > For mobile and desktop apps where users hold their own keys. > **[Barkd](/docs/barkd)** > > For exchanges, e-commerce, and services where you manage bitcoin. ## Share your feedback You've now made some of the first ever Bark transactions on mainnet across both Lightning and Ark. We're excited to see what you build! [Let us know](https://community.second.tech) if there are any more guides you'd like to see, and please share any feedback on the developer experience. # Test on signet Source: https://second.tech/docs/getting-started/bark-cli/signet Test Ark with free signet bitcoin: create a wallet with `bark`, get coins from the faucet, board the Ark, and make your first off-chain payments. Signet is a bitcoin test network where coins are free and plentiful. It provides a good opportunity to test Ark without risking real money. In this tutorial you will use `bark` to send and receive signet coins using the Ark protocol. ## Create your wallet **1. Verify Bark is installed** To ensure that `bark` is installed, run `bark --version`. Follow the [installation instructions](/docs/getting-started/bark-cli) if you need to. **2. Create a new signet wallet** The first step is to create a new signet wallet. You need to tell the wallet the URL of your Ark server and where it can find chain data. > [!NOTE] > > Use `bark --help` to see what the command-line program can do. For example, when you want to create a wallet, running `bark create --help` will give you more info. Esplora is the easiest chain source to configure. But you can also use your own signet node if you prefer. **Esplora** Don't switch the Esplora instance. We are running a version that includes package relay which will be [merged in soon](https://github.com/Blockstream/electrs/pull/119). ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} bark create --signet --ark https://ark.signet.2nd.dev --esplora https://esplora.signet.2nd.dev ``` **bitcoind (cookie)** This requires `bitcoind` v29.0 or greater. Your node must use the `-txindex` option. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} bark create --signet --ark https://ark.signet.2nd.dev --bitcoind --bitcoind-cookie ``` **bitcoind (user/pass)** This requires `bitcoind` v29.0 or greater. Your node must use the `-txindex` option. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} bark create --signet --ark https://ark.signet.2nd.dev --bitcoind --bitcoind-user --bitcoind-pass ``` > [!TIP] > > **Getting an error about unexpected data directory contents?** > > If you see an error like `Datadir has unexpected contents: ~/.bark/db.sqlite`, you likely have a wallet built from an earlier version of Bark. Wallets aren't always backward compatible between versions, so you'll need to remove the old data and create a fresh wallet: > > ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} > rm -rf ~/.bark > ``` > > Then run the `bark create` command above again. ## Board the Ark and see your balance increase **1. Check your balance** Let's check your balance. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} bark balance ``` Oh, you are broke! Let's fix that! **2. Get your Ark address** To receive money on Ark you need to share your Ark address which you can find using the following command. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} bark address ``` **3. Get sats from the faucet** You can get sats using [our signet faucet](https://signet.2nd.dev/). You will need to authenticate using your GitHub account and provide the address you obtained above. ![Screenshot of the Ark signet faucet interface](https://mintcdn.com/second-0659a37d/8VZedF7eKiQd6Pfy/images/faucet.jpg?fit=max\&auto=format\&n=8VZedF7eKiQd6Pfy\&q=85\&s=8d12d5a250b9086b35876f1cd0e0631d) signet.2nd.dev **4. Confirm your bitcoin** Check your balance again to confirm you have received the bitcoin. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} bark balance ``` Congratulations! You have boarded the Ark. Notice that you received the balance instantly and you didn't need to pay any transaction fees. ## Inspect your VTXOs Your Ark wallet manages [VTXOs](/docs/learn/vtxo) (virtual transaction outputs) instead of regular UTXOs. You can inspect your newly received VTXO. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} bark vtxos ``` You should see something like: ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} [ { "id": "7d53e2c1e57c4c40dbe942c9a040c95e92db7c4486b2faf9163804097fa165bc:0", "amount_sat": 59888, "policy_type": "pubkey", "user_pubkey": "025577f6f44237f4c334b50c257c8feab6ff89d5591db2aff0ffee5c7bef7c03db", "server_pubkey": "02f0f358c1b6173ddecec1ad06b42d3762f193e6ff98a3e112292aec21129f9f6b", "expiry_height": 271138, "exit_delta": 12, "chain_anchor": "498b069e3259c85cf99c236ff62f69ce645c3ebaa05ba0b9610f0f0a4895546c:0", "exit_depth": 3, "state": { "type": "spendable" } } ] ``` ## Refresh in a round VTXOs have a [limited lifetime](/docs/learn/lifetime) and must be periodically refreshed in a [round](/docs/learn/rounds). Our signet Ark server runs a round every 5 minutes for testing, but be aware that production servers will run rounds much less frequently. When you run the `refresh` command, you have to wait until the next round starts. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} bark refresh --all ``` Run `bark vtxos` again to confirm your old VTXO has been replaced by a new one with a different `id` and a later `expiry_height`. The `bark` CLI requires you to refresh manually. [Wallet apps built on the Bark SDK](/docs/built-with-bark) typically automate refreshes for users. ## Spend your money and buy a treat for Byte **1. Create an order** We'd like you to buy our mascot, Byte, a treat. You can order one in our [signet test store](https://signet.2nd.dev/store). ![Screenshot of the Ark signet store](https://mintcdn.com/second-0659a37d/Dul0-LNCv3q1_9fs/images/store.jpg?fit=max\&auto=format\&n=Dul0-LNCv3q1_9fs\&q=85\&s=91628febfd8103bb3aba71a4c530ec64) signet.2nd.dev/store **2. Pay the invoice** After you create an order, the shop gives you a BOLT11 invoice. Pay it using the following command. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} bark send ``` You can use `bark` to pay: * a BOLT11 invoice using Lightning * an LNURL using Lightning * an on-chain address for an on-chain payment * an Ark address for a user in the same Ark ## Getting your money out, aka offboarding You can offboard your bitcoin back to a regular on-chain UTXO. This is the cheapest and fastest way to leave Ark. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} bark offboard --all ``` If the Ark server is uncooperative, you can always perform an [emergency exit](/docs/getting-started/bark-cli/advanced) instead. For more on how offboarding works, see [Offboarding](/docs/learn/offboard) in the Learn section. ## Share your feedback You've now completed testing the full lifecycle of transactions on Ark. We're excited to see what applications you come up with! [Let us know](https://community.second.tech) if there are any more guides you'd like to see, and please share any feedback on the developer experience. # Add bitcoin payments to your app with Bark Source: https://second.tech/docs/index Bark makes it simple to build fast, low-fee, self-custodial bitcoin payments into your app: one integration for Ark, Lightning, and on-chain. ## Get started > **[Quickstart guide](/docs/getting-started/bark-cli)** > > Make your first Ark payments on signet in minutes with the Bark CLI. > **[Connection details](/docs/connection-details)** > > Copy Second's mainnet and signet endpoints into your config. > **[Build a wallet app](/docs/bark-sdk)** > > For mobile and desktop apps where users hold their own keys. > **[Integrate with your server](/docs/barkd)** > > For exchanges, e-commerce, and services where you manage bitcoin. ## Learn more > **[How Ark works](/docs/learn/intro)** > > Deep dive into the mechanics of the Ark protocol. > **[Built with Bark](/docs/built-with-bark)** > > See real apps shipping bitcoin payments with Bark. > **[Latest updates](/docs/changelog/index)** > > Follow the latest features in our changelog. > **[Run an Ark server](/docs/ark-server)** > > Set up your own Ark server for testing and development. # Ark boarding Source: https://second.tech/docs/learn/board Boarding moves on-chain bitcoin onto Ark: you and the Ark server co-sign one on-chain transaction, and you receive a board VTXO that holds your Ark balance. When you board an Ark, you cooperate with the Ark server to sign a pair of on-chain/off-chain transactions that produces a [board VTXO](/docs/learn/vtxo#board-vtxos) representing your bitcoin balance within Ark. Once broadcast and confirmed, you can start making instant, low-cost bitcoin payments over Ark and Lightning. > [!NOTE] > > **Most users won't need to board** > > You won't necessarily need to board to start using Ark. After installing an Ark wallet, you can begin receiving VTXOs immediately from friends, customers, or exchanges over Lightning or Ark. Boarding is expected to be reserved to businesses and power users. ## The boarding process The boarding process follows these steps: 1. **Create transactions:** The user constructs [a pair of transactions with special spending conditions](/docs/learn/vtxo#board-vtxos) cooperatively with the Ark server: a funding transaction and an exit transaction. 2. **Pre-sign exit transaction:** Both parties pre-sign the exit transaction, which spends from the funding transaction's output. This ensures the user can always reclaim their bitcoin on-chain if needed, even without the server's cooperation. [Learn more about emergency exits](/docs/learn/exit). 3. **Broadcast:** The user broadcasts the funding transaction on-chain, and stores the pre-signed exit transaction off-chain. 4. **Wait for confirmations:** The user waits for the funding transaction to receive six confirmations. 5. **VTXO activation:** After six confirmations, the user's board VTXO becomes active and spendable within the Ark server. Their on-chain bitcoin has been moved "off-chain". This process happens [outside of the server's normal round schedule](/docs/learn/rounds)—users don't need to wait for a round to initiate or complete their boarding. ![Diagram showing how the board process relates to a board VTXO](https://mintcdn.com/second-0659a37d/IZIYL7kfKRS394NE/images/board-process.svg?fit=max\&auto=format\&n=IZIYL7kfKRS394NE\&q=85\&s=cce53e95b3c1942c4886390596e96a26) The boarding process: User creates a board VTXO cooperatively with the Ark server ### Atomic boarding guarantee The board transaction is atomic—either both the on-chain funding and VTXO creation succeed together, or both fail together. There's no intermediate state where the server could hold the user's bitcoin without the user receiving a valid VTXO in return. The transaction structure itself achieves this atomicity: the funding transaction that spends the user's on-chain bitcoin also creates the VTXO tree that grants the user emergency exit rights. ## Boarding fees Users face two cost components when boarding: * **On-chain funding fee:** Users will pay standard bitcoin network transaction fees to broadcast the board transaction. These fees fluctuate based on blockspace demand and are paid to the bitcoin network, not the Ark server. * **Future on-chain sweep fee:** Each [board VTXO](/docs/learn/vtxo#board-vtxos) will inevitably require the Ark server to make another on-chain transaction to sweep after expiry, and the Ark server will need to make sure this future cost is covered. * **Ark server fees:** The Ark server may charge additional fees to cover general operational costs. Unlike refreshes, boarding doesn't require the Ark server to deploy [liquidity](/docs/learn/liquidity) since users provide the bitcoin upfront through the funding transaction, therefore there are no liquidity costs. See [Second's pricing](https://second.tech/pricing) for current fees. # Ark emergency exits Source: https://second.tech/docs/learn/exit Emergency exits are how you move your bitcoin back on-chain from Ark without server cooperation. Learn when exits are needed, how the process works, and costs. Every VTXO contains pre-signed transactions that let you unilaterally reclaim your bitcoin on the base layer—this is what makes Ark self-custodial. Under normal conditions, users should always use the more efficient [offboarding](/docs/learn/offboard) process. Emergency exits are reserved for situations where the server is unresponsive or refuses to cooperate. ## When are emergency exits required? Emergency exits serve as an emergency mechanism that ensures users always maintain control over their bitcoin regardless of server behavior. This backup measure is fundamentally what makes Ark self-custodial. > [!NOTE] > > **Emergency exits from different VTXO types** > > * **Board and standard refresh VTXOs:** Emergency exits are unilateral. Users can exit without any possibility of prevention by the server or other parties, as long as the exit fully confirms before [the VTXO expires](/docs/learn/lifetime#what-happens-when-vtxos-expire). > * **Spend VTXOs:** While users can independently broadcast emergency exit transactions, the exit can be prevented if the sender and Ark server collude to double-spend. The exit succeeds if it fully confirms before the VTXO expires and either the sender or the server acts honestly. Users can eliminate this trust assumption by refreshing their spend VTXOs in a round. Under normal operating conditions, users should always follow the standard offboard process when moving bitcoin from Ark back on-chain. Standard offboarding is more efficient and cost-effective for getting bitcoin back on-chain. Emergency exits should only be considered when the server is unresponsive or refuses to honor offboard requests. These situations typically fall into three categories: ### 1. Malicious behavior The Ark server may be acting maliciously, attempting to withhold or effectively steal user bitcoin by refusing to process legitimate offboard requests. ### 2. Technical difficulties The server might experience technical problems preventing normal operation. While these issues can be expected to be temporary, users can still face urgency if they hold VTXOs that are approaching expiry. ### 3. Legal constraints Legal or regulatory actions may prevent an Ark server from processing certain transactions. In these cases, the server might be legally restricted from honoring offboard requests for specific users or regions. ## The emergency exit process When a user or their wallet app triggers an emergency exit, they must broadcast a sequence of transactions from their VTXO's transaction tree in the correct order. Each transaction in this sequence must confirm before the next can be broadcast, making this a multi-step process that requires careful coordination. The exit process follows these steps: 1. **First branch transaction:** The wallet app broadcasts the first branch transaction in their VTXO's path from the root of the transaction tree. 2. **Wait for confirmation:** Once confirmed, the wallet app broadcasts the next branch transaction in the sequence. 3. **Continue down the tree:** This process continues, broadcasting each branch transaction and waiting for confirmation, until reaching the leaf. 4. **Broadcast exit transaction (leaf):** The last transaction in the tree, the *exit transaction*, is broadcast. Once the exit transaction is broadcast and confirmed, the user's bitcoin is on-chain and will never expire. However, spending this bitcoin still requires the Ark wallet database—losing this data without [a backup of your wallet data](/docs/backups) would mean permanently losing access to the exited bitcoin. To make the bitcoin spendable with standard backup methods (like a seed phrase), users must broadcast a *claim transaction* after the exit transaction's relative timelock expires. This timelock countdown begins when the exit transaction confirms, giving the Ark server and other users time to respond to any malicious exit attempts (trying to exit a VTXO that [has already been forfeited](/docs/learn/forfeits#how-forfeits-work) or spent). ![A diagram showing the order of operations for completing an exit and claim](https://mintcdn.com/second-0659a37d/rf2uS0kylw5VUHtT/images/emergency-exit-process.svg?fit=max\&auto=format\&n=rf2uS0kylw5VUHtT\&q=85\&s=8132b8d090033fdd6e6f876e4e0964b2) An example of the complete exit and claim process ### Automated wallet management Users should never need to manage the emergency exit process manually. Well-designed wallet apps should automate the entire sequence once an exit is triggered. The wallet app will: * Monitor the blockchain for transaction confirmations * Automatically broadcast the next transaction in sequence once the previous one confirms * Track block height to determine when the relative timelock becomes valid * Execute the final exit transaction to complete the process > [!NOTE] > > **Claims may not be automatic** > > Whether the claim process is included as part of the default emergency exit process depends on each wallet app's exit policy and settings. ## Cost of emergency exits A users performing an emergency exit must pay on-chain transaction fees for each transaction in the exit sequence. The total on-chain fees depend on their refresh VTXO's transaction tree depth, which is determined by the number of VTXOs refreshed in the associated round, plus the length of any additional spend VTXO chain. > [!WARNING] > > **Economic viability of emergency exits** > > If the balance held in a VTXO is less than the total on-chain fees required to broadcast all exit transactions, it may not be economically viable to recover those bitcoin. However, as explained in the [early vs. late exit section below](#how-early-exits-reduce-costs-for-later-exiters), other users performing exits from the same round can reduce your exit costs—each transaction another user broadcasts reduces the number of transactions you need to complete by one. ## Partially-completed exits An exit is not completed until the final exit transaction (leaf) of the transaction tree is broadcast and confirmed on-chain. At any point before that, the bitcoin can still be considered held in the Ark—the VTXO will expire according to its original lifetime and become sweepable by the Ark server. This gives emergency exits a degree of "cancellability". For instance, a user might begin an exit because an Ark server goes offline for an extended period. If the Ark server comes back online after the user broadcasts the branch transactions that make up their VTXO, they can choose to abort broadcasting the final transaction and keep their bitcoin in the Ark. Partially completed exits increase the costs for the Ark server to sweep the bitcoin after forfeit and expiry. With the round transaction broken up into multiple smaller transactions, the Ark server must pay multiple on-chain transaction fees to sweep the bitcoin, instead of the typical one. ## How early exits reduce costs for later exiters When users initiate emergency exits, their actions benefit other users that have participated in the same round(s). This occurs because VTXOs share common branches in the transaction tree. When a user broadcasts a branch transaction as part of their exit, they reduce the number of transactions needed by other users on the same branch by one. In scenarios where many users need to exit, those who exit earlier effectively reduce the exit costs for those who exit later. ## Managing exits during high fee periods When network fees increase significantly, situations may arise where a VTXO's value becomes smaller than the cost to exit. This raises important considerations for the Ark protocol. ### Server-side Ark servers are unlikely to monitor or restrict transactions based on economic exit viability: * Exit viability varies based on multiple factors beyond just VTXO value * Users have different risk tolerances and fee preferences * The protocol should remain neutral to economic conditions ### Client-side Wallet apps should instead implement the appropriate safeguards for users. Options include: * Warning notifications when a VTXO may cost a significant percentage of the VTXO value to exit * Exit fee estimation tools to help users make informed decisions * Options to delay exits to allow other users to exit earlier (thus reducing exit costs) # Ark fees Source: https://second.tech/docs/learn/fees How Ark fees work, why they vary with VTXO lifetime, and the different ways an Ark server can charge for refreshes, Ark, Lightning, and on-chain payments. Second's Ark server offers transparent, predictable pricing that scales with the size of payments. Holding bitcoin on Ark costs nothing as long as your wallet app refreshes each VTXO during the last two days of its [lifetime](/docs/learn/lifetime). For the current fee schedule, see [Second's pricing page](https://second.tech/pricing). ## Each Ark server will have its own fee model Fee models will differ from server to server. Fees are a matter of policy, not hardcoded into the protocol, and server operators have multiple levers to customize their pricing. One thing is for sure: any Ark server **must** charge fees (in some way or another) to cover their operational costs. The primary costs an Ark server will incur are: ### Direct costs * **Liquidity costs:** The opportunity cost of capital deployed for [liquidity operations](/docs/learn/liquidity) (e.g., refreshes, Lightning payments, and on-chain payments). * **On-chain fees:** The transaction fees required to confirm refreshes and on-chain payments on the bitcoin network. * **Lightning routing fees:** The server covers routing fees for off-Ark Lightning payments. ### Indirect costs * **Development costs:** The cost of ongoing software development—adding features, optimizing performance, supporting integrations, and fixing bugs. * **Server operating costs:** The real-world infrastructure costs of running a high-performance, high-uptime server. ## Approaches to charging fees Broadly, there are two ways Ark servers can approach structuring fees: * **Direct cost-based fees:** Each operation is priced based on its actual cost to the server. Ark payment fees would be low, while Lightning payments and refreshes would vary based on VTXO age and current on-chain feerates. This ensures the server cannot run at a loss, since every action covers its true cost. * **Abstracted fees:** The server cross-subsidizes between operations to offer more predictable pricing—for example, charging higher fees for Ark payments to subsidize lower refresh costs, or offering flat rates. This improves the user experience but requires careful design to ensure total costs are covered. Second adopts a hybrid approach. # Ark forfeits Source: https://second.tech/docs/learn/forfeits Forfeits ensure Ark operations are atomic and prevent malicious exits. Learn how they work alongside connectors and hash-locks. Forfeits are pre-signed transactions used in [refreshes](/docs/learn/rounds) and [on-chain payments](/docs/learn/payments-on-chain) to grant the Ark server control over the [VTXOs](/docs/learn/vtxo) being spent. The server holds forfeit transactions off-chain as a safeguard against malicious exits. Forfeits are used in combination with hash-locks or connectors to provide cryptographic assurance that the forfeit is only valid if the intended operation completes. This allows users to safely sign forfeit transactions without trusting any third party—ensuring the associated operations are atomic, self-custodial, and without counterparty risk. * **Forfeits + hash-locks** [for refreshes](/docs/learn/rounds#round-atomicity). * **Forfeits + connectors** [for on-chain payments](/docs/learn/payments-on-chain#atomic-guarantee) (including [offboards](/docs/learn/offboard)). > [!NOTE] > > **Connectors replaced by hash-locks for refreshes** > > As of [version 0.1.0-beta.6](/docs/changelog#23-january-2026), Bark uses hArk (Hash-lock Ark), which achieves refresh atomicity through hash-locks instead of connectors. Connectors are now used exclusively for on-chain payments and offboards. > [!NOTE] > > **Ark and Lightning payments don't use forfeits** > > [Ark](/docs/learn/payments) and Lightning payments don't involve forfeiting a VTXO. > > In Ark payments, the user pre-signs a new off-chain transaction with the Ark server that extends the leaf of an existing VTXO, creating a [spend VTXO](/docs/learn/vtxo#spend-vtxos). > > In Lightning payments, the user relies on HTLC-based spending policies to ensure atomic execution. ## How forfeits work If you are familiar with penalty transactions in the Lightning Network, you should already have a good idea of how forfeits on Ark work. To support forfeits, each VTXO's [exit transaction](/docs/learn/vtxo) (leaf) has two spend paths: * **Spend path 1:** A 2-of-2 multisig between the user and the Ark server. The user signs this path to create a forfeit transaction granting the VTXO to the server. This path has no timelock—if the exit transaction ever makes it on-chain, the server can broadcast the forfeit before the user claims the bitcoin. * **Spend path 2:** Controlled solely by the user for emergency exits. This path has a relative timelock of 144 blocks (approximately 24 hours), implemented using OP\_CHECKSEQUENCEVERIFY (CSV). ![Diagram of the spend paths in an exit output](https://mintcdn.com/second-0659a37d/92YUTFvK58wCxpgQ/images/spend-paths-leaf.svg?fit=max\&auto=format\&n=92YUTFvK58wCxpgQ\&q=85\&s=d6beff7efd682586fac36516c2be6656) Spending conditions in an exit output (leaf) that enable forfeits ### Forfeits usually never make it on-chain Under normal operations, neither spend path is used. The server simply sweeps the entire round transaction once its absolute timelock expires. The forfeit is held as insurance—only used if a user attempts an exit after forfeiting. ### Preventing malicious exits If a user attempts a malicious exit after forfeiting, they must broadcast their VTXO's branch transactions and then wait for the relative timelock on the leaf before claiming. The timelock (around 24 hours) gives the server ample time to detect the attempt and broadcast the pre-signed forfeit first. ## How hash-locks work for rounds For rounds, Bark uses hash-locks instead of connectors. During a round, the server generates a secret (known as a preimage) for each new VTXO and shares its hash with participants. Both the new VTXO and the user's forfeit transaction are constructed with a hash-lock condition—neither can be used on-chain without providing the preimage. ![Diagram showing how a hash-lock makes a forfeit transaction conditional on the server revealing the preimage](https://mintcdn.com/second-0659a37d/rf2uS0kylw5VUHtT/images/forfeit-hashlock.svg?fit=max\&auto=format\&n=rf2uS0kylw5VUHtT\&q=85\&s=5c76e5bc38ca6d2a57c081e5d24ee130) The hash-lock ensures the forfeit is only valid once the server reveals the preimage. The user can safely sign the forfeit without knowing the preimage, since the forfeit cannot be executed until the preimage is revealed. After signing, the server reveals the preimage, granting the user access to their new VTXO. If the server withholds the preimage, the user can still unilaterally exit their old VTXO—the hash-locked forfeit cannot be executed without it, so the server cannot prevent the exit. The only way the server could block the exit is by broadcasting the forfeit, but doing so reveals the preimage on-chain, which in turn gives the user access to their new VTXO. Either way, the user cannot lose bitcoin. This approach also enables non-interactive round participation, which is essential for [delegated refreshes](/docs/learn/rounds#delegated-refreshes) on some mobile devices. ## How connectors work for on-chain payments Connectors ensure that a user's forfeit is only valid if the corresponding on-chain payment is confirmed. The server constructs the payment transaction with both the destination output and a connector output. Because the user's forfeit requires the connector output to exist, the forfeit cannot be used unless the corresponding payment transaction is confirmed first. ![Diagram showing how a forfeit transaction cannot be confirmed until the payment transaction is confirmed on-chain](https://mintcdn.com/second-0659a37d/rf2uS0kylw5VUHtT/images/forfeit-connector-payment.svg?fit=max\&auto=format\&n=rf2uS0kylw5VUHtT\&q=85\&s=58fd58280237d8f921b8c9a7dfabac88) The connector ensures the forfeit is only valid once the payment transaction is broadcast. This makes on-chain payments and offboards atomic: either the payment completes and the forfeit is valid, or neither happens. # Ark protocol glossary Source: https://second.tech/docs/learn/glossary Definitions for the Ark terms you'll meet across these docs: VTXOs, rounds, exits, arkoor, connectors, and more. Here's a brief reference guide to the terms and concepts used in the Ark protocol. Terminology can vary across different organizations, so bear in mind these are specific to Second's implementation of the Ark protocol. | Term | Description | | - | - | | Ark server | A central server that coordinates rounds, helps with boarding and offboarding, deploys liquidity, and enables users to transact over the Lightning Network. The Ark server does not custody any user bitcoin. | | arkoor | Short for "Ark out-of-round"—the method used for [Ark payments](/docs/learn/payments). Arkoor transactions create [spend VTXOs](/docs/learn/vtxo#spend-vtxos). | | Board transaction | The on-chain funding transaction created when a user boards onto Ark. Once confirmed, it serves as the chain anchor for the resulting VTXO. | | Boarding | The process of getting bitcoin onto an Ark. A user co-signs a special type of funding transaction with the Ark server and broadcasts it. Once confirmed, the resulting transaction represents the creation of a new *VTXO*. | | Branch | A series of interdependent, off-chain transactions that break up the round transaction into successively smaller chunks until a user's Ark balance is released. Each branch transaction can only be broadcast after the preceding branch transaction has been broadcast. | | Chain anchor | The on-chain transaction output that a VTXO's validity depends on. For in-round VTXOs this is an output of the round transaction; for boarded VTXOs it is an output of the board transaction. The chain anchor must be confirmed on-chain for the VTXO to be spendable. | | clArk | Short for "covenant-less Ark"—an implementation variant that uses recursive multisigs instead of CTV covenants. Each node policy contains a multisig with all the public keys of all the leaves below it, plus the server key. | | Connector | A mechanism that ensures forfeit transactions are only valid if a specific on-chain payment is broadcast. Used in [on-chain payments](/docs/learn/payments-on-chain) and [offboards](/docs/learn/offboard). For rounds, connectors have been replaced by hash-locks. | | Delegated refresh | [Refreshing VTXOs by having designated co-signers sign on the user's behalf](/docs/learn/rounds#delegated-refreshes), designed for mobile devices that cannot reliably wake during scheduled round windows. Requires trusting that at least one designated co-signer behaves honestly. | | Exit transaction | A transaction that releases a user's bitcoin on-chain, at the leaf of a transaction tree. Used when a user wants to retrieve their bitcoin from the Ark protocol. | | Lifetime | The time limit set on VTXOs that requires users to spend or refresh their VTXOs before they expire. Once a VTXO expires, the Ark server can sweep the bitcoin on-chain and an emergency exit is no longer possible. The user can still refresh the VTXO, offboard it, or send it over Lightning with the server's cooperation, but can't send it as an Ark payment. On Second's Ark server, a standard VTXO lifetime is 28 days (server-configurable parameter). | | Forfeit transaction | A transaction that allows a user to give up ownership of their VTXO. It uses one of the two spending paths in an exit transaction and grants all bitcoin to the Ark server. Used in refreshes and offboards. | | hArk | Short for "Hash-lock Ark"—[a protocol enhancement introduced in January 2026](/docs/changelog#23-january-2026) that enables delegated refreshes for mobile devices and streamlines the refresh process. | | In-round | A term used for VTXOs that are included in the transaction tree embedded in the round transaction. All refreshed VTXOs are in-round. | | Leaf | The final transaction in a branch, releasing a user's bitcoin on-chain. See *exit transaction*. | | Lightning gateway | A Lightning node connected to the Ark server that enables users to transact with the broader Lightning Network and users on other Ark servers. | | Malicious exit | An attempt by a user to broadcast VTXO transactions on-chain (initiate an emergency exit) after forfeiting them. Should always fail due to [timelocks securing exits](/docs/learn/forfeits). | | Movement | A wallet-level operation that changes the state of one or more VTXOs—such as a round participation, arkoor payment, board, offboard, exit, or Lightning send/receive. A movement is created when the operation starts, locks any affected VTXOs while in progress, and transitions to a final status (successful, failed, or canceled) when the operation completes. | | Offboarding | The standard, cooperative process of withdrawing bitcoin from Ark. A user forfeits one or more VTXOs and receives an output for the same amount on-chain. | | Refresh | The process of [forfeiting old VTXOs for new ones](/docs/learn/rounds#round-process) during an Ark round, before their lifetime ends. The wallet app participates interactively during the round, signing its own exit branches in the transaction tree. See also [delegated refresh](/docs/learn/rounds#delegated-refreshes) for mobile devices that cannot reliably wake during scheduled rounds. | | Root | The single on-chain transaction that all associated branch and leaf transactions emanate from. For in-round VTXOs, this is the round transaction; for boarded VTXOs, it is the board transaction. See *chain anchor*. | | Round | A periodic event initiated by the Ark server where users can refresh their VTXOs. Only users participating in the refresh have their VTXOs included in the round transaction. | | Round transaction | The root transaction of a transaction tree that is broadcast on-chain during an Ark round. This transaction provides users with verifiable assurance that they can unilaterally retrieve their bitcoin on-chain. | | Sweep | The process by which the Ark server transfers all remaining bitcoin from an expired round to its operational wallet, including the bitcoin in VTXOs their owners never refreshed. Usually requires only a single on-chain transaction, because the whole round still sits in one output of the round transaction. If any user in the round has started or completed an emergency exit, the broadcast branch transactions split the round's bitcoin across more on-chain outputs. The server must then sweep more outputs and pay more in on-chain fees. | | Transaction tree | A hierarchical structure of transactions that enables UTXO-sharing. It consists of a root transaction (broadcast on-chain), branch transactions, and leaf transactions, allowing multiple users to share a single on-chain UTXO while maintaining control of their bitcoin. | | Transaction tree depth | The number of transactions a user must broadcast to complete an emergency exit. For a refresh VTXO, this is determined by the number of branch layers in the tree, which scales logarithmically with the number of users in the round. Each spend VTXO in a chain adds to the exit length. | | Emergency exit | The non-standard, non-cooperative process of withdrawing bitcoin from Ark. The user independently broadcasts each off-chain transaction from their VTXO in sequence, until the bitcoin is delivered to an address they solely control. The availability of emergency exits guarantees that users maintain self-custody of their bitcoin. Sometimes shortened to "exit". | | VTXO | Short for "virtual unspent transaction output" or "virtual UTXO". A series of off-chain, pre-signed transactions that a user can broadcast at any time to retrieve their bitcoin on-chain in an emergency. VTXOs have a limited lifetime and must be refreshed periodically. | # Intro to the Ark protocol Source: https://second.tech/docs/learn/intro A brief primer for the basic concepts of the Ark protocol. Learn the mechanics of how Ark makes bitcoin payments fast, cheap, and self-custodial. The Ark protocol is a second layer on the bitcoin network. It offers: simple boarding, low and predictable fees, instant payments, Lightning interoperability, and full control over your bitcoin. The Ark protocol works on bitcoin today and doesn't require any new opcodes or changes in consensus rules. ## Client-server The protocol centers around an *Ark server*. Users connect to the server to transact with one another directly over Ark. Ark users can also transact with the broader Lightning Network via the server's *Lightning gateway*. ![Diagram showing the client-server architecture of Ark, with users connecting to an Ark server](https://mintcdn.com/second-0659a37d/IZIYL7kfKRS394NE/images/client-server-second.svg?fit=max\&auto=format\&n=IZIYL7kfKRS394NE\&q=85\&s=70ac9462dc210c803ac5d146987e836f) ## VTXO-based scaling Ark introduces a new scaling model based on [virtual UTXOs (VTXOs)](/docs/learn/vtxo). A VTXO is a series of off-chain, pre-signed transactions that a user can broadcast at any time to retrieve their bitcoin on-chain in an emergency. Under normal operating conditions, these off-chain transactions will never be broadcast on-chain, and users will instead *offboard* from the Ark protocol cooperatively with the Ark server. Although VTXOs are structurally more complex under the hood, they are based on the UTXO model and for the most part function in the same manner—anything you can do with a UTXO, you can do with a VTXO. ![Diagram illustrating a board VTXO, showing the structure of the simplest type of VTXO in the Ark protocol](https://mintcdn.com/second-0659a37d/IZIYL7kfKRS394NE/images/board-vtxo.svg?fit=max\&auto=format\&n=IZIYL7kfKRS394NE\&q=85\&s=563daec3b4525d2781b507a80481381d) A board VTXO, the simplest type of VTXO ## Round-based The Ark server [initiates and coordinates rounds](/docs/learn/rounds) on a periodic basis. Second's Ark server conducts rounds every hour. In each round, users can *refresh* their VTXOs—forfeit old VTXOs for new ones. Not all users of an Ark participate in every round. Only the users participating in the refresh have their VTXOs included in the round transaction. ![Example of a one-hour round frequency](https://mintcdn.com/second-0659a37d/92YUTFvK58wCxpgQ/images/round-interval.svg?fit=max\&auto=format\&n=92YUTFvK58wCxpgQ\&q=85\&s=0dee3863956e07f06d8b883249183e74) A one-hour round interval results in a round transaction being confirmed roughly every six blocks ## Transaction trees During a round, the Ark server and users together [construct a transaction tree](/docs/learn/vtxo#transaction-trees). Each *leaf* of the tree (also known as an *exit transaction*) is controlled by a single user and corresponds to a single VTXO. The *root* of the tree is broadcast on-chain and is known as a *round transaction*. Once the round transaction is confirmed, each user has verifiable assurance that they can unilaterally retrieve their bitcoin on-chain. ![Diagram of a transaction tree showing how VTXOs are structured with overlapping branches, with the root committed to the blockchain and a refresh VTXO highlighted](https://mintcdn.com/second-0659a37d/rf2uS0kylw5VUHtT/images/refresh-vtxo.svg?fit=max\&auto=format\&n=rf2uS0kylw5VUHtT\&q=85\&s=ecbf8b018cd2cb200b6c9dc2b5cf91b6) An example transaction tree, with root committed to the blockchain, and a refresh VTXO highlighted ## VTXO lifetime VTXOs must be refreshed on an ongoing basis because [VTXOs have a limited lifetime](/docs/learn/lifetime). This is required by the protocol to enable the Ark server to claim all forfeited bitcoin in an expired round using a single on-chain transaction (*"sweeping"*), instead of many small transactions. Each VTXO includes a built-in expiry that's set at creation. Users (or rather, their wallet apps) must spend or refresh their VTXOs before they expire. Once a VTXO expires, the Ark server can sweep its bitcoin, and [recovering it depends on the server's cooperation](/docs/learn/lifetime#what-happens-when-vtxos-expire). On Second's Ark server, VTXOs are created with a 28 day lifetime. ![Diagram of an Ark server sweeping an expired round to its own wallet](https://mintcdn.com/second-0659a37d/rf2uS0kylw5VUHtT/images/round-sweep.svg?fit=max\&auto=format\&n=rf2uS0kylw5VUHtT\&q=85\&s=4ea199ec9b135b66f9ae77606619f290) VTXO lifetime is what enables an Ark server to replace deployed liquidity in a single on-chain transaction ## Liquidity Unlike Lightning, [Ark users don't need to manage liquidity](/docs/learn/liquidity)—the Ark server takes care of this for them. The Ark server must maintain liquidity for several operations, with refreshes being the most common. During a refresh, a user forfeits an old VTXO for a new one. The bitcoin in the forfeited VTXO will not be available to the Ark server until it expires, while the new VTXO requires immediate on-chain bitcoin for inclusion in the round transaction's tree. This creates a temporary capital requirement for the Ark server, which will translate into user fees. This is reflected in [Second's pricing](https://second.tech/pricing): refreshing newer VTXOs costs more, while refreshing VTXOs closer to the end of their lifetime costs less. Other liquidity-demanding operations include Lightning and on-chain payments. Ark payments don't require liquidity. ![Diagram of how Ark liquidity works](https://mintcdn.com/second-0659a37d/rf2uS0kylw5VUHtT/images/liquidity-refresh.svg?fit=max\&auto=format\&n=rf2uS0kylw5VUHtT\&q=85\&s=5e5fa41d0cb39ffd0eff239bcc0897a5) Ark servers face the capital costs of funding current rounds while waiting for the timelocks of previous rounds to expire. ## Boarding To get bitcoin onto an Ark, a user co-signs a funding transaction with the Ark server and broadcasts it. The user does not need to wait for a round, but does need to wait for one or more on-chain block confirmations to complete the boarding. Importantly, new users do not need to go through the boarding process. They can start receiving VTXOs immediately (from someone else that has) upon setting up a wallet. ## Offboarding Ark is an optimistic protocol. Under normal operations, users will withdraw bitcoin from Ark [using offboarding, not emergency exits](/docs/learn/exit), which should be reserved for exceptional circumstances. To offboard, a user cooperates with the Ark server to [forfeit their VTXO(s)](/docs/learn/forfeits) and receive an output to an on-chain bitcoin address of their choice. Like most processes on Ark, the offboard is atomic, so neither the Ark server nor the user are exposed to counterparty risk. ## Emergency exits The availability of emergency exit is the key feature of the Ark protocol that puts users in total control of their off-chain bitcoin. However, emergency exits are expected to be reserved for emergency situations—e.g., the Ark server becomes unresponsive. To perform an emergency exit, a user broadcasts the pre-signed transactions that make up their VTXO in sequence, from root to branch to leaf. Each of these transactions breaks up the round transaction into successively smaller chunks until the user's bitcoin is released to their own on-chain address. Since users' VTXOs share branches in the transaction tree, each user's emergency exit reduces the number of transactions required for subsequent users to complete their own emergency exits. ## Ark payments Users can make Ark payments to other Ark users of the same server at any time, they don't have to wait for a round. The receiver obtains a new [spend VTXO](/docs/learn/vtxo#spend-vtxos) that extends directly from the sender's leaf in the transaction tree. ![A spend VTXO chained from a board VTXO](https://mintcdn.com/second-0659a37d/92YUTFvK58wCxpgQ/images/spend-vtxo.svg?fit=max\&auto=format\&n=92YUTFvK58wCxpgQ\&q=85\&s=90d8f8c1a1e4cf2151d69a109e869192) A spend (arkoor) VTXO chained from a board VTXO Because Ark payments bypass rounds entirely, they have zero liquidity costs and near-instantaneous settlement. However, there is a temporary trust trade-off: the receiver assumes that the sender and Ark server don't collude to double-spend. As long as either the sender or server is honest, the payment is secure. And the receiver can [refresh](/docs/learn/rounds) the VTXO in any subsequent round to restore the standard Ark trust model. ## Lightning payments Ark users can send and receive [Lightning payments](/docs/learn/payments-lightning) via the Ark server's Lightning gateway. Users spend VTXOs to pay Lightning invoices and receive incoming Lightning payments as new VTXOs—no channels, inbound liquidity, or routing management required. Both directions use HTLCs to ensure payments are atomic. ![Diagram showing the Ark server acting as a Lightning gateway between user VTXOs and the Lightning Network](https://mintcdn.com/second-0659a37d/IZIYL7kfKRS394NE/images/lightning-gateway-send.svg?fit=max\&auto=format\&n=IZIYL7kfKRS394NE\&q=85\&s=e8e48c7b66deb03db7a5203b1467dfb2) The Ark server acts as a Lightning gateway, handling all channel and routing management for users ## Beyond the basics Now you're up to speed with the fundamentals, it's time to dive deeper! Whether you're a developer looking to integrate with Ark or simply exploring the protocol's design, we hope the following sections provide you the technical depth needed to fully understand Ark's approach to bitcoin scaling. # VTXO lifetime Source: https://second.tech/docs/learn/lifetime VTXOs have a limited lifetime in the Ark protocol. Understand how VTXO lifetime works and how wallet apps and servers should manage expiries. All VTXOs have a limited lifetime that determines when the server can claim any remaining bitcoin. Understanding VTXO lifetime is crucial for maintaining control of your bitcoin. On Second's Ark server, VTXOs created by [boards](/docs/learn/board) and [refreshes](/docs/learn/rounds) have a 28 day lifetime, while VTXOs from [Lightning receives](/docs/learn/payments-lightning#receiving-a-lightning-payment) have a lifetime between 1-3 days. Both are server-configurable parameters. ## What happens when VTXOs expire? An expired VTXO is not lost, but its owner can only recover the bitcoin with the server's cooperation: | Operation | After expiry | | - | - | | [Refresh](/docs/learn/rounds) | Possible | | [Lightning send](/docs/learn/payments-lightning#sending-a-lightning-payment) | Possible | | [On-chain send](/docs/learn/payments-on-chain) or [offboard](/docs/learn/offboard) | Possible | | [Ark send](/docs/learn/payments) | Not possible | | [Emergency exit](/docs/learn/exit) | Not possible | Every VTXO's [transaction tree](/docs/learn/vtxo#transaction-trees) has a [timelocked spend path](/docs/learn/vtxo#transaction-spend-paths) that unlocks at the expiry height. Once it unlocks, the server sweeps the underlying on-chain bitcoin to its own wallet. The sweep spends the root output that the user's pre-signed exit transactions depend on, rendering them invalid and preventing new Ark payments from being chained onto them. Refreshes, Lightning sends, and on-chain sends remain possible because they don't rely on extending the transaction tree. The VTXO has already returned to the server's liquidity pool, and the server settles bitcoin over Lightning or on-chain. As normal, any of these operations depends on the server's cooperation. Without emergency exits available, the user has no remedial options if the server does not cooperate. Therefore users should use wallet apps that always keep their VTXOs refreshed. ![Diagram of an Ark server sweeping an expired round to its own wallet](https://mintcdn.com/second-0659a37d/rf2uS0kylw5VUHtT/images/round-sweep-annotated.svg?fit=max\&auto=format\&n=rf2uS0kylw5VUHtT\&q=85\&s=536e310e8d4f14f1ab18f5dba8aa5b84) Once the VTXOs in a round have expired (simultaneously), the Ark server sweeps the round transaction to its own wallet ## Avoiding expiry A wallet app has four ways to keep a VTXO from expiring: * **Refresh:** The default method. The wallet app forfeits the VTXO in a [round](/docs/learn/rounds) and receives a new one with a fresh lifetime, automatically and in the background. [Delegated refreshes](/docs/learn/rounds#delegated-refreshes) ensure mobile wallet apps can do this even while they're asleep. * **Spend over Ark:** The recipient receives a [spend VTXO](/docs/learn/vtxo#spend-vtxos) that inherits the original expiry, and with it the responsibility to refresh. The server accepts Ark payments from a VTXO right up to its expiry height, so a recipient's wallet app may need to refresh a received VTXO almost immediately. * **Spend over Lightning or on-chain:** The wallet app forfeits the VTXO and the server delivers the payment [over Lightning](/docs/learn/payments-lightning#sending-a-lightning-payment) or [on-chain](/docs/learn/payments-on-chain) in an atomic operation. The recipient holds bitcoin outside Ark, with no VTXO to refresh, and the forfeited bitcoin returns to the server's [liquidity](/docs/learn/liquidity) once the round is swept. * **Emergency exit:** If the server stops cooperating, the wallet app broadcasts the VTXO's [exit transactions](/docs/learn/exit#the-emergency-exit-process) to claim the bitcoin on-chain. The exit must fully confirm before the expiry height. Reserved for emergencies: it is slow and costs on-chain fees. In practice, users shouldn't need to worry about VTXO lifetime as long as their wallet app comes online regularly. Well-designed wallet apps should implement automated policies to prevent expiry, such as automatically refreshing VTXOs that approach an expiry threshold and prioritizing older VTXOs for spending. # Ark liquidity Source: https://second.tech/docs/learn/liquidity Ark servers deploy bitcoin upfront for refreshes, on-chain payments, and Lightning payments. Learn how liquidity works and the underlying economics. When users perform operations that require on-chain bitcoin—like refreshes, offboards, and Lightning payments—the Ark server must deploy bitcoin upfront while waiting to sweep equivalent amounts from spent VTXOs [after they expire](/docs/learn/lifetime). This is known as *liquidity*, and it creates ongoing capital requirements on the Ark server that fundamentally shape the protocol's economics and fee structures. Unlike Lightning, where users are ultimately responsible for their own (channel) liquidity, Ark shifts the liquidity management burden entirely to the Ark server, relieving users of this complexity (although they'll still need to cover the liquidity costs). ![Diagram of how liquidity works](https://mintcdn.com/second-0659a37d/rf2uS0kylw5VUHtT/images/liquidity-refresh.svg?fit=max\&auto=format\&n=rf2uS0kylw5VUHtT\&q=85\&s=5e5fa41d0cb39ffd0eff239bcc0897a5) Simplified example of Ark liquidity in action: Users refresh expiring VTXOs. The server deploys 10 BTC immediately to fund new VTXOs, but must wait for the old round's timelock to expire before reclaiming the 10 BTC from the forfeited VTXOs—creating a temporary capital requirement. ## Liquidity-requiring vs liquidity-free operations ### Liquidity-requiring operations These operations require Ark servers to deploy bitcoin upfront (while waiting for spent VTXOs to expire before sweeping equivalent amounts): * **Refreshes:** The most common liquidity operation. Users forfeit old VTXOs and receive new ones with a fresh lifetime. * **Offboarding:** Moving bitcoin back on-chain via a cooperative withdrawal from the Ark server. * **Lightning payments:** The server delivers bitcoin payments through the Lightning Network, via the *Lightning gateway*. ### Liquidity-free operations * **Ark payments:** Payments between Ark users [happen out-of-round](/docs/learn/payments) and require no liquidity—they simply extend existing [transaction trees](/docs/learn/vtxo#transaction-trees). * **Emergency exits:** Users broadcast their VTXO's pre-signed transactions, requiring no server involvement or liquidity provision. ## Liquidity costs and economics To provide liquidity for Ark users, servers must maintain a bitcoin treasury—a reserve of bitcoin ready to deploy for user operations. This creates an economic trade-off that's fundamental to understanding liquidity costs. ### The opportunity cost principle The bitcoin in an Ark server's treasury could potentially earn returns if deployed elsewhere—such as in Lightning channels to earn routing and liquidity fees, or lent out through bitcoin lending platforms. When an Ark server locks up bitcoin to provide liquidity on Ark, it foregoes these alternative earning opportunities. This foregone earning potential is called the *opportunity cost*. Ark servers earn revenue primarily through payment and liquidity fees. Servers will naturally try to ensure their total fee revenue equals or exceeds what they could earn elsewhere, otherwise they become uncompetitive with other bitcoin investment opportunities. > [!NOTE] > > **Ark opportunity costs are bitcoin-denominated** > > Ark servers must refer to market rates for bitcoin-denominated returns—these will look quite different from the USD market. ### How liquidity costs are calculated Liquidity costs depend on three factors: 1. **Amount:** The bitcoin value being refreshed or offboarded 2. **Remaining lifetime:** How long until the spent VTXO expires and becomes claimable 3. **Opportunity cost:** The server's bitcoin-denominated cost of capital (expected annual return on bitcoin holdings) The formula is: `amount × (expiry_delta ÷ 365 days) × opportunity_rate = liquidity_cost` #### Example > [!NOTE] > > **Napkin math** > > These are rough calculations to give you a sense of scale—actual fees fluctuate according to market conditions. A user refreshes a 100,000 sat VTXO that has 5 days until expiry, assuming the opportunity cost is 5% annually: ``` 100,000 sats × (5 days ÷ 365 days) × 5% = 68 sats liquidity cost ``` > [!NOTE] > > **Refreshes also require on-chain fees** > > Refresh operations also require on-chain transaction fees. If 100 users refresh in a round and the bitcoin network charges 500 sats for the transaction, then the on-chain cost per user is around \~5 sats. So the total refresh cost in the above example would be around 73 sats (68 + 5) to refresh 100,000 sats (0.07%). ### VTXO age affects costs * **Fresh VTXOs:** Recently created VTXOs have higher refresh costs because servers deploy liquidity for longer periods. * **Old VTXOs:** [VTXOs](/docs/learn/vtxo) nearing the end of their [lifetime](/docs/learn/lifetime) cost significantly less to refresh since servers only deploy liquidity for shorter periods. [Ark fees](/docs/learn/fees) must reflect these server costs, naturally incentivizing users to refresh closer to the end of their VTXO's lifetime while still allowing earlier refreshes for those who prefer immediate security. ## Ark's capital efficiency Ark achieves high capital efficiency through two key factors: * **Precise liquidity usage:** Users consume exactly the amount of liquidity they need for their specific operations, when they need it, with no pre-funding required. This differs from Lightning, where channels must be pre-funded with capacity by either the user or their LSP. * **No behavior prediction required:** Servers deploy liquidity on-demand as users perform operations, eliminating the need to predict user behavior or pre-allocate capacity. Lightning requires predicting user payment flows to size channels appropriately, while Ark dynamically responds to actual usage patterns. ## Managing liquidity constraints We expect it'll be unlikely that servers run out of liquidity—if they're generating consistent bitcoin returns, capital allocators will be interested in funding them. If there's no interest, it suggests the server is underpricing liquidity fees. However, as liquidity constraints are still a possibility, servers should prepare for this scenario by anticipating shortages before they happen. Since all VTXO expiry information is known in advance, servers can see liquidity demands coming and plan accordingly. When approaching constraints, servers should calculate exactly how much bitcoin is required for urgent requests—refreshing or offboarding VTXOs that are about to expire—and reserve sufficient liquidity to cover these critical operations. They can then decline non-urgent requests, such as early refresh requests that would push liquidity below required minimums. Servers that experience frequent liquidity shortages will see their reputation damaged and revenue decline as users seek alternatives. As always, users retain the option to perform an emergency exit regardless of a server's liquidity status. # Ark offboarding Source: https://second.tech/docs/learn/offboard Withdraw bitcoin from Ark back to your own on-chain wallet. Offboarding is a cooperative process and more efficient than emergency exits. Offboarding is the standard, cooperative way to withdraw bitcoin from Ark back to your own on-chain wallet. Users should always prefer offboarding over [emergency exits](/docs/learn/exit)—emergency exits should be reserved for situations where the Ark server is unresponsive. The offboarding mechanism is identical to [on-chain payments](/docs/learn/payments-on-chain). On-chain payments are for paying third parties and will use whatever combination of VTXOs (including partial VTXOs) is needed to complete the payment. Offboarding is for withdrawing bitcoin to your own wallet—either a specific whole VTXO or your entire Ark balance. ## Offboard vs. emergency exit | | Offboard | Emergency exit | | - | - | - | | **Server cooperation** | Required | Not required | | **Cost** | Single on-chain transaction | Multiple on-chain transactions | | **Speed** | One transaction to confirm | Multiple sequential transactions to confirm | | **Use case** | Normal withdrawals | Server unresponsive | If the server is unresponsive, [users can fall back to an emergency exit](/docs/learn/exit). While more expensive and slower, emergency exits guarantee users can always access their bitcoin without server cooperation. ## Offboarding fees Offboarding fees are the same as [on-chain payment fees](/docs/learn/payments-on-chain#on-chain-payment-fees). # Ark payments Source: https://second.tech/docs/learn/payments Payments on Ark are instant and require no liquidity. Learn about the temporary trust model and how refreshing improves security. Payments on **Ark** are handled **o**ut-**o**f-**r**ound (arkoor), enabling: * Instant payments at any time * Offline receiving capability * No liquidity requirements During a payment, a user works with the Ark server to create a new VTXO—a [spend VTXO](/docs/learn/vtxo#spend-vtxos)—that spends from one of their existing VTXOs. ## The payment security trade-off Handling payments out-of-round comes with a trade-off: until a receiver refreshes their received balance, they must trust that the sender and Ark server don't collude to double-spend. Refreshing converts spend VTXOs into [refresh VTXOs](/docs/learn/vtxo#refresh-vtxos) with improved security guarantees. ### Users have control over their preferred security model This mechanism allows users to control their balance between cost and security: * **Early refreshes** improve security but increase wallet operating costs. * **Later refreshes** save costs but temporarily reduce security (users must still always refresh before their VTXOs expire). This trade-off is only ever temporary. Refreshing a spend VTXO converts it to a refresh VTXO with the standard trust model, and since all VTXOs must be refreshed before they expire, every spend VTXO returns to the standard trust model within its lifetime. Second's VTXO lifetime is 28 days (a server-configurable parameter). Users can also eliminate security concerns by spending the VTXO via Ark, Lightning, or offboard transactions. ### Incentives against double-spending Until a spend VTXO is refreshed, several strong deterrents exist against sender-server collusion: * **Inevitable disclosure:** Users can always detect double-spending when multiple recipients attempt to refresh, offboard, or perform an emergency exit. Wallets can detect invalid duplicate signatures immediately and potentially trigger automatic alerts or remedial actions. Duplicate signatures can easily be publicly proven. * **Irreparable reputational damage:** An Ark server caught double-spending would lose credibility and revenue as users quickly offboard or exit to avoid further risk. * **Requires sender and server collusion:** Payments remain secure as long as at least one party (either sender or Ark server) remains honest. Even when both actors are malicious, they must closely coordinate for double-spending to succeed. * **Mutually-assured destruction:** Any attempted emergency exit from a double-spent VTXO should trigger immediate detection by user wallets, prompting competing emergency exit transactions. The resulting transaction fee race would likely consume the entire VTXO amount in miner fees. ### Expected user behavior It's difficult to predict what user behavior will look like once Ark is in the wild. At Second we expect that most users will be comfortable leaving all received payments until their VTXOs are close to expiring before refreshing. This is especially likely on Ark servers that have built a reputation for reliable operations. The rationale is that users will prefer to take advantage of the cost savings from fewer refreshes and lower [liquidity costs](/docs/learn/liquidity). Additionally, users will likely only hold a portion of their bitcoin holdings on Ark as a kind of "checking account." Only recently received payments would be subject to the spend VTXO trust model—the rest of their Ark balance will be in refresh VTXOs. However, users may prefer more sophisticated refresh thresholds and timing strategies, for example: * **Small payments:** For day-to-day transactions, users accept the temporary trust model and wait until their VTXOs are nearly expired before refreshing, prioritizing cost savings over immediate security improvements. * **Large payments:** For significant amounts, users may refresh immediately after receiving payment, prioritizing security over cost optimization. Whatever the case, wallet refresh policies should be passive and automatic, handled by the wallet app based on user settings. Users shouldn't be required to monitor individual VTXOs manually! ## Payment chains Payments can be chained, where a received spend VTXO is subsequently spent to another user. This creates [arkoor chains](/docs/learn/vtxo#spend-vtxo-chains) where users must trust that no sender in the chain has colluded with the Ark server to double-spend. Longer chains increase exit costs and expand the trust surface area, so wallet apps may want to limit chain lengths based on user preferences. ## Change handling in payments When making payments, the sender will typically also receive [change back as a spend VTXO](/docs/learn/vtxo#spend-vtxo-change). Change inherits the trust properties of the VTXO it was spent from. For example, if a user is spending from a refresh VTXO, the change received is inherently trustless since the sender cannot collude against themselves to double-spend. # Lightning payments Source: https://second.tech/docs/learn/payments-lightning Send and receive Lightning payments from your Ark wallet app, with the Ark server as the Lightning gateway and HTLCs keeping payments atomic. Ark users can transact with anyone on the Lightning Network. An Ark wallet app can pay Lightning invoices and addresses, receive Lightning payments, and interact with any Lightning-enabled wallet app, exchange, or service. The user retains full control of their bitcoin throughout. On Bark, Lightning connectivity is built directly into the protocol. The Ark server operates its own Lightning node(s) and acts as a gateway between Ark users and the Lightning Network. Users hold VTXOs at rest and spend them to make Lightning payments. This eliminates the usual complexity of Lightning for users and developers: channel management, inbound liquidity, payment routing, and rebalancing are all handled by the Ark server. Users don't even need an on-chain transaction to start making Lightning payments. A new user can receive VTXOs—from other Ark users or via incoming Lightning payments—and begin transacting over Lightning immediately. ![Diagram showing the Ark server acting as a Lightning gateway between user VTXOs and the Lightning Network](https://mintcdn.com/second-0659a37d/IZIYL7kfKRS394NE/images/lightning-gateway-send.svg?fit=max\&auto=format\&n=IZIYL7kfKRS394NE\&q=85\&s=e8e48c7b66deb03db7a5203b1467dfb2) The Ark server acts as a Lightning gateway, handling all channel and routing management for users > [!NOTE] > > **Most Bark-based payments will be Lightning payments** > > [Ark payments](/docs/learn/payments) require both sender and receiver to share the same Ark server. Until individual Ark servers build significant user bases, most payments from Ark wallets will be routed over Lightning. Lightning reaches anyone on the network, regardless of what wallet app or service they use. ## Ark HTLCs Both outgoing and incoming Lightning payments on Ark use [HTLCs (hash time-locked contracts)](https://bitcoinops.org/en/topics/htlc/) to ensure atomic execution. An HTLC locks bitcoin with two possible outcomes: it can be claimed by revealing a secret (the *preimage*), or it returns to the sender after a timeout. HTLCs are integral to how the Lightning Network routes payments across the network. ## Sending a Lightning payment When you send a Lightning payment, you spend one of your VTXOs to an HTLC. The Ark server routes the payment to the recipient over the Lightning Network using its own channels. The HTLC serves a similar role to the [forfeit](/docs/learn/forfeits) used in [on-chain payments](/docs/learn/payments-on-chain): it's an off-chain transaction that the server holds as a safeguard, ensuring you can't reclaim the VTXO after the payment has been delivered. ### The send process 1. **Initiate payment:** You provide a Lightning invoice or address to pay. 2. **Construct HTLC:** Your wallet app and the Ark server cooperate to spend one of your VTXOs into an HTLC—a conditional off-chain output that locks the payment amount until the Lightning payment succeeds or fails. 3. **Route payment:** The Ark server routes the payment over the Lightning Network to the recipient. 4. **Settle:** The server obtains the preimage from the Lightning Network and provides it to you as proof of payment. ![Diagram of the HTLC spend paths and revocation path for sending a Lightning payment](https://mintcdn.com/second-0659a37d/rf2uS0kylw5VUHtT/images/lightning-spend.svg?fit=max\&auto=format\&n=rf2uS0kylw5VUHtT\&q=85\&s=fe224e7e81f25816f22039724dbc8c1b) A Lightning payment's HTLC structure and the revocation path used if a payment fails ### Trust model for Lightning send When a Lightning payment is delivered successfully, none of the HTLC's spend paths are used. Like a [forfeit](/docs/learn/forfeits), the HTLC is held off-chain as a safeguard against malicious exits. The server simply sweeps the round transaction when it expires. The spend paths only come into play when something goes wrong: | HTLC spend path | Scenario | How it works | | - | - | - | | **1. Cooperative revocation** | Payment fails | The server has no preimage and cannot claim your bitcoin. The server co-signs a revocation, returning your bitcoin. | | **2. Server safeguard** | User attempts a malicious exit | If the user attempts to exit on-chain after the Lightning payment has been successfully delivered, the server can claim the bitcoin by revealing the preimage before the user's timelock expires. | | **3. User safeguard** | Payment fails and server is uncooperative | If the payment was not delivered and the server stops cooperating, you can reclaim your bitcoin after the timelock expires via an [emergency exit](/docs/learn/exit). | The preimage is what makes Lightning sends atomic: it only exists if the Lightning payment was delivered, and without it the server cannot prevent you from reclaiming your bitcoin. ## Receiving a Lightning payment On Bark, you can receive Lightning payments from anyone on the Lightning Network. No channels or inbound liquidity are required. The incoming bitcoin is delivered as a VTXO, so bitcoin at rest are always held in VTXOs, not Lightning channel balances. ### The receive process 1. **Generate invoice:** Your wallet app generates a preimage and payment hash on-device, then sends the hash to the Ark server. The server returns a Lightning invoice for the sender to pay. 2. **Incoming payment:** A sender pays the invoice. The payment routes through the Lightning Network and arrives at the Ark server, secured by the preimage. The server sends your wallet app a notification that a payment has been received. 3. **HTLC prep:** Your wallet app comes online and requests an HTLC from the server. The server constructs the HTLC—funded from its VTXO pool and locked to your preimage—then shares it with your wallet app. 4. **HTLC claim:** Your wallet app verifies the HTLC, then reveals the preimage to the server. The server verifies the preimage and completes the payment via an [arkoor transfer](/docs/learn/payments). You receive a VTXO. Steps 3 and 4 are performed back-to-back once your wallet app comes online. ### Trust model for Lightning receive The receive HTLC has three spend paths, each covering a different scenario: | HTLC spend path | Scenario | How it works | | - | - | - | | **1. Cooperative claim** | Server completes the claim | You reveal the preimage and the server co-signs on the cooperative path, completing an [arkoor payment](/docs/learn/payments) from the HTLC to you. You receive a [spend VTXO](/docs/learn/vtxo#spend-vtxos). | | **2. Server safeguard** | User fails to reveal preimage | If you receive the signed HTLC but don't reveal the preimage, and then attempt a malicious exit from the HTLC, this path enables the server to claim back the bitcoin. Even if you can broadcast spend path 3 ("user safeguard") before spend path 2's absolute timelock expires, the preimage will be revealed on-chain, allowing the server to claim the bitcoin from the inbound Lightning payment. | | **3. User safeguard** | Server fails to complete the claim | If, after you cooperatively reveal the preimage, the server does not complete the arkoor payment from the HTLC, you can initiate an emergency exit via this path. The server safeguard has an absolute timelock which ensures that you have a sufficient window to broadcast your claim first. | To fund Lightning receive HTLCs, the server maintains a pool of its own VTXOs. When your wallet app requests an HTLC, the server spends one of these VTXOs into the HTLC, signs it with an ephemeral key—a temporary signing key generated for that specific HTLC—then deletes the key before sharing the signed transaction with you. ![Diagram of the receive HTLC spend paths funded from the server's VTXO pool](https://mintcdn.com/second-0659a37d/rf2uS0kylw5VUHtT/images/lightning-receive.svg?fit=max\&auto=format\&n=rf2uS0kylw5VUHtT\&q=85\&s=9a686ad3e1b22476d6c7f1a20051cfdb) Because the HTLC is funded from the server's own bitcoin, you are trusting that the server actually deleted the ephemeral key. If retained, the server could double-spend the HTLC input. To improve the security of a received payment, [refresh](/docs/learn/rounds) in any subsequent round to upgrade it to a standard [round VTXO](/docs/learn/vtxo#refresh-vtxos). Lightning receive VTXOs have a much shorter [lifetime](/docs/learn/lifetime) than the standard 28 days. The server creates its pool VTXOs with a lifetime of three days (432 blocks) and never funds a receive from a pool VTXO with less than one day (144 blocks) remaining. A Lightning receive VTXO therefore arrives with one to three days until expiry. [This keeps refresh costs low](/docs/learn/rounds#round-economics). > [!NOTE] > > **A failed claim currently requires a prompt manual exit** > > Bark no longer starts emergency exits automatically when a Lightning receive claim fails. If the server doesn't complete the claim after your wallet app reveals the preimage, Bark retries a few times over the course of a minute or two, then logs a warning and leaves the receive pending. Nothing more happens on its own. Your wallet app has to treat the receive as failed and call `attempt_lightning_receive_exit` in the Bark SDK, either automatically once retries are exhausted or through a control it exposes to you. > > Without the exit, a dishonest server could use the revealed preimage to claim the incoming Lightning payment for itself. It could then take the HTLC's bitcoin back through the server safeguard once its timelock expires. What matters is the deadline, not the number of retries. The claim can be retried for as long as the HTLC still has enough time left to complete an exit, roughly 180 blocks, and your wallet app should start the exit before that point. In the worst case, an HTLC granted at the minimum allowed expiry leaves only two blocks (about 20 minutes) of slack after the claim first fails. > > Bark previously started exits on Lightning receive failures automatically, but transient claim failures triggered unnecessary exits, so we disabled the behavior. We are working on making claims more robust, and intend to reinstate the automatic exit once that work has proven itself. ### Offline receive, online invoice generation On Bark, Lightning payments can be received when offline. Your wallet app does not need to be online when the sender pays. Any HTLC from an inbound Lightning payment is secured by your invoice's preimage. However, you do need to be online for invoice generation, which is an interactive process with the Ark server, and you do need to come online before the Lightning HTLC expires to claim the payment. ## Lightning payment fees ### Sending Sending a Lightning payment involves several cost components: * **Liquidity costs:** The Ark server must [deploy bitcoin](/docs/learn/liquidity) to route the payment over the Lightning Network. Costs depend on the payment amount and the server's cost of capital. * **Lightning routing fees:** Standard Lightning Network routing fees for the payment's path through the network. * **Ark server fees:** The Ark server may charge additional fees to cover operational costs including Lightning node infrastructure. ### Receiving Receiving Lightning payments is currently free. See [Second's pricing](https://second.tech/pricing) for current fees. # On-chain payments Source: https://second.tech/docs/learn/payments-on-chain Pay to any on-chain address from your Ark wallet. Learn how on-chain payments work and how they differ from Ark and Lightning payments. On-chain payments allow users to send bitcoin from their Ark wallet directly to any on-chain address. [Offboarding](/docs/learn/offboard) uses this same process—the distinction is that offboards specifically refer to withdrawing whole VTXOs (or an entire Ark balance) back to the user's own on-chain wallet. ## How on-chain payments work When making an on-chain payment, the user cooperates with the Ark server to forfeit one or more VTXOs to deliver an on-chain output to the recipient's address. This process is atomic—neither the user nor the Ark server are exposed to counterparty risk. ### The on-chain payment process 1. **Request payment:** The user indicates to the Ark server that they want to make an on-chain payment, specifying the recipient's address and the amount. 2. **Construct transaction:** The server constructs an on-chain transaction with the requested output and a [connector](/docs/learn/forfeits) output. If the payment amount doesn't exactly match the user's VTXO(s), any change is returned as a new VTXO. 3. **Check and sign:** The user confirms that the requested output is present, then signs [forfeit transactions](/docs/learn/forfeits) linked to the connector. 4. **Broadcast transaction:** The server signs and broadcasts the on-chain transaction. 5. **Wait for confirmation:** The recipient's bitcoin eventually confirms on the blockchain. ### Atomic guarantee The connector in step 2 ensures atomicity. Because the user's forfeit is linked to the connector output, the forfeit is only valid once the payment transaction is broadcast. Either the payment completes and the forfeit is valid, or neither happens, eliminating any possibility of either party losing bitcoin during the operation. ## Confirmation timing On-chain payments are broadcast immediately upon completion. However, unlike [Ark payments](/docs/learn/payments) and Lightning payments (which are near-instant), the recipient must wait for the transaction to confirm on the blockchain. Confirmation speed depends on the on-chain fee selected by the user or wallet app. > [!NOTE] > > **On-chain payments are no longer processed in rounds** > > Previously, on-chain payments were handled during rounds. Following the [hArk update in January 2026](/docs/changelog#23-january-2026), on-chain payments are now processed immediately when initiated. ## On-chain payment fees On-chain payments on Bark involve several cost components: * **Liquidity costs:** The Ark server must [immediately deploy bitcoin to fund the on-chain output](/docs/learn/liquidity) and wait for the forfeited VTXO(s) to expire before it can sweep the bitcoin. Costs depend on the amount paid, VTXO age, and the server's cost of capital. * **On-chain fee:** The cost of confirming the transaction on-chain. * **Ark server fees:** The Ark server may charge additional fees to cover general operational costs. See [Second's pricing](https://second.tech/pricing) for current fees. # Ark rounds Source: https://second.tech/docs/learn/rounds Users refresh their Ark VTXOs in periodic rounds to extend their lifetime and/or improve security. Learn how rounds work and their coordination process. Rounds are the heartbeat of an Ark server—periodic events where users can refresh their VTXOs to extend their lifetime. During a round, multiple users coordinate with the Ark server to forfeit old VTXOs and receive new [refresh VTXOs](/docs/learn/vtxo#refresh-vtxos) in return. This is achieved through a collaborative signing process, where, together with the server, users create a transaction tree (a hierarchical structure of pre-signed transactions) and broadcast its root on-chain—the *round transaction*. ![Diagram of a transaction tree produced during a round](https://mintcdn.com/second-0659a37d/rf2uS0kylw5VUHtT/images/round-transaction-tree.svg?fit=max\&auto=format\&n=rf2uS0kylw5VUHtT\&q=85\&s=65f0436ecc6228071d13b2d679f52c27) A simplified example of the kind of transaction tree that is produced during a round > [!NOTE] > > **Payments now occur out-of-round** > > Early Ark protocol proposals included payments within rounds, but this is no longer the case. Second's implementation of Ark handles all payments instantly through [arkoor (out-of-round) transactions](/docs/learn/vtxo#spend-vtxos). Rounds are now reserved for refreshes only. ## What rounds accomplish Users participate in rounds for two main reasons: * **Lifetime management:** Refreshing a VTXO that is nearing the end of its lifetime to extend it and maintain control of their bitcoin. * **Security upgrade:** Converting [spend VTXOs](/docs/learn/vtxo#spend-vtxos) (which have additional trust requirements) into refresh VTXOs with improved security. ## Round process Refreshing requires the wallet app to participate interactively with other users and the Ark server during the round, signing its own branches in the transaction tree. Once the round confirms, the resulting refresh VTXO can be exited unilaterally without relying on any third party. | Phase | Description | | - | - | | **1. Submit intent** | Wallet app comes online during round and submits VTXOs to refresh | | **2. Tree construction** | Server constructs transaction tree; wallet app signs exit branches | | **3. Funding** | Server broadcasts round transaction on-chain | | **4. Forfeit** | Wallet app signs forfeit to complete refresh | | **5. Claim** | New VTXO immediately accessible | This requires the wallet app to be online during scheduled round windows, making it suitable for always-on devices like desktops, servers, and nodes. ## Delegated refreshes Due to operating system limitations, some devices—particularly iOS devices—cannot reliably wake for scheduled round windows. Delegated signing addresses this by allowing designated co-signers to sign on the user's behalf during the round, with the wallet app claiming the new VTXO when the user next opens the app. > [!WARNING] > > **Co-signer functionality not yet available** > > Designated co-signer support has not been built out yet and while it's a priority for us, it is unlikely to be completed until after our mainnet launch. Until co-signers are added to the signing set, delegated refreshes will be dependent on the Ark server's signature only. ### How delegated signing works Rather than participating interactively during a round, the wallet app submits refresh intents ahead of time—either when the user opens the app or via a lightweight background wake. Designated co-signers then sign on the user's behalf during the round. | Phase | Delegated refresh process | | - | - | | **1. Submit intent** | Wallet app submits refresh intent ahead of time | | **2. Tree construction** | Server constructs transaction tree; designated co-signers sign on wallet app's behalf | | **3. Funding** | Server broadcasts round transaction on-chain | | **4. Forfeit** | Wallet app signs forfeit when user next opens app | | **5. Claim** | Server or co-signer reveals secret; wallet app claims new VTXO | ![Diagram of the delegated refresh process](https://mintcdn.com/second-0659a37d/rf2uS0kylw5VUHtT/images/delegated-refresh.svg?fit=max\&auto=format\&n=rf2uS0kylw5VUHtT\&q=85\&s=40e00777f2f79b210fc5e73fc58ca8bb) In a delegated refresh, co-signers sign on the user's behalf. The user collects the signed transactions when they next open their wallet. ### Delegated refresh trust model Delegated refresh VTXOs have reduced security compared to standard refresh VTXOs. Users must trust that at least one designated co-signer behaves honestly—a 1-of-n trust model. Wallet app providers and other entities act as co-signers, each signing the entire transaction tree. Security is additive: each additional co-signer strengthens the trust model for all users, regardless of which app they use. Some wallet apps will predefine a fixed co-signer set (presumably including themselves); others will let advanced users specify their own co-signer set. If a required co-signer is unavailable, the delegated refresh fails and alerts the user. Delegated refresh is entirely opt-in—a practical compromise for mobile OS limitations. With multiple co-signers and a 1-of-n trust model, it offers pretty good security. However, mobile wallet app developers should still consider providing optional alternative paths to standard refreshes, e.g., push notifications that prompt users to open the app before upcoming rounds, or companion desktop/node apps that can refresh on behalf of the mobile wallet. > [!NOTE] > > **Covenants eliminate the trust requirement** > > If a covenant proposal (like CTV or TEMPLATEHASH) were adopted on bitcoin, [delegated refreshes would become fully trustless](https://delvingbitcoin.org/t/evolving-the-ark-protocol-using-ctv-and-csfs/1602). ## Round atomicity Round atomicity is ensured through [hash-locked forfeit transactions](/docs/learn/forfeits#how-hash-locks-work-for-rounds). The server generates a preimage for each new VTXO and constructs both the new VTXO and the user's forfeit with a hash-lock condition tied to it. This guarantees that the server cannot claim the old VTXO without also revealing the preimage—which in turn gives the user access to their new VTXO. Either way, the user cannot lose bitcoin. ## Round timing and interval Second's Ark server conducts rounds every hour (round frequency is a server-configurable parameter). ![Diagram of an example one-hour round frequency](https://mintcdn.com/second-0659a37d/92YUTFvK58wCxpgQ/images/round-interval.svg?fit=max\&auto=format\&n=92YUTFvK58wCxpgQ\&q=85\&s=0dee3863956e07f06d8b883249183e74) A one-hour round interval results in a round transaction being confirmed roughly every six blocks ### Interval length trade-offs All things being equal, more frequent rounds will inevitably attract fewer participants per round since users are spread across more opportunities to refresh. Conversely, less frequent rounds lead to more participation demand per round. This fundamental relationship drives several important trade-offs: | | Shorter round interval | Longer round interval | | - | - | - | | **Wait time for refreshes** | Enables users to improve security faster or react more quickly to soon-to-expire VTXOs | Security-conscious users must wait longer for refreshes, and higher risk of VTXO expiries | | **On-chain fee sharing** | Higher per-user costs due to fewer participants splitting the round transaction fee | Lower per-user costs due to more participants splitting the round transaction fee | | **Emergency exit** | Fewer transactions to complete exit ([shallower trees](/docs/learn/vtxo#transaction-tree-scalability)) | More transactions to complete exit ([deeper trees](/docs/learn/vtxo#transaction-tree-scalability)) | > [!NOTE] > > **Flexible round scheduling** > > While Second's Ark server uses fixed periodic rounds, servers can technically implement more flexible scheduling: * **Demand-based rounds:** Queue thresholds for triggering a round * **Emergency rounds:** On-demand rounds for users with soon-to-expire VTXOs * **Scheduled maintenance:** Temporary increase in round frequency before planned downtime ## Round economics Executing rounds involves two major costs for an Ark server: 1. **On-chain transaction fee:** The cost of getting a round transaction confirmed on-chain, which is spread across all users participating in the round—the more users, the lower the cost per user. Despite the underlying transaction tree requiring an n-of-n multisig potentially involving hundreds of users, the Ark protocol uses Taproot and MuSig to make this complex script appear on-chain as a simple single-signature transaction, minimizing the blockchain footprint. 2. **Liquidity deployment costs:** When users refresh their VTXOs, the Ark server must deploy bitcoin ([liquidity](/docs/learn/liquidity)) from its wallet to fund the new outputs. The forfeited bitcoin from old VTXOs only becomes available to the server after those VTXOs expire, so there is a cost of capital to cover. This cost is independent of the number of users participating in the round, and is instead dependent on the amount of bitcoin being forfeited and the age of the VTXOs. > [!NOTE] > > Fee schedules for Second's Ark server are still being finalized, and may not directly reflect the server's costs for users' individual operations. You can read more about fee considerations on our [fees page](/docs/learn/fees). ### Simultaneous expiry All VTXOs created in a round share the same expiry time—the absolute timelock on the round transaction and all branch transactions expires simultaneously. Under normal circumstances, users will forfeit their VTXOs before expiry (through spending, refreshing, or offboarding) to retain control over their bitcoin. This means that when expiry occurs, the server can sweep the entire round's bitcoin balance to its own wallet in a single on-chain transaction, rather than needing to reclaim individual VTXOs separately. # Ark VTXOs Source: https://second.tech/docs/learn/vtxo VTXOs are the building blocks of Ark. Learn about the different types of VTXO (board, refresh, and spend VTXOs) and how transaction trees work. VTXOs (Virtual Transaction Outputs) are the fundamental building blocks of the Ark protocol. Just as UTXOs are to bitcoin, VTXOs are to Ark—they're how you hold your balance and make payments within the protocol. When you have bitcoin on Ark, that bitcoin is represented by one or more VTXOs in your wallet. When you want to send bitcoin to someone else on the same Ark server, you spend your VTXOs to create new VTXOs for the recipient—similar to how bitcoin transactions consume UTXOs to create new UTXOs. Under the hood, a VTXO is a series of pre-signed bitcoin transactions held off-chain by a user that provide the ability to create an on-chain UTXO at a later time, if required. Converting a VTXO into a UTXO can be performed without any third-party interaction, and is known as an "emergency exit". This emergency exit feature is what ensures Ark users are always in control of their bitcoin. > [!NOTE] > > **Offboards vs. exits** > > Under normal circumstances, a user that wants to move their bitcoin off Ark will instead perform an offboard or Lightning payment cooperatively with the server, by forfeiting their VTXO (instead of broadcasting it). This is more efficient and cheaper. ## VTXO types overview There are three types of VTXO in the Ark protocol. You'll receive a different type depending on the operation you're conducting: * **Board VTXO:** The simplest type, created when moving bitcoin onto Ark. Completely trustless after creation. * **Refresh VTXO:** Created during periodic server rounds. Standard refresh VTXOs share the same trust model as board VTXOs. More complex transaction trees enable cost sharing among users. * **Spend VTXO:** Created instantly for payments within Ark. Extends board and refresh VTXOs. Emergency exit requires trusting that previous senders haven't colluded with the server to double-spend. Each VTXO type uses a different transaction structure, resulting in different trust models and cost profiles. ![Diagram showing all three VTXO types side by side](https://mintcdn.com/second-0659a37d/rf2uS0kylw5VUHtT/images/vtxo-types.svg?fit=max\&auto=format\&n=rf2uS0kylw5VUHtT\&q=85\&s=b57bb6130a7cf5efe58ed35b073ea0ac) Comparison of board VTXO, refresh VTXO, and spend VTXO structures ### VTXO type comparison | | Board VTXO | Refresh VTXO | Spend VTXO | | - | - | - | - | | **Structure** | Root → Leaf (2 transactions) | Root → Branches → Leaf (3+ transactions) | Extended leaf from existing VTXO | | **Creation timing** | On-demand, needs on-chain confirmations | Periodic rounds only | On-demand, instant | | **Trust assumptions** | Trustless | Trustless | Assumes sender + server don't collude | | **Cost** | Full on-chain fee | Partial on-chain fee + liquidity | Marginal | | **Exit depth** | 2 (root + leaf) | 3+ (root + branches + leaf) | Same as source VTXO + 1 additional | | **Lifetime** | 28 days | 28 days | Inherited | | **Typical use case** | Moving bitcoin onto an Ark | Refreshing VTXOs | Sending payments | > [!NOTE] > > **VTXO types are illustrative** > > The three VTXO types are a conceptual framework to help explain the structural and trust model differences across VTXOs. They are not defined or distinguished in code—VTXOs are generally treated the same regardless of how they were created. ## Transaction trees All VTXOs are built on "transaction trees"—structures that enable multiple users to share one large on-chain UTXO while maintaining individual emergency exit rights. A transaction tree consists of pre-signed bitcoin transactions held off-chain, interconnected with strict spending conditions that create a "pseudo covenant". ![Diagram of a simple transaction tree](https://mintcdn.com/second-0659a37d/rf2uS0kylw5VUHtT/images/transaction-tree.svg?fit=max\&auto=format\&n=rf2uS0kylw5VUHtT\&q=85\&s=f62c2eeb8da5e2daca44d1e9431a7a34) A transaction tree with four users, each controlling their individual balance within one on-chain UTXO Transaction trees contain three transaction types: * **Root:** The only on-chain transaction, creating the VTXO when confirmed * **Branch:** Off-chain transactions that split the root's value among multiple users * **Leaf:** Individual exit transactions that deliver bitcoin to user-controlled addresses ### Transaction spend paths Each transaction in the tree enforces two mutually exclusive spend paths: **Spend path 1:** Cooperative multisig between users and server. Root and branch transactions use n-of-n multisigs (MuSig2) between all users sharing that branch plus the server for cooperative operations. Leaf transactions use 2-of-2 multisigs between user and server for forfeits and payments. **Spend path 2:** Timelocked recovery mechanisms. Root and branch transactions use absolute CLTV timelocks (` OP_CHECKLOCKTIMEVERIFY`), while leaf transactions use relative CSV timelocks (`<144> OP_CHECKSEQUENCEVERIFY`) for user exits. ![Diagram of a transaction tree output with two spending conditions](https://mintcdn.com/second-0659a37d/92YUTFvK58wCxpgQ/images/spend-paths-root-branch.svg?fit=max\&auto=format\&n=92YUTFvK58wCxpgQ\&q=85\&s=bd6027e27b09dede7fe06e7e66688ca7) Spending conditions in root and branch outputs The cooperative path enables normal Ark operations such as spending, refreshing, and offboarding. The timelock paths serve different purposes: root and branch timelocks allow the server to recover bitcoin after expiry to minimize liquidity costs, while leaf timelocks enable users to perform emergency exits from their VTXOs. > [!NOTE] > > **Quad tree structure** > > **The diagrams show binary trees for illustration purposes only**. The concepts remain the same, but in practice we use quad trees (each branch transaction splits into four outputs) because they minimize emergency exit costs by reducing the number of transactions a user must broadcast. ## Board VTXOs Board VTXOs are created when users first move bitcoin onto Ark, representing the simplest VTXO construction. ![Diagram of board VTXO structure](https://mintcdn.com/second-0659a37d/IZIYL7kfKRS394NE/images/board-vtxo.svg?fit=max\&auto=format\&n=IZIYL7kfKRS394NE\&q=85\&s=563daec3b4525d2781b507a80481381d) Board VTXO structure **Structure:** The simplest transaction tree with just two transactions. The root spends directly to the user's leaf transaction, skipping the branch layer entirely. **Trust model:** Board VTXOs are completely trustless from creation until expiry. Users can perform an emergency exit by broadcasting their leaf transaction. Until expiry, the server cannot prevent this unless the user has previously signed a forfeit or spend transaction. **Exit cost:** Users pay the full on-chain fee to broadcast both root and leaf transactions. **Lifetime:** By default, board VTXOs have the same [lifetime](/docs/learn/lifetime) as refresh VTXOs (28 days on Second's Ark server). However, users can theoretically set a custom lifetime during creation, though this depends on server policy. A custom lifetime could allow users to optimize for expected usage patterns—a shorter lifetime reduces costs for receivers who plan to refresh immediately. ## Refresh VTXOs Refresh VTXOs are created during Ark server rounds when users must refresh expiring VTXOs or when they want to improve security after receiving spend VTXOs. Rounds occur every hour ([a server-configurable parameter](/docs/learn/rounds)). ![Diagram of refresh VTXO structure within a transaction tree](https://mintcdn.com/second-0659a37d/rf2uS0kylw5VUHtT/images/refresh-vtxo.svg?fit=max\&auto=format\&n=rf2uS0kylw5VUHtT\&q=85\&s=ecbf8b018cd2cb200b6c9dc2b5cf91b6) Transaction tree with Alice's refresh VTXO highlighted. **Structure:** Full transaction trees with multiple branch layers. Users' VTXOs overlap with others in the tree (sharing branches but not leaves), and each user must hold pre-signed transactions for their entire path to exit. **Trust model:** Standard refresh VTXOs share the same trust model as board VTXOs. Users can perform an emergency exit by broadcasting their portion of the transaction tree. Until expiry, the server cannot prevent exits unless users have signed forfeits or spends. > [!NOTE] > > **Delegated refreshes on mobile devices** > > For mobile devices using [delegated refreshes](/docs/learn/rounds#delegated-refreshes), refresh VTXOs require trusting that at least one of the designated co-signers behaved honestly during the round. Users who require standard trust model VTXOs must perform a standard, interactive refresh. **Exit cost:** Users pay individual fees for each of their branch and leaf transactions. In emergency scenarios where many users exit simultaneously, the first user to broadcast each branch transaction saves all other users on that branch from having to broadcast the same transaction. Therefore users exiting earlier subsidize users exiting later. **Lifetime:** Refresh VTXOs have a [lifetime](/docs/learn/lifetime) of 28 days (a server-configurable parameter). Users cannot customize this lifetime—it's set by the server's round policy. > [!NOTE] > > **Users don't hold VTXOs in every round** > > One common misconception is that all users of an Ark server participate in *every* round. This is not the case. Users only hold refresh VTXOs in rounds where they personally participated. ## Spend VTXOs Spend VTXOs are created instantly when users send payments within the same Ark server, using a technique known as arkoor (Ark out-of-round). This mechanism enables immediate transfers without waiting for the next server round. Most users will receive their first Ark balances as spend VTXOs (from friends, customers, or exchanges). ![Diagram of spend VTXO structure within a transaction tree](https://mintcdn.com/second-0659a37d/92YUTFvK58wCxpgQ/images/spend-vtxo.svg?fit=max\&auto=format\&n=92YUTFvK58wCxpgQ\&q=85\&s=90d8f8c1a1e4cf2151d69a109e869192) Transaction tree with Wendy's spend VTXO highlighted. **Structure:** Spend VTXOs extend existing transaction trees by adding new leaf transactions. For emergency exit, users must broadcast all transactions in the original tree plus the additional spend transaction, increasing exit length. **Trust model:** Spend VTXOs follow the [state chain security model](https://bitcoinops.org/en/topics/statechains/). Users can still perform an emergency exit, but they must trust that the sender and server don't collude to double-spend the leaf. As long as either the server or sender acts honestly, payments are secure. [Read more on Ark's payment dynamics](/docs/learn/payments). **Exit cost:** Users must pay transaction fees for their complete exit path: all transactions from the original VTXO tree (all branches and original leaf) plus fees for each additional arkoor transaction in the spending chain. Each spend that extends the chain adds one more transaction fee to the total exit cost. For example, if you receive a spend VTXO that's already been spent twice, you'll pay fees for the original tree plus three arkoor transactions when exiting. **Lifetime:** Spend VTXOs inherit the [lifetime](/docs/learn/lifetime) of their source VTXO. Spending doesn't reset the lifetime, so receivers of "old" VTXOs must refresh sooner but pay lower immediate refresh costs because the server deploys [liquidity](/docs/learn/liquidity) for a shorter time period. Receivers of "fresh" VTXOs can wait longer before refreshing but face higher costs if they want to refresh immediately. Beyond the difference in trust model, spend VTXOs function like any other VTXO type. And the trust assumption only lasts until the VTXO is [refreshed](/docs/learn/rounds) (converts it to a standard refresh VTXO) or spent (settled over Ark, Lightning, or on-chain). ### Spend VTXO chains Spend VTXOs can be chained, with each consecutive spend increasing the exit length by one. A user receiving a spend VTXO in a chain must trust that none of the previous senders colluded with the server to double-spend. However, individual senders cannot unilaterally double-spend—this requires server cooperation. ![Diagram of a chain of spend VTXOs](https://mintcdn.com/second-0659a37d/92YUTFvK58wCxpgQ/images/spend-vtxo-chain.svg?fit=max\&auto=format\&n=92YUTFvK58wCxpgQ\&q=85\&s=c920c269ce11c873e2b1df1367766062) A spend VTXO (arkoor) chain. > [!WARNING] > > **Spend VTXO chain length considerations** > > Long chains increase exit costs and expand the trust surface area. Wallet app developers may want to consider providing users with tools to limit spend VTXO chain length. ### Spend VTXO change Like spending UTXOs on-chain, users typically spend only a portion of a VTXO, creating two new spend VTXOs: 1. **Payment:** Sent to the recipient 2. **Change:** Returned to the sender ![Diagram of spend VTXO change structure](https://mintcdn.com/second-0659a37d/92YUTFvK58wCxpgQ/images/spend-vtxo-change.svg?fit=max\&auto=format\&n=92YUTFvK58wCxpgQ\&q=85\&s=66db68a9bf7ec1607021307335aaeb08) How change works when partially spending a VTXO on Ark Spend VTXO change inherits the trust properties of its source: * **Change from trustless VTXOs:** Change from board or refresh VTXOs remains trustless since users cannot collude against themselves. * **Change from self-controlled chains:** Change remains trustless when every transaction in the chain is the user's own (change or self-sends) and the chain originates from the user's own board or refresh VTXO. * **Third-party chains:** Once other users appear in the spending chain, change inherits the same trust requirements as regular spend VTXOs—users must trust that previous senders in the chain didn't collude with the server. ### Multiple VTXOs for larger payments Users can send multiple VTXOs simultaneously to complete a single larger payment, creating multiple outputs for the receiver. This approach offers significant advantages over creating multiple small UTXOs on-chain. There are not the same downsides as doing this on-chain, where the on-chain transaction fees will linearly scale with the number of UTXOs. On the Ark protocol, the cost to send is marginal, and for the receiver, the cost to refresh is relative to the payment size and the amount of liquidity used—not the number of VTXOs being refreshed. However, there is still one trade-off: sending multiple VTXOs to complete a single payment increases the emergency exit costs for the receiver. If the receiver ever needs to perform an exit, they must broadcast an additional on-chain transaction for each spend VTXO they hold, multiplying their on-chain transaction fees accordingly. ## Transaction tree scalability Transaction trees scale efficiently with the number of users. The number of transactions a user must broadcast for an emergency exit of a refresh VTXO is one plus the number of branch layers in the tree. The number of branch layers scales logarithmically (`log base 4`) with the number of users. For example: * 4 users = 1 branch layer (2 total transactions to exit) * 16 users = 2 branch layers (3 total transactions to exit) * 64 users = 3 branch layers (4 total transactions to exit) * 256 users = 4 branch layers (5 total transactions to exit) This logarithmic scaling means even large numbers of users result in manageable exit transaction counts. ## VTXO fees for users While each VTXO type has different underlying costs, the fees charged to users may not directly reflect these costs. Servers may choose to abstract or subsidize fees as part of their business model. Fee schedules for Second's Ark server are still a work in progress, but you can read more about considerations on our [fees page](/docs/learn/fees). # Back up your wallet Source: https://second.tech/docs/swaptopia/backup Write down the 12-word seed phrase of your Swaptopia wallet before your first swap, and learn what it brings back and what only this browser can resume. Swaptopia offers two backups: 1. **[Write down your seed phrase](/docs/swaptopia/backup#write-down-your-seed-phrase):** This recovers the sats your wallet holds on Ark, with the Ark server's help, if this browser's data is lost. It does not bring back a swap in progress, which only this browser can resume. 2. **[Export the wallet data](/docs/swaptopia/backup#back-up-the-wallet-data-for-an-emergency-exit-optional) (optional):** This lets the Bark CLI run an emergency exit without the Ark server's cooperation. ## Write down your seed phrase > [!WARNING] > > The seed phrase is the only way to recover your sats if this browser's data is lost. Swaptopia shows it only until you select **Done**. Nobody at Second can recover your sats for you.