Quickstart
From nothing to a first on-chain payment. This is the happy path; environmental detail lives in Installation & Configuration.
Prerequisites
- Ruby >= 3.3
- A funded WIF private key (mainnet or testnet)
- Docker (optional — only if you want Postgres instead of SQLite)
1. Choose a backend
=== “SQLite (default, zero-config)”
Nothing to do. With `DATABASE_URL` unset, the wallet creates
`~/.bsv-wallet/<name>.db` automatically.
=== “Postgres”
```sh
docker compose up -d # Postgres on localhost:5433
```
Add `pg` to your Gemfile (the gem ships only `sqlite3`), then either
set `DATABASE_URL` or set the `BSV_WALLET_POSTGRES` base URL — see
[Installation & Configuration](/bsv-wallet/getting-started/installation/).
2. Set your key
export BSV_WALLET_WIF_ALICE=<your-wif-private-key>
# Or, for an unnamed wallet: export WIF=<wif> and omit wallet_name: in step 3.
Env-var resolution and named-wallet precedence are covered in Installation & Configuration.
3. Fund the root address
A fresh wallet owns no UTXOs. Boot the wallet and print its root-key P2PKH address, then send some satoshis to it from another wallet:
require 'bsv-wallet'
ctx = BSV::Wallet::CLI.boot(wallet_name: 'alice') # migrates the DB, builds the Engine
puts ctx[:key_deriver].root_private_key.public_key.address
The root address is the only funding entry point — everything else flows from there.
4. Ingest the funds
engine = ctx[:engine]
engine.import_wallet # scans the root address, imports each UTXO
import_wallet defaults to no_send: false — the import self-payment is queued for walletd to broadcast. Pass no_send: true if you want to build locally without publishing (rare; tests only).
5. Send a payment
result = engine.send_payment(
recipient: '02a1b2…', # 66-char compressed pubkey hex
satoshis: 5_000
)
# result => {
# txid: <32-byte binary>, # wire-order wtxid — convert via to_dtxid for display
# beef: <binary>, # atomic BEEF
# sender_identity_key: "<66-char hex>", # compressed pubkey, hex per identity carve-out
# outputs: [{ vout: 0, satoshis: 5_000, derivation_prefix: "...", derivation_suffix: "1" }]
# }
no_send defaults to false (broadcast — the BRC-100 createAction default). Pass no_send: true to build the BEEF envelope without publishing — the shape callers reach for when handing the action off to a counterparty peer-to-peer.
The txid: key is the subject wtxid (wire-order binary, 32 bytes), the BRC-100 spec boundary name. Convert to a display-order hex string with the BSV::Wallet::Txid refinement:
using BSV::Wallet::Txid
result[:txid].to_dtxid # => 64-char display-order hex
See the wtxid / dtxid convention in Transactions & BEEF.
6. Run the daemon
A queued broadcast is queued, not pushed — nothing lands on chain until walletd is running:
bin/walletd alice mainnet
7. Peer-to-peer delivery
For sending a payment directly to a counterparty (BRC-29 over HTTP), compose the porcelain pipe on the sender side:
bin/create alice <bob_identity_key> 500 --no-send \
| bin/transmit alice --to <bob_identity_key> --endpoint https://peer.example/internalize
On the recipient side, bin/receive reads the JSON envelope on stdin and internalises the outputs.
Gotchas to know about
- Limp mode blocks all outbound spend below 50,000 sats. Set
LIMP_THRESHOLD(orc.limp_thresholdin~/.bsv-wallet/config.rb) to lift the floor.no_senddefaults tofalse(broadcast). Passno_send: trueto build a BEEF envelope without publishing — the shapebin/createuses for the peer pipe.- One wallet per process — never boot two in the same process. Each
bin/script is its own OS process for this reason.