prepare_btc_send
Prepare an unsigned Bitcoin PSBT for sending from a Ledger wallet. Supports segwit/taproot inputs, fee rate or priority presets, RBF, and coin selection with fee cap.
Instructions
Build an unsigned Bitcoin native-send PSBT (segwit/taproot only in Phase 1). Returns a 15-min handle the agent forwards to send_transaction; the Ledger BTC app clear-signs every output (address + amount) + fee on-screen, so there is NO blind-sign hash to pre-match in chat. The verification block surfaces every output's address, amount in BTC, isChange flag, fee (BTC + sat/vB), and RBF flag. Fee selection: pass feeRateSatPerVb for an explicit sat/vB number, OR feePriority for a fuzzy preset (fastestFee / halfHourFee / hourFee / economyFee / minimumFee — issue #435) that resolves to mempool.space's named buckets at prepare time. Default (neither set) is halfHourFee. The resolved sat/vB always appears in the response under feeRateSatPerVb so the user sees what was picked. Coin-selection runs branch-and-bound + accumulative fallback via the coinselect library; a fee-cap guard refuses any tx whose fee exceeds max(10 × feeRate × vbytes, 2% of total output value) unless allowHighFee: true is passed. RBF is enabled by default (sequence 0xFFFFFFFD); pass rbf: false to mark final.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| wallet | Yes | One paired Bitcoin source address (string), OR an array of 1-20 paired source addresses for multi-input consolidation (issue #264). All addresses must belong to the SAME Ledger account (same accountIndex + addressType) — Phase 1 mixed-type sends (segwit + taproot in one tx) are out of scope. UTXOs are fetched in parallel for every listed source and merged into one coin-selection pool. "max" sweeps every UTXO from every listed wallet into a single output. Phase 1 sends only support native segwit (`bc1q...`) and taproot (`bc1p...`) sources; legacy (`1...`) and P2SH-wrapped (`3...`) sends are deferred. | |
| to | Yes | Bitcoin recipient address. Any of the four mainnet types is accepted as a destination — the restriction is only on the source side. | |
| amount | Yes | Decimal BTC string (up to 8 fractional digits, e.g. "0.001") or "max" to sweep the full balance minus fees. "max" picks the fee-aware amount after coin-selection so the user doesn't have to subtract fees by hand. | |
| feeRateSatPerVb | No | Fee rate in sat/vB. Optional — when omitted, uses mempool.space's `halfHourFee` recommendation (~3-block confirm target). Override for priority sends through congestion. Capped at 10000 sat/vB for safety. Mutually exclusive with `feePriority`. | |
| feePriority | No | Issue #435 — fuzzy-fee preset that resolves to mempool.space's named buckets (`fastestFee` ~next-block, `halfHourFee` ~3-block, `hourFee` ~6-block, `economyFee` lowest still-included, `minimumFee` floor). Resolves at prepare time via `getFeeEstimates()`; the resolved sat/vB appears in the response so the user sees what was picked. Default (neither preset nor `feeRateSatPerVb` supplied) is `halfHourFee`. Mutually exclusive with `feeRateSatPerVb`. | |
| rbf | No | BIP-125 Replace-By-Fee. Default true → sequence 0xFFFFFFFD on every input, marking the tx replaceable so the user can fee-bump if it stalls. Set false → 0xFFFFFFFE (final, not replaceable). RBF is the default for every modern wallet. | |
| allowHighFee | No | Override the fee-cap guard. The cap is `max(10 × feeRate × vbytes, 2% of total output value)`. Legitimate priority sends through heavy congestion can exceed it; pass true after confirming with the user. |