@anywalletkit/wallet-btc 0.2.5 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -0
- package/dist/{chunk-4WUAN3DC.js → chunk-TZNOUBSP.js} +24 -3
- package/dist/chunk-TZNOUBSP.js.map +1 -0
- package/dist/history.cjs +10 -2
- package/dist/history.cjs.map +1 -1
- package/dist/history.js +1 -1
- package/dist/index.cjs +76 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +25 -1
- package/dist/index.d.ts +25 -1
- package/dist/index.js +61 -8
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- package/dist/chunk-4WUAN3DC.js.map +0 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts","../src/esplora.ts","../src/client.ts","../src/message.ts","../src/coinselect.ts","../src/describe.ts","../src/address.ts","../src/network.ts","../src/read-only-account.ts","../src/account.ts","../src/manager.ts"],"sourcesContent":["export { InsufficientFundsError, NetworkError, SignerError } from '@anywalletkit/core'\n\n/** Why a spend was refused before signing. */\nexport type UnsafeTransactionCode =\n /** Fee rate above `maxFeeRate`. */\n | 'fee-rate-too-high'\n /** An output that is neither the requested recipient/amount nor our change. */\n | 'unexpected-output'\n /** The recipient output is missing or carries a different amount. */\n | 'recipient-mismatch'\n /** A change output pays an address that is not ours. */\n | 'change-not-ours'\n /** A coin the indexer reported does not match its previous transaction (txid, amount or script). */\n | 'prevout-mismatch'\n\n/** A transaction failed a hard safety check and was not signed / broadcast. */\nexport class UnsafeTransactionError extends Error {\n readonly code: UnsafeTransactionCode\n constructor(code: UnsafeTransactionCode, message: string) {\n super(message)\n this.name = 'UnsafeTransactionError'\n this.code = code\n }\n}\n\n/** Coin selection would need more inputs than `maxInputs` allows. */\nexport class TooManyInputsError extends Error {\n readonly maxInputs: number\n constructor(maxInputs: number) {\n super(`The spend needs more than ${maxInputs} inputs; consolidate the UTXOs first or raise maxInputs.`)\n this.name = 'TooManyInputsError'\n this.maxInputs = maxInputs\n }\n}\n\n/** BIP-137 message signatures only exist for p2pkh/p2wpkh keys; taproot accounts have none (BIP-322 is not implemented). */\nexport class UnsupportedAddressTypeError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'UnsupportedAddressTypeError'\n }\n}\n","import { NetworkError } from '@anywalletkit/core'\nimport { DEFAULT_TIMEOUT_MS, fetchWithTimeout, isHex64, isRecord } from './http.js'\nimport type { BlockbookTx, BtcClient, Utxo } from './types.js'\n\ninterface EsploraStats { funded_txo_sum: number; spent_txo_sum: number }\ninterface EsploraStatus { confirmed: boolean; block_height?: number }\nconst isStats = (v: unknown): v is EsploraStats => isRecord(v) && typeof v.funded_txo_sum === 'number' && typeof v.spent_txo_sum === 'number'\nconst isStatus = (v: unknown): v is EsploraStatus => isRecord(v) && typeof v.confirmed === 'boolean'\n\n/**\n * Esplora REST transport — the API served by mempool.space (`https://mempool.space/api`)\n * and Blockstream (`https://blockstream.info/api`). Public instances exist, so it is\n * the natural fallback behind a self-hosted Blockbook.\n *\n * Balance semantics: `unconfirmedOutgoing` is the mempool net outflow\n * (spent − funded, clamped at 0), a conservative stand-in for Bitcoin Core's\n * trusted-change rule that Blockbook's richer address record allows.\n */\nexport class EsploraClient implements BtcClient {\n private readonly base: string\n private readonly fetchFn: typeof fetch\n private readonly timeoutMs: number\n\n constructor(config: { url: string }, fetchFn: typeof fetch = globalThis.fetch, timeoutMs = DEFAULT_TIMEOUT_MS) {\n const trimmed = config.url.replace(/\\/+$/, '')\n this.base = trimmed.endsWith('/api') ? trimmed : `${trimmed}/api`\n this.fetchFn = fetchFn\n this.timeoutMs = timeoutMs\n }\n\n async connect(): Promise<void> {}\n async close(): Promise<void> {}\n\n private async request(path: string, init?: RequestInit): Promise<Response> {\n const url = `${this.base}${path}`\n const res = await fetchWithTimeout(this.fetchFn, url, init, this.timeoutMs, this.base)\n if (!res.ok) throw new NetworkError(`Esplora request failed: ${res.status} ${res.statusText} (${url})`, { provider: this.base })\n return res\n }\n\n private async json<T>(path: string, check: (v: unknown) => v is T): Promise<T> {\n const res = await this.request(path)\n let body: unknown\n try { body = await res.json() } catch (e) { throw new NetworkError(`Esplora returned non-JSON for ${path}`, { provider: this.base, cause: e }) }\n if (!check(body)) throw new NetworkError(`Esplora returned an unexpected shape for ${path}`, { provider: this.base })\n return body\n }\n\n private async text(path: string, init?: RequestInit): Promise<string> {\n return (await this.request(path, init)).text()\n }\n\n async getBalance(address: string) {\n const d = await this.json(`/address/${address}`, (v): v is { chain_stats: EsploraStats; mempool_stats: EsploraStats } =>\n isRecord(v) && isStats(v.chain_stats) && isStats(v.mempool_stats))\n const confirmed = BigInt(d.chain_stats.funded_txo_sum) - BigInt(d.chain_stats.spent_txo_sum)\n const unconfirmed = BigInt(d.mempool_stats.funded_txo_sum) - BigInt(d.mempool_stats.spent_txo_sum)\n const outgoing = BigInt(d.mempool_stats.spent_txo_sum) - BigInt(d.mempool_stats.funded_txo_sum)\n return { confirmed, unconfirmed, unconfirmedOutgoing: outgoing > 0n ? outgoing : 0n }\n }\n\n async listUnspent(address: string): Promise<Utxo[]> {\n const d = await this.json(`/address/${address}/utxo`, (v): v is Array<{ txid: string; vout: number; value: number; status: EsploraStatus }> =>\n Array.isArray(v) && v.every((u) => isRecord(u) && isHex64(u.txid) && typeof u.vout === 'number' && typeof u.value === 'number' && isStatus(u.status)))\n return d.map((u) => ({ txid: u.txid, vout: u.vout, value: BigInt(u.value), height: u.status.confirmed && u.status.block_height ? u.status.block_height : -1 }))\n }\n\n /** Esplora pages 25 (mempool.space: up to 50) txs per call; walk `/txs/chain/<last>` until a short page. */\n async getHistory(address: string) {\n const items: Array<{ txid: string; height: number }> = []\n const check = (v: unknown): v is Array<{ txid: string; status: EsploraStatus }> => Array.isArray(v) && v.every((t) => isRecord(t) && isHex64(t.txid) && isStatus(t.status))\n let page = await this.json(`/address/${address}/txs`, check)\n for (;;) {\n for (const t of page) items.push({ txid: t.txid, height: t.status.confirmed && t.status.block_height ? t.status.block_height : -1 })\n if (page.length < 25) break\n const confirmedTail = [...page].reverse().find((t) => t.status.confirmed)\n if (!confirmedTail) break\n page = await this.json(`/address/${address}/txs/chain/${confirmedTail.txid}`, check)\n if (page.length === 0) break\n }\n return items\n }\n\n async getTransactionInfo(txid: string): Promise<BlockbookTx | undefined> {\n let d: { txid: string; status: EsploraStatus; fee?: number }\n try {\n d = await this.json(`/tx/${txid}`, (v): v is { txid: string; status: EsploraStatus; fee?: number } => isRecord(v) && isHex64(v.txid) && isStatus(v.status))\n } catch (e) {\n if (e instanceof NetworkError && /\\b(400|404)\\b/.test(e.message)) return undefined\n throw e\n }\n const height = d.status.confirmed && d.status.block_height ? d.status.block_height : -1\n const confirmations = height > 0 ? Math.max((await this.getBlockHeight()) - height + 1, 1) : 0\n return { txid: d.txid, blockHeight: height, confirmations, ...(typeof d.fee === 'number' ? { fees: String(d.fee) } : {}) }\n }\n\n async getTransaction(txid: string): Promise<string> {\n const hex = (await this.text(`/tx/${txid}/hex`)).trim()\n if (!/^[0-9a-fA-F]+$/.test(hex) || hex.length < 20) throw new NetworkError(`Esplora returned no hex for ${txid}`, { provider: this.base })\n return hex\n }\n\n async broadcast(rawTx: string): Promise<string> {\n const id = (await this.text('/tx', { method: 'POST', body: rawTx, headers: { 'content-type': 'text/plain' } })).trim()\n if (!/^[0-9a-fA-F]{64}$/.test(id)) throw new NetworkError(`Esplora broadcast returned an unexpected body: ${id.slice(0, 120)}`, { provider: this.base })\n return id\n }\n\n /** `/fee-estimates` → { \"1\": sat/vB, \"2\": …, \"25\": …, \"144\": … }; picks the nearest target ≥ `blocks`. */\n async estimateFee(blocks: number): Promise<number> {\n const d = await this.json('/fee-estimates', (v): v is Record<string, number> => isRecord(v) && Object.values(v).every((n) => typeof n === 'number'))\n const targets = Object.keys(d).map(Number).filter((n) => Number.isFinite(n) && n > 0).sort((a, b) => a - b)\n const target = targets.find((t) => t >= blocks) ?? targets.at(-1)\n const rate = target !== undefined ? d[String(target)] : undefined\n if (!rate || rate <= 0) throw new NetworkError('Esplora has no fee estimate', { provider: this.base })\n return rate\n }\n\n async getBlockHeight(): Promise<number> {\n const h = Number((await this.text('/blocks/tip/height')).trim())\n if (!Number.isInteger(h) || h <= 0) throw new NetworkError('Esplora did not report a block height', { provider: this.base })\n return h\n }\n}\n","import { NetworkError } from '@anywalletkit/core'\nimport { BlockbookClient } from './blockbook.js'\nimport { EsploraClient } from './esplora.js'\nimport { DEFAULT_TIMEOUT_MS } from './http.js'\nimport type { BtcClient, BtcClientConfig, BtcConfig } from './types.js'\n\nconst isClient = (c: unknown): c is BtcClient => typeof c === 'object' && c !== null && typeof (c as BtcClient).listUnspent === 'function'\n\nfunction toClient(c: BtcClientConfig | BtcClient, fetchFn: typeof fetch | undefined, timeoutMs: number): BtcClient {\n if (isClient(c)) return c\n switch (c.type) {\n case 'blockbook-http': return new BlockbookClient(c.clientConfig, fetchFn, timeoutMs)\n case 'esplora-http': return new EsploraClient(c.clientConfig, fetchFn, timeoutMs)\n default: throw new Error(`Unknown BTC client type: ${String((c as { type: string }).type)}`)\n }\n}\n\nconst METHODS = ['connect', 'close', 'getBalance', 'listUnspent', 'getHistory', 'getTransaction', 'getTransactionInfo', 'broadcast', 'estimateFee', 'getBlockHeight'] as const\n\n/** One client, or a failover client over the list: each call walks the list in order, `retries` extra rounds. */\nexport function createClient(config: BtcConfig): BtcClient | undefined {\n if (config.client === undefined) return undefined\n const timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS\n const list = (Array.isArray(config.client) ? config.client : [config.client]).map((c) => toClient(c, config.fetch, timeoutMs))\n if (list.length === 0) return undefined\n if (list.length === 1) return list[0]!\n const attempts = list.length + (config.retries ?? 3)\n const call = (method: (typeof METHODS)[number]) => async (...args: unknown[]) => {\n let last: unknown\n for (let i = 0; i < attempts; i++) {\n const c = list[i % list.length]! as unknown as Record<string, ((...a: unknown[]) => Promise<unknown>) | undefined>\n const fn = c[method]\n if (!fn) continue // optional method this transport lacks — try the next one\n try { return await fn.apply(c, args) } catch (e) { last = e }\n }\n throw new NetworkError(`All BTC clients failed for ${method}`, { cause: last })\n }\n const out = {} as Record<(typeof METHODS)[number], (...args: unknown[]) => Promise<unknown>>\n for (const m of METHODS) out[m] = call(m)\n return out as unknown as BtcClient\n}\n","/**\n * BIP-137 message signatures (the Electrum / Bitcoin Core encoding):\n * hash = sha256d(varint(prefix) || prefix || varint(len) || message); header byte =\n * 27 + recovery (+4 compressed) (+8 segwit, +4 more for p2wpkh) → p2wpkh = 39 + recovery.\n * Output: base64 of header || r || s. Signing is RFC-6979 deterministic, low-S.\n *\n * Only p2pkh / p2wpkh keys have a BIP-137 form; taproot accounts must use BIP-322\n * (not implemented).\n */\nimport { sha256 } from '@noble/hashes/sha2.js'\nimport { secp256k1 } from '@noble/curves/secp256k1.js'\nimport { base64 } from '@scure/base'\nimport type { Signer } from '@anywalletkit/core'\n\nconst PREFIX = new TextEncoder().encode('\\u0018Bitcoin Signed Message:\\n') // the \\x18 IS the varint length (24) of \"Bitcoin Signed Message:\\n\"\n\nfunction varint(n: number): Uint8Array {\n if (n < 0xfd) return Uint8Array.of(n)\n if (n <= 0xffff) return Uint8Array.of(0xfd, n & 0xff, n >> 8)\n return Uint8Array.of(0xfe, n & 0xff, (n >> 8) & 0xff, (n >> 16) & 0xff, (n >>> 24) & 0xff)\n}\n\n/** BIP-137 hash of a message (`Bitcoin Signed Message:` prefix, double SHA-256). */\nexport function magicHash(message: string | Uint8Array): Uint8Array {\n const msg = typeof message === 'string' ? new TextEncoder().encode(message) : message\n const len = varint(msg.length)\n const buf = new Uint8Array(PREFIX.length + len.length + msg.length)\n buf.set(PREFIX, 0); buf.set(len, PREFIX.length); buf.set(msg, PREFIX.length + len.length)\n return sha256(sha256(buf))\n}\n\n/** Address flavour a BIP-137 signature header is written for. */\nexport type SegwitType = 'p2wpkh' | 'p2sh(p2wpkh)'\n\n/** Header flag for a compressed key: +4 compressed, +8 segwit, +4 more for p2wpkh (→ 39 + recovery). */\nfunction headerFlag(recovery: number, segwitType: SegwitType | undefined): number {\n let flag = recovery\n if (segwitType !== undefined) { flag += 8; if (segwitType === 'p2wpkh') flag += 4 } else flag += 4\n return 27 + flag\n}\n\n/** Encode `r‖s` + recovery id as a base64 BIP-137 signature. */\nexport function encodeMessageSignature(rs: Uint8Array, recovery: number, segwitType: SegwitType | undefined = 'p2wpkh'): string {\n if (rs.length !== 64 || recovery > 1) throw new Error('BIP-137: expected a 64-byte r‖s signature and a 0/1 recovery id.')\n const out = new Uint8Array(65)\n out[0] = headerFlag(recovery, segwitType)\n out.set(rs, 1)\n return base64.encode(out)\n}\n\n/** Sign with a raw private key (RFC-6979 deterministic, low-S). Kept for callers that hold a key outside a Signer. */\nexport function signMessage(message: string | Uint8Array, privateKey: Uint8Array, segwitType: SegwitType | undefined = 'p2wpkh'): string {\n // noble 'recovered' = recovery id || r || s\n const sig = secp256k1.sign(magicHash(message), privateKey, { prehash: false, format: 'recovered' })\n return encodeMessageSignature(sig.subarray(1), sig[0]!, segwitType)\n}\n\n/** Sign through a {@link Signer} (`ecdsa-recoverable`, context `btc-message`). */\nexport async function signMessageWith(message: string | Uint8Array, signer: Signer, segwitType: SegwitType | undefined = 'p2wpkh'): Promise<string> {\n const sig = await signer.sign(magicHash(message), { scheme: 'ecdsa-recoverable', context: 'btc-message' })\n return encodeMessageSignature(sig.subarray(0, 64), sig[64]!, segwitType)\n}\n\n/** Recover the public key (compressed unless the header says otherwise) from a BIP-137 signature, or undefined when malformed. */\nexport function recoverMessagePublicKey(message: string | Uint8Array, signature: string): { publicKey: Uint8Array; segwitType: SegwitType | undefined } | undefined {\n let bytes: Uint8Array\n try { bytes = base64.decode(signature) } catch { return undefined }\n if (bytes.length !== 65) return undefined\n const flag = bytes[0]! - 27\n if (flag < 0 || flag > 15) return undefined\n const recovery = flag & 3\n const compressed = !!(flag & 4) || !!(flag & 8)\n const segwit = flag & 8 ? ((flag & 4) ? 'p2wpkh' : 'p2sh(p2wpkh)') : undefined\n const recovered = new Uint8Array(65)\n recovered[0] = recovery\n recovered.set(bytes.subarray(1), 1)\n try {\n const pub = secp256k1.recoverPublicKey(recovered, magicHash(message), { prehash: false })\n const publicKey = compressed ? pub : secp256k1.Point.fromBytes(pub).toBytes(false)\n return { publicKey, segwitType: segwit }\n } catch { return undefined }\n}\n","/**\n * Coin selection — our own, deterministic, documented. (btc-signer ships\n * `selectUTXO`, but it is outside the audited scope, so it is not used.)\n *\n * Strategy: effective-value accumulation, largest first.\n * 1. Drop UTXOs whose value does not cover the fee their own input adds.\n * 2. Sort the rest by value descending (ties: txid, then vout — stable across runs).\n * 3. Add inputs until Σvalue ≥ targets + fee(no-change tx).\n * 4. If what is left after a change output is ≥ the change dust threshold, keep\n * the change; otherwise fold it into the fee (one output less).\n * 5. More than `maxInputs` inputs → TooManyInputsError.\n *\n * Fees are feeRate × vsize, vsize = ceil(weight / 4) with the standard\n * segwit weights (see address.ts). The p2wpkh input estimate assumes a 72-byte\n * DER signature, so the estimate is an upper bound for lowR signatures.\n */\nimport { InsufficientFundsError } from '@anywalletkit/core'\nimport { TooManyInputsError } from './errors.js'\nimport type { Utxo } from './types.js'\n\n/** Most inputs one spend may use; above it the account asks to consolidate first. */\nexport const MAX_UTXO_INPUTS = 200\n\n/** Version 4 + locktime 4 + input count 1 + output count 1 = 10 B × 4, plus segwit marker + flag (2 WU). */\nconst OVERHEAD_WEIGHT = 42\n\n/** An output the selection must fund. */\nexport interface SelectionTarget {\n value: bigint\n /** vbytes the output occupies (see `outputVBytes`). */\n vbytes: number\n}\n\n/** Input to {@link selectCoins}. */\nexport interface CoinSelectOptions {\n utxos: Utxo[]\n targets: SelectionTarget[]\n /** sat/vB, ≥ 1. */\n feeRate: bigint\n /** Weight units one of our inputs adds (`INPUT_WEIGHT[addressType]`). */\n inputWeight: number\n /** vbytes a change output to our own address occupies. */\n changeVBytes: number\n /** Dust threshold for our change output type. */\n changeDust: bigint\n maxInputs?: number\n}\n\n/** UTXOs chosen for a spend, the fee and the change. */\nexport interface CoinSelection {\n utxos: Utxo[]\n fee: bigint\n /** Change back to us; 0n when folded into the fee. */\n change: bigint\n /** True when change existed but fell below dust and became fee. */\n changeFolded: boolean\n /** Estimated vsize of the final transaction. */\n vsize: number\n feeRate: bigint\n}\n\n/** Virtual size (vB) of a segwit transaction with the given inputs and outputs. */\nexport function estimateVsize(inputs: number, inputWeight: number, outputVBytes: number[]): number {\n const outputWeight = outputVBytes.reduce((s, vb) => s + vb * 4, 0)\n // Count varints grow past 252 entries; one extra byte each covers up to 65535.\n const extra = (inputs > 252 ? 2 : 0) + (outputVBytes.length > 252 ? 2 : 0)\n return Math.ceil((OVERHEAD_WEIGHT + extra * 4 + inputs * inputWeight + outputWeight) / 4)\n}\n\nconst cmpUtxo = (a: Utxo, b: Utxo): number =>\n a.value > b.value ? -1 : a.value < b.value ? 1 : a.txid < b.txid ? -1 : a.txid > b.txid ? 1 : a.vout - b.vout\n\n/** UTXOs worth spending at this fee rate, largest first. */\nexport function spendableUtxos(utxos: Utxo[], feeRate: bigint, inputWeight: number): Utxo[] {\n const inputFee = BigInt(Math.ceil(inputWeight / 4)) * feeRate\n return utxos.filter((u) => u.value > inputFee).sort(cmpUtxo)\n}\n\n/**\n * Pick UTXOs to fund the targets at `feeRate` (sat/vB): change goes back when it is above dust,\n * otherwise it joins the fee.\n *\n * @throws `InsufficientFundsError` (core) when the UTXOs cannot cover targets plus fee,\n * `TooManyInputsError` above `maxInputs`, Error for a fee rate below 1 sat/vB.\n */\nexport function selectCoins(o: CoinSelectOptions): CoinSelection {\n if (o.feeRate < 1n) throw new Error('feeRate must be at least 1 sat/vB')\n const maxInputs = o.maxInputs ?? MAX_UTXO_INPUTS\n const targetSum = o.targets.reduce((s, t) => s + t.value, 0n)\n const targetVB = o.targets.map((t) => t.vbytes)\n const candidates = spendableUtxos(o.utxos, o.feeRate, o.inputWeight)\n const available = o.utxos.reduce((s, u) => s + u.value, 0n)\n\n const feeFor = (n: number, withChange: boolean) =>\n BigInt(estimateVsize(n, o.inputWeight, withChange ? [...targetVB, o.changeVBytes] : targetVB)) * o.feeRate\n\n const selected: Utxo[] = []\n let sum = 0n\n for (const u of candidates) {\n if (selected.length >= maxInputs) throw new TooManyInputsError(maxInputs)\n selected.push(u)\n sum += u.value\n const n = selected.length\n const feeNoChange = feeFor(n, false)\n if (sum < targetSum + feeNoChange) continue\n const feeWithChange = feeFor(n, true)\n const change = sum - targetSum - feeWithChange\n if (change >= o.changeDust) {\n return { utxos: selected, fee: feeWithChange, change, changeFolded: false, vsize: estimateVsize(n, o.inputWeight, [...targetVB, o.changeVBytes]), feeRate: o.feeRate }\n }\n return { utxos: selected, fee: sum - targetSum, change: 0n, changeFolded: sum - targetSum > feeNoChange, vsize: estimateVsize(n, o.inputWeight, targetVB), feeRate: o.feeRate }\n }\n const need = targetSum + feeFor(Math.max(selected.length, 1), false)\n throw new InsufficientFundsError(need, available, 'BTC')\n}\n\n/** Sweep: every spendable input (largest first, capped), one output, no change. */\nexport function selectAll(o: Omit<CoinSelectOptions, 'targets' | 'changeVBytes' | 'changeDust'> & { outputVBytes: number }): { utxos: Utxo[]; fee: bigint; amount: bigint; vsize: number } {\n const maxInputs = o.maxInputs ?? MAX_UTXO_INPUTS\n const utxos = spendableUtxos(o.utxos, o.feeRate, o.inputWeight).slice(0, maxInputs)\n if (utxos.length === 0) return { utxos, fee: 0n, amount: 0n, vsize: 0 }\n const vsize = estimateVsize(utxos.length, o.inputWeight, [o.outputVBytes])\n const fee = BigInt(vsize) * o.feeRate\n const amount = utxos.reduce((s, u) => s + u.value, 0n) - fee\n return { utxos, fee, amount: amount > 0n ? amount : 0n, vsize }\n}\n","import { Transaction } from '@scure/btc-signer'\nimport type { BTC_NETWORK } from '@scure/btc-signer/utils.js'\nimport { hex } from '@scure/base'\nimport { dustLimit, scriptKind } from './address.js'\nimport { UnsafeTransactionError } from './errors.js'\nimport type { BtcTxDescription, BtcTxOutputDescription, BtcWarning } from './types.js'\nimport { bigintToNumber } from '@anywalletkit/core'\n\n/** Default fee-rate ceiling, sat/vB; a spend above it is refused. */\nexport const DEFAULT_MAX_FEE_RATE = 500\n/** Replace-by-fee signalling: any sequence below 0xfffffffe (BIP-125). */\nexport const RBF_SEQUENCE = 0xfffffffd\n/** Opts out of RBF while still letting nLockTime apply. */\nexport const FINAL_SEQUENCE = 0xfffffffe\n\n/** What a description needs to tell recipient, change and unknown outputs apart. */\nexport interface DescribeContext {\n network: BTC_NETWORK\n /** Our own address: outputs paying it are tagged `change`. */\n ownAddress: string\n /** The spend the caller asked for. Outputs matching it are `recipient`; anything else is `unknown`. */\n intended?: { to: string; value: bigint } | undefined\n maxFeeRate?: number | undefined\n}\n\n/** Parse raw tx hex. Prevout amounts are not in the wire format — callers pass them in `inputValues`. */\nexport function parseRawTransaction(rawHex: string): Transaction {\n return Transaction.fromRaw(hex.decode(rawHex), { allowUnknownInputs: true, allowUnknownOutputs: true })\n}\n\n/** Signed: exact vsize. Unsigned: the non-witness serialisation length (exact for legacy inputs, a lower bound for segwit). */\nexport function vsizeOf(tx: Transaction): number {\n try { return tx.vsize } catch { return tx.unsignedTx.length }\n}\n\n/**\n * Describe a (signed or unsigned) btc-signer Transaction given the sat value of\n * every input, in input order. Pure: no network, no signing.\n */\nexport function describeTransaction(tx: Transaction, inputValues: bigint[], ctx: DescribeContext): BtcTxDescription {\n if (inputValues.length !== tx.inputsLength) throw new Error(`describeTransaction: ${tx.inputsLength} inputs but ${inputValues.length} values`)\n const inputs = Array.from({ length: tx.inputsLength }, (_, i) => {\n const inp = tx.getInput(i)\n return { txid: inp.txid ? hex.encode(inp.txid) : '', vout: inp.index ?? 0, value: inputValues[i]! }\n })\n const outputs: BtcTxOutputDescription[] = []\n const warnings = new Set<BtcWarning>()\n for (let i = 0; i < tx.outputsLength; i++) {\n const out = tx.getOutput(i)\n const value = out.amount ?? 0n\n const address = tx.getOutputAddress(i, ctx.network)\n const role: BtcTxOutputDescription['role'] =\n address !== undefined && address === ctx.ownAddress ? 'change'\n : ctx.intended === undefined ? 'recipient'\n : address !== undefined && address === ctx.intended.to && value === ctx.intended.value ? 'recipient'\n : 'unknown'\n if (out.script && value < dustLimit(scriptKind(out.script))) warnings.add('dust-output')\n outputs.push({ address, value, role })\n }\n const inputSum = inputs.reduce((s, i) => s + i.value, 0n)\n const outputSum = outputs.reduce((s, o) => s + o.value, 0n)\n const fee = inputSum - outputSum\n const amount = outputs.filter((o) => o.role !== 'change').reduce((s, o) => s + o.value, 0n)\n const vsize = vsizeOf(tx)\n const feeRate = vsize > 0 ? Math.round((bigintToNumber(fee) / vsize) * 100) / 100 : 0\n if (feeRate > (ctx.maxFeeRate ?? DEFAULT_MAX_FEE_RATE)) warnings.add('high-fee-rate')\n if (amount > 0n && fee * 10n > amount) warnings.add('fee-over-10pct-of-amount')\n if (!outputs.some((o) => o.role === 'change')) warnings.add('no-change')\n let rbf = false\n for (let i = 0; i < tx.inputsLength; i++) if ((tx.getInput(i).sequence ?? 0xffffffff) < FINAL_SEQUENCE) rbf = true\n const desc: BtcTxDescription = { kind: 'btc-transfer', inputs, outputs, amount, fee, feeRate, vsize, rbf, lockTime: tx.lockTime, warnings: [...warnings] }\n if (tx.isFinal) desc.txid = tx.id\n return desc\n}\n\n/**\n * Hard checks run before signing and before broadcasting. Throws UnsafeTransactionError;\n * never mutates. With `intended`, exactly one output must be the requested\n * recipient/amount and every other output must be our change.\n */\nexport function assertSafe(desc: BtcTxDescription, ctx: DescribeContext): void {\n const maxFeeRate = ctx.maxFeeRate ?? DEFAULT_MAX_FEE_RATE\n if (desc.feeRate > maxFeeRate) {\n throw new UnsafeTransactionError('fee-rate-too-high', `Fee rate ${desc.feeRate} sat/vB exceeds the ${maxFeeRate} sat/vB ceiling (maxFeeRate).`)\n }\n if (desc.fee < 0n) throw new UnsafeTransactionError('unexpected-output', 'Outputs exceed inputs.')\n for (const o of desc.outputs) {\n if (o.role === 'change' && o.address !== ctx.ownAddress) throw new UnsafeTransactionError('change-not-ours', `Change output pays ${o.address ?? '<no address>'}, not ${ctx.ownAddress}.`)\n }\n if (ctx.intended) {\n const recipients = desc.outputs.filter((o) => o.role === 'recipient')\n if (recipients.length !== 1) throw new UnsafeTransactionError('recipient-mismatch', `Expected one output of ${ctx.intended.value} sat to ${ctx.intended.to}, found ${recipients.length}.`)\n const unknown = desc.outputs.filter((o) => o.role === 'unknown')\n if (unknown.length) throw new UnsafeTransactionError('unexpected-output', `Transaction carries ${unknown.length} output(s) that are neither the recipient nor our change.`)\n }\n}\n","import { Address, OutScript, p2tr, p2wpkh } from '@scure/btc-signer'\nimport type { BTC_NETWORK } from '@scure/btc-signer/utils.js'\nimport type { BtcAddressType } from './types.js'\n\n/** Output-script families btc-signer recognises (`OutScript.decode(...).type`). */\nexport type ScriptKind = 'pk' | 'pkh' | 'sh' | 'wsh' | 'wpkh' | 'ms' | 'tr' | 'tr_ns' | 'tr_ms' | 'p2a' | 'unknown'\n\n/** An address decoded to its output script. */\nexport interface DecodedAddress {\n script: Uint8Array\n kind: ScriptKind\n}\n\n/** Decode and validate an address for `network`; throws on a malformed address or a foreign network. */\nexport function decodeAddress(address: string, network: BTC_NETWORK): DecodedAddress {\n let decoded\n try { decoded = Address(network).decode(address) } catch (e) {\n throw new Error(`Invalid bitcoin address for this network: ${address}`, { cause: e })\n }\n return { script: OutScript.encode(decoded), kind: decoded.type as ScriptKind }\n}\n\n/** Address for an output script, or undefined when the script has no address form. */\nexport function addressFromScript(script: Uint8Array, network: BTC_NETWORK): string | undefined {\n try { return Address(network).encode(OutScript.decode(script)) } catch { return undefined }\n}\n\n/** Type of an output script; `unknown` when it cannot be decoded. */\nexport function scriptKind(script: Uint8Array): ScriptKind {\n try { return OutScript.decode(script).type as ScriptKind } catch { return 'unknown' }\n}\n\n/** Spend descriptor for OUR key: p2wpkh from the compressed key, p2tr from its x-only form (BIP-86 key-path, no script tree). */\nexport function spendInfo(publicKey: Uint8Array, network: BTC_NETWORK, type: BtcAddressType) {\n if (type === 'p2tr') return p2tr(publicKey.length === 33 ? publicKey.subarray(1) : publicKey, undefined, network)\n return p2wpkh(publicKey, network)\n}\n\n/** Address of a compressed public key: p2wpkh (`bc1q…`) or p2tr key-path (`bc1p…`). */\nexport function addressFromPublicKey(publicKey: Uint8Array, network: BTC_NETWORK, type: BtcAddressType = 'p2wpkh'): string {\n const { address } = spendInfo(publicKey, network, type)\n if (!address) throw new Error(`Could not derive a ${type} address`)\n return address\n}\n\n// ── Size + dust constants (Bitcoin Core policy) ─────────────────────────────\n\n/** Weight units one of OUR inputs adds once signed (prevout 41 B × 4 + witness). p2wpkh assumes a 72-byte DER sig. */\nexport const INPUT_WEIGHT: Record<BtcAddressType, number> = { p2wpkh: 272, p2tr: 230 }\n\n/** Virtual bytes an output of this script kind occupies (8 B value + 1 B len + script). */\nexport function outputVBytes(kind: ScriptKind, script?: Uint8Array): number {\n switch (kind) {\n case 'wpkh': return 31\n case 'tr': case 'wsh': return 43\n case 'pkh': return 34\n case 'sh': return 32\n default: return 9 + (script?.length ?? 34)\n }\n}\n\n/** Bitcoin Core dust threshold (3 sat/vB discard rate) per output type, in sats. */\nexport function dustLimit(kind: ScriptKind): bigint {\n switch (kind) {\n case 'wpkh': return 294n\n case 'tr': case 'wsh': return 330n\n case 'pkh': return 546n\n case 'sh': return 540n\n default: return 546n\n }\n}\n\n/** Smallest p2wpkh output relay policy accepts, in satoshis. */\nexport const DUST_LIMIT_P2WPKH = dustLimit('wpkh')\n/** Smallest p2tr output relay policy accepts, in satoshis. */\nexport const DUST_LIMIT_P2TR = dustLimit('tr')\n\nexport const kindOfType = (type: BtcAddressType): ScriptKind => (type === 'p2tr' ? 'tr' : 'wpkh')\n","import { NETWORK, TEST_NETWORK } from '@scure/btc-signer'\nimport type { BTC_NETWORK } from '@scure/btc-signer/utils.js'\nimport type { BtcAddressType, BtcNetwork } from './types.js'\n\n/** btc-signer ships mainnet + testnet; regtest only differs in the bech32 HRP. */\nexport const REGTEST_NETWORK: BTC_NETWORK = Object.freeze({ bech32: 'bcrt', pubKeyHash: 0x6f, scriptHash: 0xc4, wif: 0xef })\n\n/** `@scure/btc-signer` parameters of a network. */\nexport function networkParams(network: BtcNetwork): BTC_NETWORK {\n switch (network) {\n case 'bitcoin': return NETWORK\n case 'testnet': return TEST_NETWORK\n case 'regtest': return REGTEST_NETWORK\n default: throw new Error(`Unknown bitcoin network: ${String(network)}`)\n }\n}\n\n/** SLIP-44 coin type: 0 for mainnet, 1 for every test network. */\nexport const coinType = (network: BtcNetwork): 0 | 1 => (network === 'bitcoin' ? 0 : 1)\n\n/** BIP purpose for the address type: 84 (p2wpkh) or 86 (p2tr). */\nexport const purposeFor = (type: BtcAddressType): 84 | 86 => (type === 'p2tr' ? 86 : 84)\n","import { InsufficientFundsError, NetworkError, type IWalletAccountReadOnly } from '@anywalletkit/core'\nimport type { BTC_NETWORK } from '@scure/btc-signer/utils.js'\nimport { INPUT_WEIGHT, decodeAddress, dustLimit, kindOfType, outputVBytes, spendInfo, type ScriptKind } from './address.js'\nimport { createClient } from './client.js'\nimport { MAX_UTXO_INPUTS, selectAll, selectCoins, type CoinSelection } from './coinselect.js'\nimport { DEFAULT_MAX_FEE_RATE } from './describe.js'\nimport { UnsupportedAddressTypeError } from './errors.js'\nimport { recoverMessagePublicKey } from './message.js'\nimport { networkParams } from './network.js'\nimport { CAIP2_GENESIS, type BtcAddressType, type BtcClient, type BtcConfig, type BtcMaxSpendableResult, type BtcNetwork, type BtcReceipt, type BtcSpend, type BtcTransferOptions } from './types.js'\n\nexport { MAX_UTXO_INPUTS }\n\n/** A coin selection for one spend, with the recipient's script. */\nexport interface SpendPlan extends CoinSelection {\n /** Sats the recipient gets (the requested value — never reduced). */\n amount: bigint\n recipientScript: Uint8Array\n recipientKind: ScriptKind\n}\n\nconst toBig = (v: bigint | number | string): bigint => (typeof v === 'bigint' ? v : BigInt(Math.round(Number(v))))\nexport const toHex = (u8: Uint8Array) => Array.from(u8, (b) => b.toString(16).padStart(2, '0')).join('')\n\n/** Watch-only Bitcoin account: balances, quotes, receipts, BIP-137 verification. No key. */\nexport class WalletAccountReadOnlyBtc implements IWalletAccountReadOnly {\n /** The address. */\n readonly address: string\n readonly chain: string\n /** Output script of `address`. */\n readonly scriptPubKey: Uint8Array\n /** Script type of the address. */\n readonly scriptKind: ScriptKind\n /** p2wpkh / p2tr when the address is one we know how to spend from; undefined for other script types. */\n readonly addressType: BtcAddressType | undefined\n /** Smallest output this address type may create, in satoshis. */\n readonly dustLimit: bigint\n protected readonly _config: BtcConfig\n protected readonly _client: BtcClient | undefined\n protected readonly _network: BTC_NETWORK\n protected readonly _networkName: BtcNetwork\n\n constructor(address: string, config: BtcConfig = {}) {\n this._config = config\n this._networkName = config.network ?? 'bitcoin'\n this._network = networkParams(this._networkName)\n const decoded = decodeAddress(address, this._network)\n this.address = address\n this.scriptPubKey = decoded.script\n this.scriptKind = decoded.kind\n this.addressType = decoded.kind === 'wpkh' ? 'p2wpkh' : decoded.kind === 'tr' ? 'p2tr' : undefined\n this.dustLimit = dustLimit(decoded.kind)\n this.chain = CAIP2_GENESIS[this._networkName]\n this._client = createClient(config)\n }\n\n protected requireClient(what: string): BtcClient {\n if (!this._client) throw new NetworkError(`The wallet must be connected to a client to ${what}.`)\n return this._client\n }\n\n /** Fee-rate ceiling in sat/vB: `BtcConfig.maxFeeRate` or {@link DEFAULT_MAX_FEE_RATE}. */\n get maxFeeRate(): number {\n return this._config.maxFeeRate ?? DEFAULT_MAX_FEE_RATE\n }\n\n /** The address. */\n async getAddress(): Promise<string> { return this.address }\n\n /** Confirmed minus pending outgoing (Bitcoin Core wallet semantics). */\n async getBalance(): Promise<bigint> {\n const { confirmed, unconfirmed, unconfirmedOutgoing } = await this.requireClient('read balances').getBalance(this.address)\n return unconfirmedOutgoing !== undefined ? confirmed - unconfirmedOutgoing : confirmed + unconfirmed\n }\n\n /** Always throws: Bitcoin has no tokens. */\n async getTokenBalance(_token: string): Promise<bigint> {\n throw new Error(\"The 'getTokenBalance' method is not supported on the bitcoin blockchain.\")\n }\n\n /** Weight one of OUR inputs adds; throws for address types we cannot spend from. */\n protected inputWeight(): number {\n if (!this.addressType) throw new UnsupportedAddressTypeError(`Cannot build spends from a ${this.scriptKind} address; only p2wpkh and p2tr accounts spend.`)\n return INPUT_WEIGHT[this.addressType]\n }\n\n protected async resolveFeeRate(spend: { feeRate?: bigint | number; confirmationTarget?: number }): Promise<bigint> {\n if (spend.feeRate !== undefined) {\n const r = toBig(spend.feeRate)\n return r < 1n ? 1n : r\n }\n const est = await this.requireClient('estimate fees').estimateFee(spend.confirmationTarget ?? 1)\n return BigInt(Math.max(Math.ceil(est), 1))\n }\n\n /** Coin selection for a spend (see coinselect.ts). Validates the recipient and the dust floor first. */\n protected async planSpend(spend: BtcSpend): Promise<SpendPlan> {\n const amount = toBig(spend.value)\n const recipient = decodeAddress(spend.to, this._network)\n const floor = dustLimit(recipient.kind)\n if (amount < floor) throw new Error(`The amount must be at least the dust limit of the recipient's address type (${floor} sat).`)\n const inputWeight = this.inputWeight()\n const feeRate = await this.resolveFeeRate(spend)\n const utxos = await this.requireClient('plan a spend').listUnspent(this.address)\n if (utxos.length === 0) throw new InsufficientFundsError(amount, 0n, 'BTC')\n const own = kindOfType(this.addressType!)\n const selection = selectCoins({\n utxos,\n targets: [{ value: amount, vbytes: outputVBytes(recipient.kind, recipient.script) }],\n feeRate,\n inputWeight,\n changeVBytes: outputVBytes(own),\n changeDust: dustLimit(own),\n maxInputs: this._config.maxInputs ?? MAX_UTXO_INPUTS,\n })\n return { ...selection, amount, recipientScript: recipient.script, recipientKind: recipient.kind }\n }\n\n /** Fee of a spend in satoshis, from a coin selection at the current fee rate. */\n async quoteSendTransaction(tx: BtcSpend): Promise<{ fee: bigint }> {\n const { fee } = await this.planSpend(tx)\n return { fee }\n }\n\n /**\n * Fee of a transfer in satoshis.\n *\n * @throws Error when `token` is set.\n */\n async quoteTransfer(o: BtcTransferOptions): Promise<{ fee: bigint }> {\n if (o.token) throw new Error('Tokens are not supported on the bitcoin blockchain.')\n return this.quoteSendTransaction({ to: o.recipient, value: o.amount })\n }\n\n /** Everything spendable in ONE transaction to a single output of our own address type, no change. */\n async getMaxSpendable(opts: { feeRate?: bigint | number; confirmationTarget?: number; to?: string } = {}): Promise<BtcMaxSpendableResult> {\n const inputWeight = this.inputWeight()\n const feeRate = await this.resolveFeeRate(opts)\n const utxos = await this.requireClient('plan a spend').listUnspent(this.address)\n const outKind = opts.to ? decodeAddress(opts.to, this._network).kind : kindOfType(this.addressType!)\n const sweep = selectAll({ utxos, feeRate, inputWeight, outputVBytes: outputVBytes(outKind), maxInputs: this._config.maxInputs ?? MAX_UTXO_INPUTS })\n const amount = sweep.amount >= dustLimit(outKind) ? sweep.amount : 0n\n return { amount, fee: amount > 0n ? sweep.fee : 0n, changeValue: 0n, inputs: amount > 0n ? sweep.utxos.length : 0, feeRate }\n }\n\n /** Undefined until the transaction is mined. */\n async getTransactionReceipt(hash: string): Promise<BtcReceipt | undefined> {\n if (!/^[0-9a-fA-F]{64}$/.test(hash)) throw new Error(\"The 'getTransactionReceipt(hash)' method requires a valid transaction hash.\")\n const client = this.requireClient('fetch transaction receipts')\n const info = client.getTransactionInfo ? await client.getTransactionInfo(hash) : undefined\n if (!info || !info.blockHeight || info.blockHeight <= 0) return undefined\n return {\n hash, status: 1, blockNumber: BigInt(info.blockHeight), confirmations: info.confirmations,\n ...(info.fees !== undefined ? { fee: BigInt(info.fees) } : {}), ...(info.hex !== undefined ? { hex: info.hex } : {}),\n }\n }\n\n /** BIP-137: recover the key and compare its p2wpkh address with ours. Taproot addresses have no BIP-137 form. */\n async verify(message: string | Uint8Array, signature: string): Promise<boolean> {\n if (this.addressType === 'p2tr') throw new UnsupportedAddressTypeError('BIP-137 message signatures do not exist for taproot addresses (BIP-322 is not implemented).')\n const rec = recoverMessagePublicKey(message, signature)\n if (!rec || rec.publicKey.length !== 33) return false\n try { return spendInfo(rec.publicKey, this._network, 'p2wpkh').address === this.address } catch { return false }\n }\n\n /** Chain tip for anti-fee-sniping; undefined when disabled or the transport cannot tell. */\n protected async lockTimeHeight(): Promise<number> {\n if (this._config.antiFeeSniping === false || !this._client?.getBlockHeight) return 0\n try { return await this._client.getBlockHeight() } catch { return 0 }\n }\n}\n","import { InsufficientFundsError, LocalSigner, SignerError, feeLimit, requireCurve, type IWalletAccount, type IWalletAccountReadOnly, type Signer, type TransferResult, type WriteOptions } from '@anywalletkit/core'\nimport { SigHash, Transaction, p2pkh } from '@scure/btc-signer'\nimport type { BTC_NETWORK } from '@scure/btc-signer/utils.js'\nimport { schnorr, secp256k1 } from '@noble/curves/secp256k1.js'\nimport { hex } from '@scure/base'\nimport { addressFromPublicKey, spendInfo } from './address.js'\nimport { FINAL_SEQUENCE, RBF_SEQUENCE, assertSafe, describeTransaction, parseRawTransaction, type DescribeContext } from './describe.js'\nimport { UnsafeTransactionError, UnsupportedAddressTypeError } from './errors.js'\nimport { signMessageWith } from './message.js'\nimport { networkParams } from './network.js'\nimport { WalletAccountReadOnlyBtc, type SpendPlan } from './read-only-account.js'\nimport type { BtcAddressType, BtcConfig, BtcNetwork, BtcSpend, BtcTransaction, BtcTransferOptions, BtcTxDescription, Utxo } from './types.js'\n\nexport { addressFromPublicKey }\n\n/** Address for a compressed public key; `network` may be a name or btc-signer params. */\nexport function addressFor(publicKey: Uint8Array, network: BtcNetwork | BTC_NETWORK = 'bitcoin', type: BtcAddressType = 'p2wpkh'): string {\n return addressFromPublicKey(publicKey, typeof network === 'string' ? networkParams(network) : network, type)\n}\n\ninterface Built {\n tx: Transaction\n fee: bigint\n plan: SpendPlan\n desc: BtcTxDescription\n}\n\n/**\n * Signing Bitcoin account — BIP-84 p2wpkh or BIP-86 p2tr (key-path). The key never\n * enters this package: every signature is one `signer.sign(...)` call over a\n * btc-signer-computed sighash — a {@link LocalSigner} for seed wallets, anything\n * else (hardware, MPC, backend) through `externalSigner()`:\n *\n * ```text\n * p2wpkh input → `ecdsa` over the BIP-143 sighash (SIGHASH_ALL), DER-encoded here\n * p2tr input → `schnorr` + `tweak` over the BIP-341 sighash (DEFAULT), tweak = TapTweak(xonly)\n * BIP-137 msg → `ecdsa-recoverable` over the magic hash\n * ```\n *\n * Every spend is resolved to a full description (\"what you sign\") and run through\n * the hard safety checks (fee-rate ceiling, recipient/amount exactness, change\n * ownership) before signing AND before broadcast — also for caller-supplied raw hex.\n */\nexport class WalletAccountBtc extends WalletAccountReadOnlyBtc implements IWalletAccount {\n /** UTXOs, fee rate and tip height come from the network before signing. */\n readonly needsNetwork = true\n /** Derivation path, or `external` for an external signer. */\n readonly path: string\n /** Compressed secp256k1 public key. */\n readonly publicKey: Uint8Array\n override readonly addressType: BtcAddressType\n /** The signer that holds the key. */\n readonly signer: Signer\n private _disposed = false\n private _readOnly: WalletAccountReadOnlyBtc | undefined\n\n /** `publicKey` is the signer's compressed secp256k1 key (33 bytes); it is needed synchronously for the address. */\n constructor(signer: Signer, publicKey: Uint8Array, path: string, config: BtcConfig = {}) {\n const type = config.addressType ?? 'p2wpkh'\n super(addressFromPublicKey(publicKey, networkParams(config.network ?? 'bitcoin'), type), config)\n this.addressType = type\n this.signer = requireCurve(signer, 'secp256k1')\n // Fail at construction, not mid-spend: taproot key-path needs schnorr, p2wpkh needs plain ecdsa.\n const needed = type === 'p2tr' ? 'schnorr' : 'ecdsa'\n if (!this.signer.schemes.includes(needed)) throw new SignerError(`A ${type} account needs a signer with the '${needed}' scheme (has: ${this.signer.schemes.join(', ')}).`)\n this.publicKey = publicKey\n this.path = path\n }\n\n /** Back-compat: wrap a raw derived key in a {@link LocalSigner} (the account takes ownership; it cannot derive). */\n static fromPrivateKey(privateKey: Uint8Array, publicKey: Uint8Array, path: string, config: BtcConfig = {}): WalletAccountBtc {\n return new WalletAccountBtc(LocalSigner.fromPrivateKey('secp256k1', privateKey, publicKey, path), publicKey, path, config)\n }\n\n /** Account index for the standard m/{84|86}'/{0|1}'/0'/0/i path. */\n get index(): number | undefined {\n const m = /^m\\/8[46]'\\/[01]'\\/0'\\/0\\/(\\d+)$/.exec(this.path)\n return m ? Number(m[1]) : undefined\n }\n\n private live(): void {\n if (this._disposed) throw new SignerError('This account has been disposed.')\n }\n\n /** BIP-137 p2wpkh signature, base64 (Electrum / Bitcoin Core encoding). Not available for taproot accounts. */\n async sign(message: string | Uint8Array): Promise<string> {\n this.live()\n if (this.addressType === 'p2tr') throw new UnsupportedAddressTypeError('BIP-137 message signatures do not exist for taproot accounts (BIP-322 is not implemented).')\n return signMessageWith(message, this.signer, 'p2wpkh')\n }\n\n /** The x-only internal key and its BIP-86 tweak (no script tree) for taproot key-path spends. */\n private taprootKeys(): { xonly: Uint8Array; tweak: Uint8Array } {\n const xonly = this.publicKey.length === 33 ? this.publicKey.subarray(1) : this.publicKey\n return { xonly, tweak: schnorr.utils.taggedHash('TapTweak', xonly) }\n }\n\n /**\n * Sign every input through the signer and attach the witness-ready signature:\n * p2wpkh → `partialSig` (DER + SIGHASH_ALL), p2tr → `tapKeySig` (64 bytes, DEFAULT).\n * btc-signer only computes the sighash and assembles the witness; it never sees a key.\n */\n private async signInputs(tx: Transaction, values: bigint[]): Promise<void> {\n if (this.addressType === 'p2tr') {\n const { tweak } = this.taprootKeys()\n const scripts = Array.from({ length: tx.inputsLength }, () => this.scriptPubKey)\n for (let i = 0; i < tx.inputsLength; i++) {\n const sighash = tx.preimageWitnessV1(i, scripts, SigHash.DEFAULT, values)\n const sig = await this.signer.sign(sighash, { scheme: 'schnorr', context: 'btc-taproot-keypath', tweak })\n tx.updateInput(i, { tapKeySig: sig }, true)\n }\n return\n }\n const scriptCode = p2pkh(this.publicKey).script\n for (let i = 0; i < tx.inputsLength; i++) {\n const sighash = tx.preimageWitnessV0(i, scriptCode, SigHash.ALL, values[i]!)\n const rs = await this.signer.sign(sighash, { scheme: 'ecdsa', context: 'btc-sighash' })\n const der = secp256k1.Signature.fromBytes(rs, 'compact').toBytes('der')\n const sig = new Uint8Array(der.length + 1)\n sig.set(der, 0)\n sig[der.length] = SigHash.ALL\n tx.updateInput(i, { partialSig: [[this.publicKey, sig]] }, true)\n }\n }\n\n private ctx(intended?: { to: string; value: bigint }): DescribeContext {\n return { network: this._network, ownAddress: this.address, intended, maxFeeRate: this.maxFeeRate }\n }\n\n private async signPlan(plan: SpendPlan, to: string, recipientValue: bigint, change: bigint, lockTime: number, rbf: boolean): Promise<Transaction> {\n const spend = spendInfo(this.publicKey, this._network, this.addressType)\n const tx = new Transaction({ lockTime })\n const sequence = rbf ? RBF_SEQUENCE : FINAL_SEQUENCE\n for (const u of plan.utxos) {\n tx.addInput({ ...spend, txid: u.txid, index: u.vout, sequence, witnessUtxo: { script: this.scriptPubKey, amount: u.value } })\n }\n tx.addOutputAddress(to, recipientValue, this._network)\n if (change > 0n) tx.addOutputAddress(this.address, change, this._network)\n await this.signInputs(tx, plan.utxos.map((u) => u.value))\n tx.finalize()\n return tx\n }\n\n /**\n * Plan → sign → measure. The plan's fee assumes 72-byte DER signatures; if the\n * signed vsize somehow needs more, the difference comes out of change (never the\n * recipient) and the tx is re-signed once.\n */\n protected async signSpend(spend: BtcSpend): Promise<Built> {\n this.live()\n const plan = await this.planSpend(spend)\n await this.verifyPrevouts(plan.utxos)\n const lockTime = await this.lockTimeHeight()\n const rbf = spend.rbf ?? this._config.rbf ?? true\n let change = plan.change\n let fee = plan.fee\n let tx = await this.signPlan(plan, spend.to, plan.amount, change, lockTime, rbf)\n const required = BigInt(tx.vsize) * plan.feeRate\n if (required > fee) {\n const delta = required - fee\n if (change === 0n) {\n const have = plan.utxos.reduce((s, u) => s + u.value, 0n)\n throw new InsufficientFundsError(plan.amount + required, have, 'BTC')\n }\n change = change - delta\n if (change < this.dustLimit) { fee = plan.fee + plan.change; change = 0n } else fee = required\n tx = await this.signPlan(plan, spend.to, plan.amount, change, lockTime, rbf)\n if (BigInt(tx.vsize) * plan.feeRate > fee) throw new Error('Fee shortfall after output rebalance.')\n }\n const ctx = this.ctx({ to: spend.to, value: plan.amount })\n const desc = describeTransaction(tx, plan.utxos.map((u) => u.value), ctx)\n assertSafe(desc, ctx)\n return { tx, fee, plan, desc }\n }\n\n private checkMax(fee: bigint, limit: bigint | number | undefined, op: string) {\n if (limit !== undefined && fee > BigInt(limit)) throw new Error(`Exceeded maximum fee cost for ${op} operation.`)\n }\n\n /**\n * BIP-143 (p2wpkh) commits each input's signature to that input's CLAIMED amount\n * only: an indexer that understates a different coin in each of two signing\n * sessions can combine their signatures into one valid tx whose real fee the\n * wallet never showed (scan 2026-10-23 F2). So every p2wpkh coin is read from\n * its full previous transaction, which must hash to the claimed txid, and its\n * amount and script must match before anything is signed. Taproot (BIP-341)\n * commits to every input amount and skips the extra requests.\n */\n private async verifyPrevouts(utxos: Utxo[]): Promise<void> {\n if (this.addressType === 'p2tr') return\n const client = this.requireClient('verify the coins it spends')\n const ours = hex.encode(this.scriptPubKey)\n const cache = new Map<string, Transaction>()\n for (const u of utxos) {\n let prev = cache.get(u.txid)\n if (!prev) {\n prev = parseRawTransaction(await client.getTransaction(u.txid))\n if (prev.id !== u.txid) throw new UnsafeTransactionError('prevout-mismatch', `The indexer's transaction for ${u.txid} hashes to ${prev.id}.`)\n cache.set(u.txid, prev)\n }\n const out = u.vout < prev.outputsLength ? prev.getOutput(u.vout) : undefined\n if (out?.amount === undefined || out.amount !== u.value) {\n throw new UnsafeTransactionError('prevout-mismatch', `Coin ${u.txid}:${u.vout} is worth ${out?.amount ?? 'nothing'} sat on chain, not the ${u.value} the indexer reported.`)\n }\n if (!out.script || hex.encode(out.script) !== ours) throw new UnsafeTransactionError('prevout-mismatch', `Coin ${u.txid}:${u.vout} does not pay this account.`)\n }\n }\n\n /** Prevout values of a raw tx, fetched through the client (the wire format carries none). */\n private async inputValues(tx: Transaction): Promise<bigint[]> {\n const client = this.requireClient('inspect a raw transaction')\n const cache = new Map<string, Transaction>()\n const values: bigint[] = []\n for (let i = 0; i < tx.inputsLength; i++) {\n const inp = tx.getInput(i)\n if (!inp.txid || inp.index === undefined) throw new Error('Raw transaction input without a prevout.')\n const id = hex.encode(inp.txid)\n let prev = cache.get(id)\n if (!prev) {\n prev = parseRawTransaction(await client.getTransaction(id))\n // An unauthenticated prevout would let the indexer forge the fee this check computes (scan F2).\n if (prev.id !== id) throw new UnsafeTransactionError('prevout-mismatch', `The indexer's transaction for ${id} hashes to ${prev.id}.`)\n cache.set(id, prev)\n }\n const out = prev.getOutput(inp.index)\n if (out.amount === undefined) throw new Error(`Prevout ${id}:${inp.index} not found.`)\n values.push(out.amount)\n }\n return values\n }\n\n /** Describe a raw signed tx (needs the network for prevout values) and run the safety checks. */\n private async describeRaw(rawHex: string): Promise<{ tx: Transaction; desc: BtcTxDescription }> {\n const tx = parseRawTransaction(rawHex)\n const ctx = this.ctx()\n const desc = describeTransaction(tx, await this.inputValues(tx), ctx)\n assertSafe(desc, ctx)\n return { tx, desc }\n }\n\n /** \"What you sign\": the fully resolved spend (signed, NOT broadcast) or a caller's raw hex. */\n async describeTransaction(tx: BtcTransaction): Promise<BtcTxDescription> {\n if (typeof tx === 'string') return (await this.describeRaw(tx)).desc\n return (await this.signSpend(tx)).desc\n }\n\n /** Sign without broadcasting. Returns the raw transaction hex. Raw hex input gets the checks `sendTransaction` runs (prevouts through the client) and is returned unchanged, never re-signed. */\n async signTransaction(tx: BtcTransaction, options: WriteOptions = {}): Promise<string> {\n this.live()\n if (typeof tx === 'string') {\n const { desc } = await this.describeRaw(tx)\n this.checkMax(desc.fee, feeLimit(this._config.transactionMaxFee, options), 'transaction')\n return tx\n }\n const { tx: built, fee } = await this.signSpend(tx)\n this.checkMax(fee, feeLimit(this._config.transactionMaxFee, options), 'transaction')\n return built.hex\n }\n\n override async quoteSendTransaction(tx: BtcTransaction): Promise<{ fee: bigint }> {\n if (typeof tx === 'string') return { fee: (await this.describeRaw(tx)).desc.fee }\n return super.quoteSendTransaction(tx)\n }\n\n async sendTransaction(tx: BtcTransaction, options: WriteOptions = {}): Promise<TransferResult> {\n this.live()\n const client = this.requireClient('send transactions')\n let rawHex: string, hash: string, fee: bigint\n if (typeof tx === 'string') {\n const { tx: parsed, desc } = await this.describeRaw(tx)\n rawHex = tx; hash = parsed.id; fee = desc.fee\n } else {\n const built = await this.signSpend(tx)\n rawHex = built.tx.hex; hash = built.tx.id; fee = built.fee\n }\n this.checkMax(fee, feeLimit(this._config.transactionMaxFee, options), 'transaction')\n const txid = await client.broadcast(rawHex)\n return { hash: txid || hash, fee }\n }\n\n /** Native BTC only (`token` is rejected). Subject to `transferMaxFee`. */\n async transfer(o: BtcTransferOptions, writeOptions: WriteOptions = {}): Promise<TransferResult> {\n if (o.token) throw new Error('Tokens are not supported on the bitcoin blockchain.')\n this.live()\n const client = this.requireClient('transfer')\n const built = await this.signSpend({ to: o.recipient, value: o.amount })\n this.checkMax(built.fee, feeLimit(this._config.transferMaxFee, writeOptions), 'transfer')\n const txid = await client.broadcast(built.tx.hex)\n return { hash: txid || built.tx.id, fee: built.fee }\n }\n\n /** The same address as a {@link WalletAccountReadOnlyBtc}. */\n toReadOnlyAccount(): IWalletAccountReadOnly {\n this._readOnly ??= new WalletAccountReadOnlyBtc(this.address, this._config)\n return this._readOnly\n }\n\n dispose(): void {\n this._disposed = true\n this.signer.dispose()\n }\n}\n","import { LocalSigner, SignerError, WalletManager, isSeedSigner, type FeeRates, type Signer } from '@anywalletkit/core'\nimport { WalletAccountBtc } from './account.js'\nimport { coinType, purposeFor } from './network.js'\nimport { WalletAccountReadOnlyBtc } from './read-only-account.js'\nimport type { BtcConfig } from './types.js'\n\n/**\n * One seed → Bitcoin accounts.\n * p2wpkh (default): BIP-84, m/84'/0'/0'/0/i on mainnet, m/84'/1'/0'/0/i on test networks — bc1q… / tb1q…\n * p2tr: BIP-86, m/86'/0'/0'/0/i (key-path taproot) — bc1p… / tb1p…\n * Paths may be relative to the purpose/coin prefix (\"0'/0/i\") or given in full.\n *\n * Built with a secp256k1 `Signer` instead of a seed, the manager wraps it:\n * - a derivable `SeedSigner` sitting at the account branch (`m/84'/0'/0'/0` or\n * `m/86'/0'/0'/0`, per `addressType`/`network`) yields `getAccount(i)` children;\n * - a `SeedSigner` at a leaf, or any external signer, is `getAccount(0)` (path = the\n * signer's path, or 'external') with the configured address type; other\n * indexes/paths throw.\n */\nexport class WalletManagerBtc extends WalletManager<WalletAccountBtc, BtcConfig> {\n constructor(seedOrSigner: string | Uint8Array | Signer, config: BtcConfig = {}) {\n super(seedOrSigner, config)\n }\n\n\n /**\n * `m/84'/0'` for p2wpkh or `m/86'/0'` for p2tr on mainnet (coin type 1 on test networks); account\n * `i` is at `basePath/0'/0/i`.\n */\n get basePath(): string {\n return `m/${purposeFor(this._config.addressType ?? 'p2wpkh')}'/${coinType(this._config.network ?? 'bitcoin')}'`\n }\n\n async getAccount(index = 0): Promise<WalletAccountBtc> {\n return this.getAccountByPath(`${this.basePath}/0'/0/${index}`)\n }\n\n async getAccountByPath(path: string): Promise<WalletAccountBtc> {\n const full = path.startsWith('m/') ? path : `${this.basePath}/${path}`\n const cached = this._accounts.get(full)\n if (cached) return cached\n const external = this.externalSigner()\n if (external) return this.fromSigner(external, full)\n return this.cachedAccount(full, () => {\n const signer = LocalSigner.leafFromSeed(this.seedBytes(), 'secp256k1', full)\n return new WalletAccountBtc(signer, signer.publicKey, full, this._config)\n })\n }\n\n /** Resolve `path` against an injected signer: the signer itself, or a child when it can derive there. */\n private async fromSigner(signer: Signer, path: string): Promise<WalletAccountBtc> {\n this.requireSigner('secp256k1')\n let rel: string | undefined\n let key = 'external'\n if (isSeedSigner(signer)) {\n if (path === signer.path) key = path\n else if (path.startsWith(`${signer.path}/`)) { rel = path.slice(signer.path.length + 1); key = path }\n else throw new SignerError(`The injected signer sits at ${signer.path}; it cannot provide ${path}.`)\n } else if (path !== `${this.basePath}/0'/0/0` && path !== 'external') {\n throw new SignerError(`An external signer has one account; ${path} is not derivable from it.`)\n }\n return this.signerAccount(key, signer, rel, (leaf, publicKey) => new WalletAccountBtc(leaf, publicKey, key, this._config))\n }\n\n /** A read-only account for any address, with this manager's config. */\n getReadOnlyAccount(address: string): WalletAccountReadOnlyBtc {\n return new WalletAccountReadOnlyBtc(address, this._config)\n }\n\n /** sat/vB from the client's estimator: fast = 1 block, normal = 3, slow = 6. */\n async getFeeRates(): Promise<FeeRates> {\n const probe = new WalletAccountReadOnlyBtc(\n (this._config.network ?? 'bitcoin') === 'bitcoin' ? 'bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu' : 'tb1q6rz28mcfaxtmd6v789l9rrlrusdprr9pqcpvkl',\n this._config,\n )\n const client = (probe as unknown as { requireClient(w: string): { estimateFee(b: number): Promise<number> } }).requireClient('get fee rates')\n const [fast, normal, slow] = await Promise.all([1, 3, 6].map((b) => client.estimateFee(b)))\n const big = (n: number) => BigInt(Math.max(Math.ceil(n), 1))\n return { slow: big(slow!), normal: big(normal!), fast: big(fast!) }\n }\n\n}\n"],"mappings":"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","names":["NetworkError","NetworkError","hex","NetworkError","NetworkError","InsufficientFundsError","outputVBytes","InsufficientFundsError","InsufficientFundsError","NetworkError","NetworkError","unconfirmedOutgoing","InsufficientFundsError","InsufficientFundsError","SignerError","Transaction","secp256k1","hex","SignerError","secp256k1","Transaction","InsufficientFundsError","hex","LocalSigner","SignerError","LocalSigner","SignerError"]}
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/esplora.ts","../src/client.ts","../src/message.ts","../src/coinselect.ts","../src/describe.ts","../src/address.ts","../src/network.ts","../src/read-only-account.ts","../src/account.ts","../src/manager.ts"],"sourcesContent":["export { InsufficientFundsError, NetworkError, SignerError } from '@anywalletkit/core'\n\n/** Why a spend was refused before signing. */\nexport type UnsafeTransactionCode =\n /** Fee rate above `maxFeeRate`. */\n | 'fee-rate-too-high'\n /** An output that is neither the requested recipient/amount nor our change. */\n | 'unexpected-output'\n /** The recipient output is missing or carries a different amount. */\n | 'recipient-mismatch'\n /** A change output pays an address that is not ours. */\n | 'change-not-ours'\n /** A coin the indexer reported does not match its previous transaction (txid, amount or script). */\n | 'prevout-mismatch'\n\n/** A transaction failed a hard safety check and was not signed / broadcast. */\nexport class UnsafeTransactionError extends Error {\n readonly code: UnsafeTransactionCode\n constructor(code: UnsafeTransactionCode, message: string) {\n super(message)\n this.name = 'UnsafeTransactionError'\n this.code = code\n }\n}\n\n/** Coin selection would need more inputs than `maxInputs` allows. */\nexport class TooManyInputsError extends Error {\n readonly maxInputs: number\n constructor(maxInputs: number) {\n super(`The spend needs more than ${maxInputs} inputs; consolidate the UTXOs first or raise maxInputs.`)\n this.name = 'TooManyInputsError'\n this.maxInputs = maxInputs\n }\n}\n\n/** BIP-137 message signatures only exist for p2pkh/p2wpkh keys; taproot accounts have none (BIP-322 is not implemented). */\nexport class UnsupportedAddressTypeError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'UnsupportedAddressTypeError'\n }\n}\n\n/**\n * The transaction was handed to the network but no definitive answer came back (no response, a\n * timeout, a 5xx, an unreadable body): it MAY be in the mempool. Do not build another spend of the\n * same coins — watch `hash`, the txid computed before sending (round 3, M12).\n */\nexport class BroadcastUnknownError extends Error {\n /** Always true: the transaction may be on its way. */\n readonly maybeSent = true\n /** The transaction id (hex). */\n readonly hash: string\n constructor(hash: string, cause: unknown) {\n super(`Broadcast outcome unknown for ${hash}: ${cause instanceof Error ? cause.message.slice(0, 200) : String(cause).slice(0, 200)}`, { cause })\n this.name = 'BroadcastUnknownError'\n this.hash = hash\n }\n}\n","import { NetworkError } from '@anywalletkit/core'\nimport { DEFAULT_TIMEOUT_MS, fetchWithTimeout, isHex64, isRecord, refusal, refusedStatus } from './http.js'\nimport type { BlockbookTx, BtcClient, Utxo } from './types.js'\n\ninterface EsploraStats { funded_txo_sum: number; spent_txo_sum: number }\ninterface EsploraStatus { confirmed: boolean; block_height?: number }\nconst isStats = (v: unknown): v is EsploraStats => isRecord(v) && typeof v.funded_txo_sum === 'number' && typeof v.spent_txo_sum === 'number'\nconst isStatus = (v: unknown): v is EsploraStatus => isRecord(v) && typeof v.confirmed === 'boolean'\n\n/**\n * Esplora REST transport — the API served by mempool.space (`https://mempool.space/api`)\n * and Blockstream (`https://blockstream.info/api`). Public instances exist, so it is\n * the natural fallback behind a self-hosted Blockbook.\n *\n * Balance semantics: `unconfirmedOutgoing` is the mempool net outflow\n * (spent − funded, clamped at 0), a conservative stand-in for Bitcoin Core's\n * trusted-change rule that Blockbook's richer address record allows.\n */\nexport class EsploraClient implements BtcClient {\n private readonly base: string\n private readonly fetchFn: typeof fetch\n private readonly timeoutMs: number\n\n constructor(config: { url: string }, fetchFn: typeof fetch = globalThis.fetch, timeoutMs = DEFAULT_TIMEOUT_MS) {\n const trimmed = config.url.replace(/\\/+$/, '')\n this.base = trimmed.endsWith('/api') ? trimmed : `${trimmed}/api`\n this.fetchFn = fetchFn\n this.timeoutMs = timeoutMs\n }\n\n async connect(): Promise<void> {}\n async close(): Promise<void> {}\n\n private async request(path: string, init?: RequestInit): Promise<Response> {\n const url = `${this.base}${path}`\n const res = await fetchWithTimeout(this.fetchFn, url, init, this.timeoutMs, this.base)\n if (!res.ok) {\n // A 4xx (not 408) is the server refusing: nothing was taken. A 5xx may have been forwarded (round 3, M12).\n const reason = refusedStatus(res.status) ? (await res.text().catch(() => '')).slice(0, 200) : ''\n const err = new NetworkError(`Esplora request failed: ${res.status} ${res.statusText} (${url})${reason ? `: ${reason}` : ''}`, { provider: this.base })\n throw refusedStatus(res.status) ? refusal(err) : err\n }\n return res\n }\n\n private async json<T>(path: string, check: (v: unknown) => v is T): Promise<T> {\n const res = await this.request(path)\n let body: unknown\n try { body = await res.json() } catch (e) { throw new NetworkError(`Esplora returned non-JSON for ${path}`, { provider: this.base, cause: e }) }\n if (!check(body)) throw new NetworkError(`Esplora returned an unexpected shape for ${path}`, { provider: this.base })\n return body\n }\n\n private async text(path: string, init?: RequestInit): Promise<string> {\n return (await this.request(path, init)).text()\n }\n\n async getBalance(address: string) {\n const d = await this.json(`/address/${address}`, (v): v is { chain_stats: EsploraStats; mempool_stats: EsploraStats } =>\n isRecord(v) && isStats(v.chain_stats) && isStats(v.mempool_stats))\n const confirmed = BigInt(d.chain_stats.funded_txo_sum) - BigInt(d.chain_stats.spent_txo_sum)\n const unconfirmed = BigInt(d.mempool_stats.funded_txo_sum) - BigInt(d.mempool_stats.spent_txo_sum)\n const outgoing = BigInt(d.mempool_stats.spent_txo_sum) - BigInt(d.mempool_stats.funded_txo_sum)\n return { confirmed, unconfirmed, unconfirmedOutgoing: outgoing > 0n ? outgoing : 0n }\n }\n\n async listUnspent(address: string): Promise<Utxo[]> {\n const d = await this.json(`/address/${address}/utxo`, (v): v is Array<{ txid: string; vout: number; value: number; status: EsploraStatus }> =>\n Array.isArray(v) && v.every((u) => isRecord(u) && isHex64(u.txid) && typeof u.vout === 'number' && typeof u.value === 'number' && isStatus(u.status)))\n return d.map((u) => ({ txid: u.txid, vout: u.vout, value: BigInt(u.value), height: u.status.confirmed && u.status.block_height ? u.status.block_height : -1 }))\n }\n\n /** Esplora pages 25 (mempool.space: up to 50) txs per call; walk `/txs/chain/<last>` until a short page. */\n async getHistory(address: string) {\n const items: Array<{ txid: string; height: number }> = []\n const check = (v: unknown): v is Array<{ txid: string; status: EsploraStatus }> => Array.isArray(v) && v.every((t) => isRecord(t) && isHex64(t.txid) && isStatus(t.status))\n let page = await this.json(`/address/${address}/txs`, check)\n for (;;) {\n for (const t of page) items.push({ txid: t.txid, height: t.status.confirmed && t.status.block_height ? t.status.block_height : -1 })\n if (page.length < 25) break\n const confirmedTail = [...page].reverse().find((t) => t.status.confirmed)\n if (!confirmedTail) break\n page = await this.json(`/address/${address}/txs/chain/${confirmedTail.txid}`, check)\n if (page.length === 0) break\n }\n return items\n }\n\n async getTransactionInfo(txid: string): Promise<BlockbookTx | undefined> {\n let d: { txid: string; status: EsploraStatus; fee?: number }\n try {\n d = await this.json(`/tx/${txid}`, (v): v is { txid: string; status: EsploraStatus; fee?: number } => isRecord(v) && isHex64(v.txid) && isStatus(v.status))\n } catch (e) {\n if (e instanceof NetworkError && /\\b(400|404)\\b/.test(e.message)) return undefined\n throw e\n }\n const height = d.status.confirmed && d.status.block_height ? d.status.block_height : -1\n const confirmations = height > 0 ? Math.max((await this.getBlockHeight()) - height + 1, 1) : 0\n return { txid: d.txid, blockHeight: height, confirmations, ...(typeof d.fee === 'number' ? { fees: String(d.fee) } : {}) }\n }\n\n async getTransaction(txid: string): Promise<string> {\n const hex = (await this.text(`/tx/${txid}/hex`)).trim()\n if (!/^[0-9a-fA-F]+$/.test(hex) || hex.length < 20) throw new NetworkError(`Esplora returned no hex for ${txid}`, { provider: this.base })\n return hex\n }\n\n async broadcast(rawTx: string): Promise<string> {\n const id = (await this.text('/tx', { method: 'POST', body: rawTx, headers: { 'content-type': 'text/plain' } })).trim()\n if (!/^[0-9a-fA-F]{64}$/.test(id)) throw new NetworkError(`Esplora broadcast returned an unexpected body: ${id.slice(0, 120)}`, { provider: this.base })\n return id\n }\n\n /** `/fee-estimates` → { \"1\": sat/vB, \"2\": …, \"25\": …, \"144\": … }; picks the nearest target ≥ `blocks`. */\n async estimateFee(blocks: number): Promise<number> {\n const d = await this.json('/fee-estimates', (v): v is Record<string, number> => isRecord(v) && Object.values(v).every((n) => typeof n === 'number'))\n const targets = Object.keys(d).map(Number).filter((n) => Number.isFinite(n) && n > 0).sort((a, b) => a - b)\n const target = targets.find((t) => t >= blocks) ?? targets.at(-1)\n const rate = target !== undefined ? d[String(target)] : undefined\n if (!rate || rate <= 0) throw new NetworkError('Esplora has no fee estimate', { provider: this.base })\n return rate\n }\n\n async getBlockHeight(): Promise<number> {\n const h = Number((await this.text('/blocks/tip/height')).trim())\n if (!Number.isInteger(h) || h <= 0) throw new NetworkError('Esplora did not report a block height', { provider: this.base })\n return h\n }\n}\n","import { NetworkError } from '@anywalletkit/core'\nimport { BlockbookClient } from './blockbook.js'\nimport { EsploraClient } from './esplora.js'\nimport { DEFAULT_TIMEOUT_MS, isAnsweredRefusal, refusal } from './http.js'\nimport type { BtcClient, BtcClientConfig, BtcConfig } from './types.js'\n\nconst isClient = (c: unknown): c is BtcClient => typeof c === 'object' && c !== null && typeof (c as BtcClient).listUnspent === 'function'\n\nfunction toClient(c: BtcClientConfig | BtcClient, fetchFn: typeof fetch | undefined, timeoutMs: number): BtcClient {\n if (isClient(c)) return c\n switch (c.type) {\n case 'blockbook-http': return new BlockbookClient(c.clientConfig, fetchFn, timeoutMs)\n case 'esplora-http': return new EsploraClient(c.clientConfig, fetchFn, timeoutMs)\n default: throw new Error(`Unknown BTC client type: ${String((c as { type: string }).type)}`)\n }\n}\n\nconst METHODS = ['connect', 'close', 'getBalance', 'listUnspent', 'getHistory', 'getTransaction', 'getTransactionInfo', 'broadcast', 'estimateFee', 'getBlockHeight'] as const\n\n/** One client, or a failover client over the list: each call walks the list in order, `retries` extra rounds. */\nexport function createClient(config: BtcConfig): BtcClient | undefined {\n if (config.client === undefined) return undefined\n const timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS\n const list = (Array.isArray(config.client) ? config.client : [config.client]).map((c) => toClient(c, config.fetch, timeoutMs))\n if (list.length === 0) return undefined\n if (list.length === 1) return list[0]!\n const attempts = list.length + (config.retries ?? 3)\n const call = (method: (typeof METHODS)[number]) => async (...args: unknown[]) => {\n let last: unknown\n let answered = true\n for (let i = 0; i < attempts; i++) {\n const c = list[i % list.length]! as unknown as Record<string, ((...a: unknown[]) => Promise<unknown>) | undefined>\n const fn = c[method]\n if (!fn) continue // optional method this transport lacks — try the next one\n try { return await fn.apply(c, args) } catch (e) { last = e; answered &&= isAnsweredRefusal(e) }\n }\n // Refused everywhere is a refusal; one endpoint that never answered may have taken it (round 3, M12).\n const err = new NetworkError(`All BTC clients failed for ${method}`, { cause: last })\n throw answered && last !== undefined ? refusal(err) : err\n }\n const out = {} as Record<(typeof METHODS)[number], (...args: unknown[]) => Promise<unknown>>\n for (const m of METHODS) out[m] = call(m)\n return out as unknown as BtcClient\n}\n","/**\n * BIP-137 message signatures (the Electrum / Bitcoin Core encoding):\n * hash = sha256d(varint(prefix) || prefix || varint(len) || message); header byte =\n * 27 + recovery (+4 compressed) (+8 segwit, +4 more for p2wpkh) → p2wpkh = 39 + recovery.\n * Output: base64 of header || r || s. Signing is RFC-6979 deterministic, low-S.\n *\n * Only p2pkh / p2wpkh keys have a BIP-137 form; taproot accounts must use BIP-322\n * (not implemented).\n */\nimport { sha256 } from '@noble/hashes/sha2.js'\nimport { secp256k1 } from '@noble/curves/secp256k1.js'\nimport { base64 } from '@scure/base'\nimport type { Signer } from '@anywalletkit/core'\n\nconst PREFIX = new TextEncoder().encode('\\u0018Bitcoin Signed Message:\\n') // the \\x18 IS the varint length (24) of \"Bitcoin Signed Message:\\n\"\n\nfunction varint(n: number): Uint8Array {\n if (n < 0xfd) return Uint8Array.of(n)\n if (n <= 0xffff) return Uint8Array.of(0xfd, n & 0xff, n >> 8)\n return Uint8Array.of(0xfe, n & 0xff, (n >> 8) & 0xff, (n >> 16) & 0xff, (n >>> 24) & 0xff)\n}\n\n/** BIP-137 hash of a message (`Bitcoin Signed Message:` prefix, double SHA-256). */\nexport function magicHash(message: string | Uint8Array): Uint8Array {\n const msg = typeof message === 'string' ? new TextEncoder().encode(message) : message\n const len = varint(msg.length)\n const buf = new Uint8Array(PREFIX.length + len.length + msg.length)\n buf.set(PREFIX, 0); buf.set(len, PREFIX.length); buf.set(msg, PREFIX.length + len.length)\n return sha256(sha256(buf))\n}\n\n/** Address flavour a BIP-137 signature header is written for. */\nexport type SegwitType = 'p2wpkh' | 'p2sh(p2wpkh)'\n\n/** Header flag for a compressed key: +4 compressed, +8 segwit, +4 more for p2wpkh (→ 39 + recovery). */\nfunction headerFlag(recovery: number, segwitType: SegwitType | undefined): number {\n let flag = recovery\n if (segwitType !== undefined) { flag += 8; if (segwitType === 'p2wpkh') flag += 4 } else flag += 4\n return 27 + flag\n}\n\n/** Encode `r‖s` + recovery id as a base64 BIP-137 signature. */\nexport function encodeMessageSignature(rs: Uint8Array, recovery: number, segwitType: SegwitType | undefined = 'p2wpkh'): string {\n if (rs.length !== 64 || recovery > 1) throw new Error('BIP-137: expected a 64-byte r‖s signature and a 0/1 recovery id.')\n const out = new Uint8Array(65)\n out[0] = headerFlag(recovery, segwitType)\n out.set(rs, 1)\n return base64.encode(out)\n}\n\n/** Sign with a raw private key (RFC-6979 deterministic, low-S). Kept for callers that hold a key outside a Signer. */\nexport function signMessage(message: string | Uint8Array, privateKey: Uint8Array, segwitType: SegwitType | undefined = 'p2wpkh'): string {\n // noble 'recovered' = recovery id || r || s\n const sig = secp256k1.sign(magicHash(message), privateKey, { prehash: false, format: 'recovered' })\n return encodeMessageSignature(sig.subarray(1), sig[0]!, segwitType)\n}\n\n/** Sign through a {@link Signer} (`ecdsa-recoverable`, context `btc-message`). */\nexport async function signMessageWith(message: string | Uint8Array, signer: Signer, segwitType: SegwitType | undefined = 'p2wpkh'): Promise<string> {\n const sig = await signer.sign(magicHash(message), { scheme: 'ecdsa-recoverable', context: 'btc-message' })\n return encodeMessageSignature(sig.subarray(0, 64), sig[64]!, segwitType)\n}\n\n/** Recover the public key (compressed unless the header says otherwise) from a BIP-137 signature, or undefined when malformed. */\nexport function recoverMessagePublicKey(message: string | Uint8Array, signature: string): { publicKey: Uint8Array; segwitType: SegwitType | undefined } | undefined {\n let bytes: Uint8Array\n try { bytes = base64.decode(signature) } catch { return undefined }\n if (bytes.length !== 65) return undefined\n const flag = bytes[0]! - 27\n if (flag < 0 || flag > 15) return undefined\n const recovery = flag & 3\n const compressed = !!(flag & 4) || !!(flag & 8)\n const segwit = flag & 8 ? ((flag & 4) ? 'p2wpkh' : 'p2sh(p2wpkh)') : undefined\n const recovered = new Uint8Array(65)\n recovered[0] = recovery\n recovered.set(bytes.subarray(1), 1)\n try {\n const pub = secp256k1.recoverPublicKey(recovered, magicHash(message), { prehash: false })\n const publicKey = compressed ? pub : secp256k1.Point.fromBytes(pub).toBytes(false)\n return { publicKey, segwitType: segwit }\n } catch { return undefined }\n}\n","/**\n * Coin selection — our own, deterministic, documented. (btc-signer ships\n * `selectUTXO`, but it is outside the audited scope, so it is not used.)\n *\n * Strategy: effective-value accumulation, largest first.\n * 1. Drop UTXOs whose value does not cover the fee their own input adds.\n * 2. Sort the rest by value descending (ties: txid, then vout — stable across runs).\n * 3. Add inputs until Σvalue ≥ targets + fee(no-change tx).\n * 4. If what is left after a change output is ≥ the change dust threshold, keep\n * the change; otherwise fold it into the fee (one output less).\n * 5. More than `maxInputs` inputs → TooManyInputsError.\n *\n * Fees are feeRate × vsize, vsize = ceil(weight / 4) with the standard\n * segwit weights (see address.ts). The p2wpkh input estimate assumes a 72-byte\n * DER signature, so the estimate is an upper bound for lowR signatures.\n */\nimport { InsufficientFundsError } from '@anywalletkit/core'\nimport { TooManyInputsError } from './errors.js'\nimport type { Utxo } from './types.js'\n\n/** Most inputs one spend may use; above it the account asks to consolidate first. */\nexport const MAX_UTXO_INPUTS = 200\n\n/** Version 4 + locktime 4 + input count 1 + output count 1 = 10 B × 4, plus segwit marker + flag (2 WU). */\nconst OVERHEAD_WEIGHT = 42\n\n/** An output the selection must fund. */\nexport interface SelectionTarget {\n value: bigint\n /** vbytes the output occupies (see `outputVBytes`). */\n vbytes: number\n}\n\n/** Input to {@link selectCoins}. */\nexport interface CoinSelectOptions {\n utxos: Utxo[]\n targets: SelectionTarget[]\n /** sat/vB, ≥ 1. */\n feeRate: bigint\n /** Weight units one of our inputs adds (`INPUT_WEIGHT[addressType]`). */\n inputWeight: number\n /** vbytes a change output to our own address occupies. */\n changeVBytes: number\n /** Dust threshold for our change output type. */\n changeDust: bigint\n maxInputs?: number\n}\n\n/** UTXOs chosen for a spend, the fee and the change. */\nexport interface CoinSelection {\n utxos: Utxo[]\n fee: bigint\n /** Change back to us; 0n when folded into the fee. */\n change: bigint\n /** True when change existed but fell below dust and became fee. */\n changeFolded: boolean\n /** Estimated vsize of the final transaction. */\n vsize: number\n feeRate: bigint\n}\n\n/** Virtual size (vB) of a segwit transaction with the given inputs and outputs. */\nexport function estimateVsize(inputs: number, inputWeight: number, outputVBytes: number[]): number {\n const outputWeight = outputVBytes.reduce((s, vb) => s + vb * 4, 0)\n // Count varints grow past 252 entries; one extra byte each covers up to 65535.\n const extra = (inputs > 252 ? 2 : 0) + (outputVBytes.length > 252 ? 2 : 0)\n return Math.ceil((OVERHEAD_WEIGHT + extra * 4 + inputs * inputWeight + outputWeight) / 4)\n}\n\nconst cmpUtxo = (a: Utxo, b: Utxo): number =>\n a.value > b.value ? -1 : a.value < b.value ? 1 : a.txid < b.txid ? -1 : a.txid > b.txid ? 1 : a.vout - b.vout\n\n/** UTXOs worth spending at this fee rate, largest first. */\nexport function spendableUtxos(utxos: Utxo[], feeRate: bigint, inputWeight: number): Utxo[] {\n const inputFee = BigInt(Math.ceil(inputWeight / 4)) * feeRate\n return utxos.filter((u) => u.value > inputFee).sort(cmpUtxo)\n}\n\n/**\n * Pick UTXOs to fund the targets at `feeRate` (sat/vB): change goes back when it is above dust,\n * otherwise it joins the fee.\n *\n * @throws `InsufficientFundsError` (core) when the UTXOs cannot cover targets plus fee,\n * `TooManyInputsError` above `maxInputs`, Error for a fee rate below 1 sat/vB.\n */\nexport function selectCoins(o: CoinSelectOptions): CoinSelection {\n if (o.feeRate < 1n) throw new Error('feeRate must be at least 1 sat/vB')\n const maxInputs = o.maxInputs ?? MAX_UTXO_INPUTS\n const targetSum = o.targets.reduce((s, t) => s + t.value, 0n)\n const targetVB = o.targets.map((t) => t.vbytes)\n const candidates = spendableUtxos(o.utxos, o.feeRate, o.inputWeight)\n const available = o.utxos.reduce((s, u) => s + u.value, 0n)\n\n const feeFor = (n: number, withChange: boolean) =>\n BigInt(estimateVsize(n, o.inputWeight, withChange ? [...targetVB, o.changeVBytes] : targetVB)) * o.feeRate\n\n const selected: Utxo[] = []\n let sum = 0n\n for (const u of candidates) {\n if (selected.length >= maxInputs) throw new TooManyInputsError(maxInputs)\n selected.push(u)\n sum += u.value\n const n = selected.length\n const feeNoChange = feeFor(n, false)\n if (sum < targetSum + feeNoChange) continue\n const feeWithChange = feeFor(n, true)\n const change = sum - targetSum - feeWithChange\n if (change >= o.changeDust) {\n return { utxos: selected, fee: feeWithChange, change, changeFolded: false, vsize: estimateVsize(n, o.inputWeight, [...targetVB, o.changeVBytes]), feeRate: o.feeRate }\n }\n return { utxos: selected, fee: sum - targetSum, change: 0n, changeFolded: sum - targetSum > feeNoChange, vsize: estimateVsize(n, o.inputWeight, targetVB), feeRate: o.feeRate }\n }\n const need = targetSum + feeFor(Math.max(selected.length, 1), false)\n throw new InsufficientFundsError(need, available, 'BTC')\n}\n\n/** Sweep: every spendable input (largest first, capped), one output, no change. */\nexport function selectAll(o: Omit<CoinSelectOptions, 'targets' | 'changeVBytes' | 'changeDust'> & { outputVBytes: number }): { utxos: Utxo[]; fee: bigint; amount: bigint; vsize: number } {\n const maxInputs = o.maxInputs ?? MAX_UTXO_INPUTS\n const utxos = spendableUtxos(o.utxos, o.feeRate, o.inputWeight).slice(0, maxInputs)\n if (utxos.length === 0) return { utxos, fee: 0n, amount: 0n, vsize: 0 }\n const vsize = estimateVsize(utxos.length, o.inputWeight, [o.outputVBytes])\n const fee = BigInt(vsize) * o.feeRate\n const amount = utxos.reduce((s, u) => s + u.value, 0n) - fee\n return { utxos, fee, amount: amount > 0n ? amount : 0n, vsize }\n}\n","import { Transaction } from '@scure/btc-signer'\nimport type { BTC_NETWORK } from '@scure/btc-signer/utils.js'\nimport { hex } from '@scure/base'\nimport { decodeAddress, dustLimit, scriptKind } from './address.js'\nimport { UnsafeTransactionError } from './errors.js'\nimport type { BtcTxDescription, BtcTxOutputDescription, BtcWarning } from './types.js'\nimport { bigintToNumber } from '@anywalletkit/core'\n\n/** Default fee-rate ceiling, sat/vB; a spend above it is refused. */\nexport const DEFAULT_MAX_FEE_RATE = 500\n/** Replace-by-fee signalling: any sequence below 0xfffffffe (BIP-125). */\nexport const RBF_SEQUENCE = 0xfffffffd\n/** Opts out of RBF while still letting nLockTime apply. */\nexport const FINAL_SEQUENCE = 0xfffffffe\n\n/** What a description needs to tell recipient, change and unknown outputs apart. */\nexport interface DescribeContext {\n network: BTC_NETWORK\n /** Our own address: outputs paying it are tagged `change`. */\n ownAddress: string\n /** The spend the caller asked for. Outputs matching it are `recipient`; anything else is `unknown`. */\n intended?: { to: string; value: bigint } | undefined\n maxFeeRate?: number | undefined\n}\n\n/** Parse raw tx hex. Prevout amounts are not in the wire format — callers pass them in `inputValues`. */\nexport function parseRawTransaction(rawHex: string): Transaction {\n return Transaction.fromRaw(hex.decode(rawHex), { allowUnknownInputs: true, allowUnknownOutputs: true })\n}\n\n/** Signed: exact vsize. Unsigned: the non-witness serialisation length (exact for legacy inputs, a lower bound for segwit). */\nexport function vsizeOf(tx: Transaction): number {\n try { return tx.vsize } catch { return tx.unsignedTx.length }\n}\n\n/**\n * Describe a (signed or unsigned) btc-signer Transaction given the sat value of\n * every input, in input order. Pure: no network, no signing.\n */\nexport function describeTransaction(tx: Transaction, inputValues: bigint[], ctx: DescribeContext): BtcTxDescription {\n if (inputValues.length !== tx.inputsLength) throw new Error(`describeTransaction: ${tx.inputsLength} inputs but ${inputValues.length} values`)\n const inputs = Array.from({ length: tx.inputsLength }, (_, i) => {\n const inp = tx.getInput(i)\n return { txid: inp.txid ? hex.encode(inp.txid) : '', vout: inp.index ?? 0, value: inputValues[i]! }\n })\n const outputs: BtcTxOutputDescription[] = []\n const warnings = new Set<BtcWarning>()\n // Outputs are matched by scriptPubKey, the recipient first: a transfer to oneself pays our own\n // script twice (recipient + change), and an uppercase bech32 address is the same script (round 3, L9).\n const scriptOf = (address: string): string | undefined => { try { return hex.encode(decodeAddress(address, ctx.network).script) } catch { return undefined } }\n const ownScript = scriptOf(ctx.ownAddress)\n const intendedScript = ctx.intended ? scriptOf(ctx.intended.to) : undefined\n let recipientSeen = false\n for (let i = 0; i < tx.outputsLength; i++) {\n const out = tx.getOutput(i)\n const value = out.amount ?? 0n\n const address = tx.getOutputAddress(i, ctx.network)\n const script = out.script ? hex.encode(out.script) : undefined\n const mine = script !== undefined && script === ownScript\n let role: BtcTxOutputDescription['role']\n if (ctx.intended === undefined) role = mine ? 'change' : 'recipient'\n else if (!recipientSeen && script !== undefined && script === intendedScript && value === ctx.intended.value) { role = 'recipient'; recipientSeen = true }\n else role = mine ? 'change' : 'unknown'\n if (out.script && value < dustLimit(scriptKind(out.script))) warnings.add('dust-output')\n outputs.push({ address, value, role })\n }\n const inputSum = inputs.reduce((s, i) => s + i.value, 0n)\n const outputSum = outputs.reduce((s, o) => s + o.value, 0n)\n const fee = inputSum - outputSum\n const amount = outputs.filter((o) => o.role !== 'change').reduce((s, o) => s + o.value, 0n)\n const vsize = vsizeOf(tx)\n const feeRate = vsize > 0 ? Math.round((bigintToNumber(fee) / vsize) * 100) / 100 : 0\n if (feeRate > (ctx.maxFeeRate ?? DEFAULT_MAX_FEE_RATE)) warnings.add('high-fee-rate')\n if (amount > 0n && fee * 10n > amount) warnings.add('fee-over-10pct-of-amount')\n if (!outputs.some((o) => o.role === 'change')) warnings.add('no-change')\n let rbf = false\n for (let i = 0; i < tx.inputsLength; i++) if ((tx.getInput(i).sequence ?? 0xffffffff) < FINAL_SEQUENCE) rbf = true\n const desc: BtcTxDescription = { kind: 'btc-transfer', inputs, outputs, amount, fee, feeRate, vsize, rbf, lockTime: tx.lockTime, warnings: [...warnings] }\n if (tx.isFinal) desc.txid = tx.id\n return desc\n}\n\n/**\n * Hard checks run before signing and before broadcasting. Throws UnsafeTransactionError;\n * never mutates. With `intended`, exactly one output must be the requested\n * recipient/amount and every other output must be our change.\n */\nexport function assertSafe(desc: BtcTxDescription, ctx: DescribeContext): void {\n const maxFeeRate = ctx.maxFeeRate ?? DEFAULT_MAX_FEE_RATE\n if (desc.feeRate > maxFeeRate) {\n throw new UnsafeTransactionError('fee-rate-too-high', `Fee rate ${desc.feeRate} sat/vB exceeds the ${maxFeeRate} sat/vB ceiling (maxFeeRate).`)\n }\n if (desc.fee < 0n) throw new UnsafeTransactionError('unexpected-output', 'Outputs exceed inputs.')\n for (const o of desc.outputs) {\n if (o.role === 'change' && o.address !== ctx.ownAddress) throw new UnsafeTransactionError('change-not-ours', `Change output pays ${o.address ?? '<no address>'}, not ${ctx.ownAddress}.`)\n }\n if (ctx.intended) {\n const recipients = desc.outputs.filter((o) => o.role === 'recipient')\n if (recipients.length !== 1) throw new UnsafeTransactionError('recipient-mismatch', `Expected one output of ${ctx.intended.value} sat to ${ctx.intended.to}, found ${recipients.length}.`)\n const unknown = desc.outputs.filter((o) => o.role === 'unknown')\n if (unknown.length) throw new UnsafeTransactionError('unexpected-output', `Transaction carries ${unknown.length} output(s) that are neither the recipient nor our change.`)\n }\n}\n","import { Address, OutScript, p2tr, p2wpkh } from '@scure/btc-signer'\nimport type { BTC_NETWORK } from '@scure/btc-signer/utils.js'\nimport type { BtcAddressType } from './types.js'\n\n/** Output-script families btc-signer recognises (`OutScript.decode(...).type`). */\nexport type ScriptKind = 'pk' | 'pkh' | 'sh' | 'wsh' | 'wpkh' | 'ms' | 'tr' | 'tr_ns' | 'tr_ms' | 'p2a' | 'unknown'\n\n/** An address decoded to its output script. */\nexport interface DecodedAddress {\n script: Uint8Array\n kind: ScriptKind\n}\n\n/** Decode and validate an address for `network`; throws on a malformed address or a foreign network. */\nexport function decodeAddress(address: string, network: BTC_NETWORK): DecodedAddress {\n let decoded\n try { decoded = Address(network).decode(address) } catch (e) {\n throw new Error(`Invalid bitcoin address for this network: ${address}`, { cause: e })\n }\n return { script: OutScript.encode(decoded), kind: decoded.type as ScriptKind }\n}\n\n/** Address for an output script, or undefined when the script has no address form. */\nexport function addressFromScript(script: Uint8Array, network: BTC_NETWORK): string | undefined {\n try { return Address(network).encode(OutScript.decode(script)) } catch { return undefined }\n}\n\n/** Type of an output script; `unknown` when it cannot be decoded. */\nexport function scriptKind(script: Uint8Array): ScriptKind {\n try { return OutScript.decode(script).type as ScriptKind } catch { return 'unknown' }\n}\n\n/** Spend descriptor for OUR key: p2wpkh from the compressed key, p2tr from its x-only form (BIP-86 key-path, no script tree). */\nexport function spendInfo(publicKey: Uint8Array, network: BTC_NETWORK, type: BtcAddressType) {\n if (type === 'p2tr') return p2tr(publicKey.length === 33 ? publicKey.subarray(1) : publicKey, undefined, network)\n return p2wpkh(publicKey, network)\n}\n\n/** Address of a compressed public key: p2wpkh (`bc1q…`) or p2tr key-path (`bc1p…`). */\nexport function addressFromPublicKey(publicKey: Uint8Array, network: BTC_NETWORK, type: BtcAddressType = 'p2wpkh'): string {\n const { address } = spendInfo(publicKey, network, type)\n if (!address) throw new Error(`Could not derive a ${type} address`)\n return address\n}\n\n// ── Size + dust constants (Bitcoin Core policy) ─────────────────────────────\n\n/** Weight units one of OUR inputs adds once signed (prevout 41 B × 4 + witness). p2wpkh assumes a 72-byte DER sig. */\nexport const INPUT_WEIGHT: Record<BtcAddressType, number> = { p2wpkh: 272, p2tr: 230 }\n\n/** Virtual bytes an output of this script kind occupies (8 B value + 1 B len + script). */\nexport function outputVBytes(kind: ScriptKind, script?: Uint8Array): number {\n switch (kind) {\n case 'wpkh': return 31\n case 'tr': case 'wsh': return 43\n case 'pkh': return 34\n case 'sh': return 32\n default: return 9 + (script?.length ?? 34)\n }\n}\n\n/** Bitcoin Core dust threshold (3 sat/vB discard rate) per output type, in sats. */\nexport function dustLimit(kind: ScriptKind): bigint {\n switch (kind) {\n case 'wpkh': return 294n\n case 'tr': case 'wsh': return 330n\n case 'pkh': return 546n\n case 'sh': return 540n\n default: return 546n\n }\n}\n\n/** Smallest p2wpkh output relay policy accepts, in satoshis. */\nexport const DUST_LIMIT_P2WPKH = dustLimit('wpkh')\n/** Smallest p2tr output relay policy accepts, in satoshis. */\nexport const DUST_LIMIT_P2TR = dustLimit('tr')\n\nexport const kindOfType = (type: BtcAddressType): ScriptKind => (type === 'p2tr' ? 'tr' : 'wpkh')\n","import { NETWORK, TEST_NETWORK } from '@scure/btc-signer'\nimport type { BTC_NETWORK } from '@scure/btc-signer/utils.js'\nimport type { BtcAddressType, BtcNetwork } from './types.js'\n\n/** btc-signer ships mainnet + testnet; regtest only differs in the bech32 HRP. */\nexport const REGTEST_NETWORK: BTC_NETWORK = Object.freeze({ bech32: 'bcrt', pubKeyHash: 0x6f, scriptHash: 0xc4, wif: 0xef })\n\n/** `@scure/btc-signer` parameters of a network. */\nexport function networkParams(network: BtcNetwork): BTC_NETWORK {\n switch (network) {\n case 'bitcoin': return NETWORK\n case 'testnet': return TEST_NETWORK\n case 'regtest': return REGTEST_NETWORK\n default: throw new Error(`Unknown bitcoin network: ${String(network)}`)\n }\n}\n\n/** SLIP-44 coin type: 0 for mainnet, 1 for every test network. */\nexport const coinType = (network: BtcNetwork): 0 | 1 => (network === 'bitcoin' ? 0 : 1)\n\n/** BIP purpose for the address type: 84 (p2wpkh) or 86 (p2tr). */\nexport const purposeFor = (type: BtcAddressType): 84 | 86 => (type === 'p2tr' ? 86 : 84)\n","import { InsufficientFundsError, NetworkError, type IWalletAccountReadOnly } from '@anywalletkit/core'\nimport type { BTC_NETWORK } from '@scure/btc-signer/utils.js'\nimport { INPUT_WEIGHT, decodeAddress, dustLimit, kindOfType, outputVBytes, spendInfo, type ScriptKind } from './address.js'\nimport { createClient } from './client.js'\nimport { MAX_UTXO_INPUTS, selectAll, selectCoins, type CoinSelection } from './coinselect.js'\nimport { DEFAULT_MAX_FEE_RATE } from './describe.js'\nimport { UnsupportedAddressTypeError } from './errors.js'\nimport { recoverMessagePublicKey } from './message.js'\nimport { networkParams } from './network.js'\nimport { CAIP2_GENESIS, type BtcAddressType, type BtcClient, type BtcConfig, type BtcMaxSpendableResult, type BtcNetwork, type BtcReceipt, type BtcSpend, type BtcTransferOptions } from './types.js'\n\nexport { MAX_UTXO_INPUTS }\n\n/** A coin selection for one spend, with the recipient's script. */\nexport interface SpendPlan extends CoinSelection {\n /** Sats the recipient gets (the requested value — never reduced). */\n amount: bigint\n recipientScript: Uint8Array\n recipientKind: ScriptKind\n}\n\nconst toBig = (v: bigint | number | string): bigint => (typeof v === 'bigint' ? v : BigInt(Math.round(Number(v))))\nexport const toHex = (u8: Uint8Array) => Array.from(u8, (b) => b.toString(16).padStart(2, '0')).join('')\n\n/** Watch-only Bitcoin account: balances, quotes, receipts, BIP-137 verification. No key. */\nexport class WalletAccountReadOnlyBtc implements IWalletAccountReadOnly {\n /** The address. */\n readonly address: string\n readonly chain: string\n /** Output script of `address`. */\n readonly scriptPubKey: Uint8Array\n /** Script type of the address. */\n readonly scriptKind: ScriptKind\n /** p2wpkh / p2tr when the address is one we know how to spend from; undefined for other script types. */\n readonly addressType: BtcAddressType | undefined\n /** Smallest output this address type may create, in satoshis. */\n readonly dustLimit: bigint\n protected readonly _config: BtcConfig\n protected readonly _client: BtcClient | undefined\n protected readonly _network: BTC_NETWORK\n protected readonly _networkName: BtcNetwork\n\n constructor(address: string, config: BtcConfig = {}) {\n this._config = config\n this._networkName = config.network ?? 'bitcoin'\n this._network = networkParams(this._networkName)\n const decoded = decodeAddress(address, this._network)\n this.address = address\n this.scriptPubKey = decoded.script\n this.scriptKind = decoded.kind\n this.addressType = decoded.kind === 'wpkh' ? 'p2wpkh' : decoded.kind === 'tr' ? 'p2tr' : undefined\n this.dustLimit = dustLimit(decoded.kind)\n this.chain = CAIP2_GENESIS[this._networkName]\n this._client = createClient(config)\n }\n\n protected requireClient(what: string): BtcClient {\n if (!this._client) throw new NetworkError(`The wallet must be connected to a client to ${what}.`)\n return this._client\n }\n\n /** Fee-rate ceiling in sat/vB: `BtcConfig.maxFeeRate` or {@link DEFAULT_MAX_FEE_RATE}. */\n get maxFeeRate(): number {\n return this._config.maxFeeRate ?? DEFAULT_MAX_FEE_RATE\n }\n\n /** The address. */\n async getAddress(): Promise<string> { return this.address }\n\n /** Confirmed minus pending outgoing (Bitcoin Core wallet semantics). */\n async getBalance(): Promise<bigint> {\n const { confirmed, unconfirmed, unconfirmedOutgoing } = await this.requireClient('read balances').getBalance(this.address)\n return unconfirmedOutgoing !== undefined ? confirmed - unconfirmedOutgoing : confirmed + unconfirmed\n }\n\n /** Always throws: Bitcoin has no tokens. */\n async getTokenBalance(_token: string): Promise<bigint> {\n throw new Error(\"The 'getTokenBalance' method is not supported on the bitcoin blockchain.\")\n }\n\n /** Weight one of OUR inputs adds; throws for address types we cannot spend from. */\n protected inputWeight(): number {\n if (!this.addressType) throw new UnsupportedAddressTypeError(`Cannot build spends from a ${this.scriptKind} address; only p2wpkh and p2tr accounts spend.`)\n return INPUT_WEIGHT[this.addressType]\n }\n\n protected async resolveFeeRate(spend: { feeRate?: bigint | number; confirmationTarget?: number }): Promise<bigint> {\n if (spend.feeRate !== undefined) {\n const r = toBig(spend.feeRate)\n return r < 1n ? 1n : r\n }\n const est = await this.requireClient('estimate fees').estimateFee(spend.confirmationTarget ?? 1)\n return BigInt(Math.max(Math.ceil(est), 1))\n }\n\n /** Coin selection for a spend (see coinselect.ts). Validates the recipient and the dust floor first. */\n protected async planSpend(spend: BtcSpend): Promise<SpendPlan> {\n const amount = toBig(spend.value)\n const recipient = decodeAddress(spend.to, this._network)\n const floor = dustLimit(recipient.kind)\n if (amount < floor) throw new Error(`The amount must be at least the dust limit of the recipient's address type (${floor} sat).`)\n const inputWeight = this.inputWeight()\n const feeRate = await this.resolveFeeRate(spend)\n const utxos = await this.requireClient('plan a spend').listUnspent(this.address)\n if (utxos.length === 0) throw new InsufficientFundsError(amount, 0n, 'BTC')\n const own = kindOfType(this.addressType!)\n const selection = selectCoins({\n utxos,\n targets: [{ value: amount, vbytes: outputVBytes(recipient.kind, recipient.script) }],\n feeRate,\n inputWeight,\n changeVBytes: outputVBytes(own),\n changeDust: dustLimit(own),\n maxInputs: this._config.maxInputs ?? MAX_UTXO_INPUTS,\n })\n return { ...selection, amount, recipientScript: recipient.script, recipientKind: recipient.kind }\n }\n\n /** Fee of a spend in satoshis, from a coin selection at the current fee rate. */\n async quoteSendTransaction(tx: BtcSpend): Promise<{ fee: bigint }> {\n const { fee } = await this.planSpend(tx)\n return { fee }\n }\n\n /**\n * Fee of a transfer in satoshis.\n *\n * @throws Error when `token` is set.\n */\n async quoteTransfer(o: BtcTransferOptions): Promise<{ fee: bigint }> {\n if (o.token) throw new Error('Tokens are not supported on the bitcoin blockchain.')\n return this.quoteSendTransaction({ to: o.recipient, value: o.amount })\n }\n\n /** Everything spendable in ONE transaction to a single output of our own address type, no change. */\n async getMaxSpendable(opts: { feeRate?: bigint | number; confirmationTarget?: number; to?: string } = {}): Promise<BtcMaxSpendableResult> {\n const inputWeight = this.inputWeight()\n const feeRate = await this.resolveFeeRate(opts)\n const utxos = await this.requireClient('plan a spend').listUnspent(this.address)\n const outKind = opts.to ? decodeAddress(opts.to, this._network).kind : kindOfType(this.addressType!)\n const sweep = selectAll({ utxos, feeRate, inputWeight, outputVBytes: outputVBytes(outKind), maxInputs: this._config.maxInputs ?? MAX_UTXO_INPUTS })\n const amount = sweep.amount >= dustLimit(outKind) ? sweep.amount : 0n\n return { amount, fee: amount > 0n ? sweep.fee : 0n, changeValue: 0n, inputs: amount > 0n ? sweep.utxos.length : 0, feeRate }\n }\n\n /** Undefined until the transaction is mined. */\n async getTransactionReceipt(hash: string): Promise<BtcReceipt | undefined> {\n if (!/^[0-9a-fA-F]{64}$/.test(hash)) throw new Error(\"The 'getTransactionReceipt(hash)' method requires a valid transaction hash.\")\n const client = this.requireClient('fetch transaction receipts')\n const info = client.getTransactionInfo ? await client.getTransactionInfo(hash) : undefined\n if (!info || !info.blockHeight || info.blockHeight <= 0) return undefined\n return {\n hash, status: 1, blockNumber: BigInt(info.blockHeight), confirmations: info.confirmations,\n ...(info.fees !== undefined ? { fee: BigInt(info.fees) } : {}), ...(info.hex !== undefined ? { hex: info.hex } : {}),\n }\n }\n\n /** BIP-137: recover the key and compare its p2wpkh address with ours. Taproot addresses have no BIP-137 form. */\n async verify(message: string | Uint8Array, signature: string): Promise<boolean> {\n if (this.addressType === 'p2tr') throw new UnsupportedAddressTypeError('BIP-137 message signatures do not exist for taproot addresses (BIP-322 is not implemented).')\n const rec = recoverMessagePublicKey(message, signature)\n if (!rec || rec.publicKey.length !== 33) return false\n try { return spendInfo(rec.publicKey, this._network, 'p2wpkh').address === this.address } catch { return false }\n }\n\n /** Chain tip for anti-fee-sniping; undefined when disabled or the transport cannot tell. */\n protected async lockTimeHeight(): Promise<number> {\n if (this._config.antiFeeSniping === false || !this._client?.getBlockHeight) return 0\n try { return await this._client.getBlockHeight() } catch { return 0 }\n }\n}\n","import { InsufficientFundsError, LocalSigner, SignerError, feeLimit, requireCurve, type IWalletAccount, type IWalletAccountReadOnly, type Signer, type TransferResult, type WriteOptions } from '@anywalletkit/core'\nimport { SigHash, Transaction, p2pkh } from '@scure/btc-signer'\nimport type { BTC_NETWORK } from '@scure/btc-signer/utils.js'\nimport { schnorr, secp256k1 } from '@noble/curves/secp256k1.js'\nimport { hex } from '@scure/base'\nimport { addressFromPublicKey, spendInfo } from './address.js'\nimport { FINAL_SEQUENCE, RBF_SEQUENCE, assertSafe, describeTransaction, parseRawTransaction, type DescribeContext } from './describe.js'\nimport { BroadcastUnknownError, UnsafeTransactionError, UnsupportedAddressTypeError } from './errors.js'\nimport { isAlreadyKnown, isAnsweredRefusal } from './http.js'\nimport { signMessageWith } from './message.js'\nimport { networkParams } from './network.js'\nimport { WalletAccountReadOnlyBtc, type SpendPlan } from './read-only-account.js'\nimport type { BtcClient, BtcAddressType, BtcConfig, BtcNetwork, BtcSpend, BtcTransaction, BtcTransferOptions, BtcTxDescription, Utxo } from './types.js'\n\nexport { addressFromPublicKey }\n\n/** Address for a compressed public key; `network` may be a name or btc-signer params. */\nexport function addressFor(publicKey: Uint8Array, network: BtcNetwork | BTC_NETWORK = 'bitcoin', type: BtcAddressType = 'p2wpkh'): string {\n return addressFromPublicKey(publicKey, typeof network === 'string' ? networkParams(network) : network, type)\n}\n\ninterface Built {\n tx: Transaction\n fee: bigint\n plan: SpendPlan\n desc: BtcTxDescription\n}\n\n/**\n * Signing Bitcoin account — BIP-84 p2wpkh or BIP-86 p2tr (key-path). The key never\n * enters this package: every signature is one `signer.sign(...)` call over a\n * btc-signer-computed sighash — a {@link LocalSigner} for seed wallets, anything\n * else (hardware, MPC, backend) through `externalSigner()`:\n *\n * ```text\n * p2wpkh input → `ecdsa` over the BIP-143 sighash (SIGHASH_ALL), DER-encoded here\n * p2tr input → `schnorr` + `tweak` over the BIP-341 sighash (DEFAULT), tweak = TapTweak(xonly)\n * BIP-137 msg → `ecdsa-recoverable` over the magic hash\n * ```\n *\n * Every spend is resolved to a full description (\"what you sign\") and run through\n * the hard safety checks (fee-rate ceiling, recipient/amount exactness, change\n * ownership) before signing AND before broadcast — also for caller-supplied raw hex.\n */\nexport class WalletAccountBtc extends WalletAccountReadOnlyBtc implements IWalletAccount {\n /** UTXOs, fee rate and tip height come from the network before signing. */\n readonly needsNetwork = true\n /** Derivation path, or `external` for an external signer. */\n readonly path: string\n /** Compressed secp256k1 public key. */\n readonly publicKey: Uint8Array\n override readonly addressType: BtcAddressType\n /** The signer that holds the key. */\n readonly signer: Signer\n private _disposed = false\n private _readOnly: WalletAccountReadOnlyBtc | undefined\n\n /** `publicKey` is the signer's compressed secp256k1 key (33 bytes); it is needed synchronously for the address. */\n constructor(signer: Signer, publicKey: Uint8Array, path: string, config: BtcConfig = {}) {\n const type = config.addressType ?? 'p2wpkh'\n super(addressFromPublicKey(publicKey, networkParams(config.network ?? 'bitcoin'), type), config)\n this.addressType = type\n this.signer = requireCurve(signer, 'secp256k1')\n // Fail at construction, not mid-spend: taproot key-path needs schnorr, p2wpkh needs plain ecdsa.\n const needed = type === 'p2tr' ? 'schnorr' : 'ecdsa'\n if (!this.signer.schemes.includes(needed)) throw new SignerError(`A ${type} account needs a signer with the '${needed}' scheme (has: ${this.signer.schemes.join(', ')}).`)\n this.publicKey = publicKey\n this.path = path\n }\n\n /** Back-compat: wrap a raw derived key in a {@link LocalSigner} (the account takes ownership; it cannot derive). */\n static fromPrivateKey(privateKey: Uint8Array, publicKey: Uint8Array, path: string, config: BtcConfig = {}): WalletAccountBtc {\n return new WalletAccountBtc(LocalSigner.fromPrivateKey('secp256k1', privateKey, publicKey, path), publicKey, path, config)\n }\n\n /** Account index for the standard m/{84|86}'/{0|1}'/0'/0/i path. */\n get index(): number | undefined {\n const m = /^m\\/8[46]'\\/[01]'\\/0'\\/0\\/(\\d+)$/.exec(this.path)\n return m ? Number(m[1]) : undefined\n }\n\n private live(): void {\n if (this._disposed) throw new SignerError('This account has been disposed.')\n }\n\n /** BIP-137 p2wpkh signature, base64 (Electrum / Bitcoin Core encoding). Not available for taproot accounts. */\n async sign(message: string | Uint8Array): Promise<string> {\n this.live()\n if (this.addressType === 'p2tr') throw new UnsupportedAddressTypeError('BIP-137 message signatures do not exist for taproot accounts (BIP-322 is not implemented).')\n return signMessageWith(message, this.signer, 'p2wpkh')\n }\n\n /** The x-only internal key and its BIP-86 tweak (no script tree) for taproot key-path spends. */\n private taprootKeys(): { xonly: Uint8Array; tweak: Uint8Array } {\n const xonly = this.publicKey.length === 33 ? this.publicKey.subarray(1) : this.publicKey\n return { xonly, tweak: schnorr.utils.taggedHash('TapTweak', xonly) }\n }\n\n /**\n * Sign every input through the signer and attach the witness-ready signature:\n * p2wpkh → `partialSig` (DER + SIGHASH_ALL), p2tr → `tapKeySig` (64 bytes, DEFAULT).\n * btc-signer only computes the sighash and assembles the witness; it never sees a key.\n */\n private async signInputs(tx: Transaction, values: bigint[]): Promise<void> {\n if (this.addressType === 'p2tr') {\n const { tweak } = this.taprootKeys()\n const scripts = Array.from({ length: tx.inputsLength }, () => this.scriptPubKey)\n for (let i = 0; i < tx.inputsLength; i++) {\n const sighash = tx.preimageWitnessV1(i, scripts, SigHash.DEFAULT, values)\n const sig = await this.signer.sign(sighash, { scheme: 'schnorr', context: 'btc-taproot-keypath', tweak })\n tx.updateInput(i, { tapKeySig: sig }, true)\n }\n return\n }\n const scriptCode = p2pkh(this.publicKey).script\n for (let i = 0; i < tx.inputsLength; i++) {\n const sighash = tx.preimageWitnessV0(i, scriptCode, SigHash.ALL, values[i]!)\n const rs = await this.signer.sign(sighash, { scheme: 'ecdsa', context: 'btc-sighash' })\n const der = secp256k1.Signature.fromBytes(rs, 'compact').toBytes('der')\n const sig = new Uint8Array(der.length + 1)\n sig.set(der, 0)\n sig[der.length] = SigHash.ALL\n tx.updateInput(i, { partialSig: [[this.publicKey, sig]] }, true)\n }\n }\n\n private ctx(intended?: { to: string; value: bigint }): DescribeContext {\n return { network: this._network, ownAddress: this.address, intended, maxFeeRate: this.maxFeeRate }\n }\n\n private async signPlan(plan: SpendPlan, to: string, recipientValue: bigint, change: bigint, lockTime: number, rbf: boolean): Promise<Transaction> {\n const spend = spendInfo(this.publicKey, this._network, this.addressType)\n const tx = new Transaction({ lockTime })\n const sequence = rbf ? RBF_SEQUENCE : FINAL_SEQUENCE\n for (const u of plan.utxos) {\n tx.addInput({ ...spend, txid: u.txid, index: u.vout, sequence, witnessUtxo: { script: this.scriptPubKey, amount: u.value } })\n }\n tx.addOutputAddress(to, recipientValue, this._network)\n if (change > 0n) tx.addOutputAddress(this.address, change, this._network)\n await this.signInputs(tx, plan.utxos.map((u) => u.value))\n tx.finalize()\n return tx\n }\n\n /**\n * Plan → sign → measure. The plan's fee assumes 72-byte DER signatures; if the\n * signed vsize somehow needs more, the difference comes out of change (never the\n * recipient) and the tx is re-signed once.\n */\n protected async signSpend(spend: BtcSpend): Promise<Built> {\n this.live()\n const plan = await this.planSpend(spend)\n await this.verifyPrevouts(plan.utxos)\n const lockTime = await this.lockTimeHeight()\n const rbf = spend.rbf ?? this._config.rbf ?? true\n let change = plan.change\n let fee = plan.fee\n let tx = await this.signPlan(plan, spend.to, plan.amount, change, lockTime, rbf)\n const required = BigInt(tx.vsize) * plan.feeRate\n if (required > fee) {\n const delta = required - fee\n if (change === 0n) {\n const have = plan.utxos.reduce((s, u) => s + u.value, 0n)\n throw new InsufficientFundsError(plan.amount + required, have, 'BTC')\n }\n change = change - delta\n if (change < this.dustLimit) { fee = plan.fee + plan.change; change = 0n } else fee = required\n tx = await this.signPlan(plan, spend.to, plan.amount, change, lockTime, rbf)\n if (BigInt(tx.vsize) * plan.feeRate > fee) throw new Error('Fee shortfall after output rebalance.')\n }\n const ctx = this.ctx({ to: spend.to, value: plan.amount })\n const desc = describeTransaction(tx, plan.utxos.map((u) => u.value), ctx)\n assertSafe(desc, ctx)\n return { tx, fee, plan, desc }\n }\n\n private checkMax(fee: bigint, limit: bigint | number | undefined, op: string) {\n if (limit !== undefined && fee > BigInt(limit)) throw new Error(`Exceeded maximum fee cost for ${op} operation.`)\n }\n\n /**\n * BIP-143 (p2wpkh) commits each input's signature to that input's CLAIMED amount\n * only: an indexer that understates a different coin in each of two signing\n * sessions can combine their signatures into one valid tx whose real fee the\n * wallet never showed (scan 2026-10-23 F2). So every p2wpkh coin is read from\n * its full previous transaction, which must hash to the claimed txid, and its\n * amount and script must match before anything is signed. Taproot (BIP-341)\n * commits to every input amount and skips the extra requests.\n */\n private async verifyPrevouts(utxos: Utxo[]): Promise<void> {\n if (this.addressType === 'p2tr') return\n const client = this.requireClient('verify the coins it spends')\n const ours = hex.encode(this.scriptPubKey)\n const cache = new Map<string, Transaction>()\n for (const u of utxos) {\n let prev = cache.get(u.txid)\n if (!prev) {\n prev = parseRawTransaction(await client.getTransaction(u.txid))\n if (prev.id !== u.txid) throw new UnsafeTransactionError('prevout-mismatch', `The indexer's transaction for ${u.txid} hashes to ${prev.id}.`)\n cache.set(u.txid, prev)\n }\n const out = u.vout < prev.outputsLength ? prev.getOutput(u.vout) : undefined\n if (out?.amount === undefined || out.amount !== u.value) {\n throw new UnsafeTransactionError('prevout-mismatch', `Coin ${u.txid}:${u.vout} is worth ${out?.amount ?? 'nothing'} sat on chain, not the ${u.value} the indexer reported.`)\n }\n if (!out.script || hex.encode(out.script) !== ours) throw new UnsafeTransactionError('prevout-mismatch', `Coin ${u.txid}:${u.vout} does not pay this account.`)\n }\n }\n\n /** Prevout values of a raw tx, fetched through the client (the wire format carries none). */\n private async inputValues(tx: Transaction): Promise<bigint[]> {\n const client = this.requireClient('inspect a raw transaction')\n const cache = new Map<string, Transaction>()\n const values: bigint[] = []\n for (let i = 0; i < tx.inputsLength; i++) {\n const inp = tx.getInput(i)\n if (!inp.txid || inp.index === undefined) throw new Error('Raw transaction input without a prevout.')\n const id = hex.encode(inp.txid)\n let prev = cache.get(id)\n if (!prev) {\n prev = parseRawTransaction(await client.getTransaction(id))\n // An unauthenticated prevout would let the indexer forge the fee this check computes (scan F2).\n if (prev.id !== id) throw new UnsafeTransactionError('prevout-mismatch', `The indexer's transaction for ${id} hashes to ${prev.id}.`)\n cache.set(id, prev)\n }\n const out = prev.getOutput(inp.index)\n if (out.amount === undefined) throw new Error(`Prevout ${id}:${inp.index} not found.`)\n values.push(out.amount)\n }\n return values\n }\n\n /** Describe a raw signed tx (needs the network for prevout values) and run the safety checks. */\n private async describeRaw(rawHex: string): Promise<{ tx: Transaction; desc: BtcTxDescription }> {\n const tx = parseRawTransaction(rawHex)\n const ctx = this.ctx()\n const desc = describeTransaction(tx, await this.inputValues(tx), ctx)\n assertSafe(desc, ctx)\n return { tx, desc }\n }\n\n /** \"What you sign\": the fully resolved spend (signed, NOT broadcast) or a caller's raw hex. */\n async describeTransaction(tx: BtcTransaction): Promise<BtcTxDescription> {\n if (typeof tx === 'string') return (await this.describeRaw(tx)).desc\n return (await this.signSpend(tx)).desc\n }\n\n /** Sign without broadcasting. Returns the raw transaction hex. Raw hex input gets the checks `sendTransaction` runs (prevouts through the client) and is returned unchanged, never re-signed. */\n async signTransaction(tx: BtcTransaction, options: WriteOptions = {}): Promise<string> {\n this.live()\n if (typeof tx === 'string') {\n const { desc } = await this.describeRaw(tx)\n this.checkMax(desc.fee, feeLimit(this._config.transactionMaxFee, options), 'transaction')\n return tx\n }\n const { tx: built, fee } = await this.signSpend(tx)\n this.checkMax(fee, feeLimit(this._config.transactionMaxFee, options), 'transaction')\n return built.hex\n }\n\n override async quoteSendTransaction(tx: BtcTransaction): Promise<{ fee: bigint }> {\n if (typeof tx === 'string') return { fee: (await this.describeRaw(tx)).desc.fee }\n return super.quoteSendTransaction(tx)\n }\n\n async sendTransaction(tx: BtcTransaction, options: WriteOptions = {}): Promise<TransferResult> {\n this.live()\n const client = this.requireClient('send transactions')\n let rawHex: string, hash: string, fee: bigint\n if (typeof tx === 'string') {\n const { tx: parsed, desc } = await this.describeRaw(tx)\n rawHex = tx; hash = parsed.id; fee = desc.fee\n } else {\n const built = await this.signSpend(tx)\n rawHex = built.tx.hex; hash = built.tx.id; fee = built.fee\n }\n this.checkMax(fee, feeLimit(this._config.transactionMaxFee, options), 'transaction')\n return { hash: await this.broadcast(client, rawHex, hash), fee }\n }\n\n /** Native BTC only (`token` is rejected). Subject to `transferMaxFee`. */\n async transfer(o: BtcTransferOptions, writeOptions: WriteOptions = {}): Promise<TransferResult> {\n if (o.token) throw new Error('Tokens are not supported on the bitcoin blockchain.')\n this.live()\n const client = this.requireClient('transfer')\n const built = await this.signSpend({ to: o.recipient, value: o.amount })\n this.checkMax(built.fee, feeLimit(this._config.transferMaxFee, writeOptions), 'transfer')\n return { hash: await this.broadcast(client, built.tx.hex, built.tx.id), fee: built.fee }\n }\n\n /**\n * Send once through the client. Only a node's refusal means nothing went out; \"already in the\n * mempool / block chain\" means an earlier attempt delivered it; anything else may have landed and\n * is a {@link BroadcastUnknownError} with the txid computed before sending (round 3, M12).\n */\n private async broadcast(client: BtcClient, rawHex: string, txid: string): Promise<string> {\n try {\n return (await client.broadcast(rawHex)) || txid\n } catch (e) {\n if (isAlreadyKnown(e)) return txid\n if (isAnsweredRefusal(e)) throw e\n throw new BroadcastUnknownError(txid, e)\n }\n }\n\n /** The same address as a {@link WalletAccountReadOnlyBtc}. */\n toReadOnlyAccount(): IWalletAccountReadOnly {\n this._readOnly ??= new WalletAccountReadOnlyBtc(this.address, this._config)\n return this._readOnly\n }\n\n dispose(): void {\n this._disposed = true\n this.signer.dispose()\n }\n}\n","import { LocalSigner, SignerError, WalletManager, isSeedSigner, type FeeRates, type Signer } from '@anywalletkit/core'\nimport { WalletAccountBtc } from './account.js'\nimport { coinType, purposeFor } from './network.js'\nimport { WalletAccountReadOnlyBtc } from './read-only-account.js'\nimport type { BtcConfig } from './types.js'\n\n/**\n * One seed → Bitcoin accounts.\n * p2wpkh (default): BIP-84, m/84'/0'/0'/0/i on mainnet, m/84'/1'/0'/0/i on test networks — bc1q… / tb1q…\n * p2tr: BIP-86, m/86'/0'/0'/0/i (key-path taproot) — bc1p… / tb1p…\n * Paths may be relative to the purpose/coin prefix (\"0'/0/i\") or given in full.\n *\n * Built with a secp256k1 `Signer` instead of a seed, the manager wraps it:\n * - a derivable `SeedSigner` sitting at the account branch (`m/84'/0'/0'/0` or\n * `m/86'/0'/0'/0`, per `addressType`/`network`) yields `getAccount(i)` children;\n * - a `SeedSigner` at a leaf, or any external signer, is `getAccount(0)` (path = the\n * signer's path, or 'external') with the configured address type; other\n * indexes/paths throw.\n */\nexport class WalletManagerBtc extends WalletManager<WalletAccountBtc, BtcConfig> {\n constructor(seedOrSigner: string | Uint8Array | Signer, config: BtcConfig = {}) {\n super(seedOrSigner, config)\n }\n\n\n /**\n * `m/84'/0'` for p2wpkh or `m/86'/0'` for p2tr on mainnet (coin type 1 on test networks); account\n * `i` is at `basePath/0'/0/i`.\n */\n get basePath(): string {\n return `m/${purposeFor(this._config.addressType ?? 'p2wpkh')}'/${coinType(this._config.network ?? 'bitcoin')}'`\n }\n\n async getAccount(index = 0): Promise<WalletAccountBtc> {\n return this.getAccountByPath(`${this.basePath}/0'/0/${index}`)\n }\n\n async getAccountByPath(path: string): Promise<WalletAccountBtc> {\n const full = path.startsWith('m/') ? path : `${this.basePath}/${path}`\n const cached = this._accounts.get(full)\n if (cached) return cached\n const external = this.externalSigner()\n if (external) return this.fromSigner(external, full)\n return this.cachedAccount(full, () => {\n const signer = LocalSigner.leafFromSeed(this.seedBytes(), 'secp256k1', full)\n return new WalletAccountBtc(signer, signer.publicKey, full, this._config)\n })\n }\n\n /** Resolve `path` against an injected signer: the signer itself, or a child when it can derive there. */\n private async fromSigner(signer: Signer, path: string): Promise<WalletAccountBtc> {\n this.requireSigner('secp256k1')\n let rel: string | undefined\n let key = 'external'\n if (isSeedSigner(signer)) {\n if (path === signer.path) key = path\n else if (path.startsWith(`${signer.path}/`)) { rel = path.slice(signer.path.length + 1); key = path }\n else throw new SignerError(`The injected signer sits at ${signer.path}; it cannot provide ${path}.`)\n } else if (path !== `${this.basePath}/0'/0/0` && path !== 'external') {\n throw new SignerError(`An external signer has one account; ${path} is not derivable from it.`)\n }\n return this.signerAccount(key, signer, rel, (leaf, publicKey) => new WalletAccountBtc(leaf, publicKey, key, this._config))\n }\n\n /** A read-only account for any address, with this manager's config. */\n getReadOnlyAccount(address: string): WalletAccountReadOnlyBtc {\n return new WalletAccountReadOnlyBtc(address, this._config)\n }\n\n /** sat/vB from the client's estimator: fast = 1 block, normal = 3, slow = 6. */\n async getFeeRates(): Promise<FeeRates> {\n const probe = new WalletAccountReadOnlyBtc(\n (this._config.network ?? 'bitcoin') === 'bitcoin' ? 'bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu' : 'tb1q6rz28mcfaxtmd6v789l9rrlrusdprr9pqcpvkl',\n this._config,\n )\n const client = (probe as unknown as { requireClient(w: string): { estimateFee(b: number): Promise<number> } }).requireClient('get fee rates')\n const [fast, normal, slow] = await Promise.all([1, 3, 6].map((b) => client.estimateFee(b)))\n const big = (n: number) => BigInt(Math.max(Math.ceil(n), 1))\n return { slow: big(slow!), normal: big(normal!), fast: big(fast!) }\n }\n\n}\n"],"mappings":"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","names":["NetworkError","NetworkError","hex","NetworkError","NetworkError","InsufficientFundsError","outputVBytes","InsufficientFundsError","InsufficientFundsError","NetworkError","NetworkError","unconfirmedOutgoing","InsufficientFundsError","InsufficientFundsError","SignerError","Transaction","secp256k1","hex","SignerError","secp256k1","Transaction","InsufficientFundsError","hex","LocalSigner","SignerError","LocalSigner","SignerError"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@anywalletkit/wallet-btc",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Bitcoin wallet for Any Wallet Kit on @scure/btc-signer: BIP-84 p2wpkh and BIP-86 taproot accounts, own coin selection, RBF, Blockbook/Esplora transports.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://docs.anywallet.tech",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
},
|
|
15
15
|
"type": "module",
|
|
16
16
|
"engines": {
|
|
17
|
-
"node": ">=
|
|
17
|
+
"node": ">=22"
|
|
18
18
|
},
|
|
19
19
|
"sideEffects": false,
|
|
20
20
|
"main": "./dist/index.cjs",
|
|
@@ -52,11 +52,11 @@
|
|
|
52
52
|
"@noble/hashes": "^2.4.0",
|
|
53
53
|
"@scure/base": "^2.4.0",
|
|
54
54
|
"@scure/btc-signer": "^2.4.1",
|
|
55
|
-
"@anywalletkit/core": "0.
|
|
55
|
+
"@anywalletkit/core": "0.6.0"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"vitest": "^5.0.3",
|
|
59
|
-
"@anywalletkit/conformance": "0.4.
|
|
59
|
+
"@anywalletkit/conformance": "0.4.3"
|
|
60
60
|
},
|
|
61
61
|
"publishConfig": {
|
|
62
62
|
"access": "public",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/blockbook.ts","../src/http.ts","../src/types.ts","../src/history.ts"],"sourcesContent":["import { NetworkError } from '@anywalletkit/core'\nimport { DEFAULT_TIMEOUT_MS, fetchWithTimeout, isIntString, isRecord } from './http.js'\nimport type { BlockbookTx, BtcClient, Utxo } from './types.js'\n\nconst MEMPOOL_SPACE_URL = 'https://mempool.space'\n\nexport interface BlockbookVin { txid?: string; vout?: number; n?: number; isAddress?: boolean; isOwn?: boolean; addresses?: string[]; value?: string }\nexport interface BlockbookVout { n: number; isAddress?: boolean; isOwn?: boolean; addresses?: string[]; value?: string; spent?: boolean }\ninterface BlockbookAddressTx { txid: string; blockHeight: number; vin?: BlockbookVin[]; vout?: BlockbookVout[] }\n/** A Blockbook transaction with its inputs and outputs (`/api/v2/tx/{txid}`, or one row of `?details=txs`). */\nexport interface BlockbookTxDetails extends BlockbookTx {\n vin?: BlockbookVin[]\n vout?: BlockbookVout[]\n value?: string\n valueIn?: string\n}\n/** One `/api/v2/address/{a}?details=txs` page. */\nexport interface BlockbookAddressPage {\n page?: number\n totalPages?: number\n itemsOnPage?: number\n address?: string\n balance?: string\n unconfirmedBalance?: string\n txs?: number\n transactions?: BlockbookTxDetails[]\n}\n\n/**\n * Pending outgoing value the way Bitcoin Core's wallet counts it: a pending tx\n * is trusted only if every input is ours and confirmed or chained from another\n * trusted tx; only then its change counts back.\n */\nexport function unconfirmedOutgoing(transactions: BlockbookAddressTx[] | undefined, address: string): bigint {\n const pending = (transactions ?? []).filter((tx) => tx.blockHeight === -1)\n const pendingIds = new Set(pending.map((t) => t.txid))\n const byId = new Map(pending.map((t) => [t.txid, t]))\n const trusted = new Map<string, boolean>()\n const owned = (entries: Array<BlockbookVin | BlockbookVout> | undefined) =>\n (entries ?? []).filter((e) => e.isAddress && e.addresses?.includes(address)).reduce((s, e) => s + BigInt(e.value ?? 0), 0n)\n const isTrusted = (tx: BlockbookAddressTx): boolean => {\n if (trusted.has(tx.txid)) return trusted.get(tx.txid)!\n trusted.set(tx.txid, false)\n const vins = tx.vin ?? []\n const ours = vins.filter((v) => v.isAddress && v.addresses?.includes(address))\n const ok = vins.length > 0 && ours.length === vins.length && ours.every((v) => !v.txid || !pendingIds.has(v.txid) || isTrusted(byId.get(v.txid)!))\n trusted.set(tx.txid, ok)\n return ok\n }\n const consumed = new Set<string>()\n for (const tx of pending) for (const v of tx.vin ?? []) if (v.txid && pendingIds.has(v.txid)) consumed.add(`${v.txid}:${v.vout}`)\n return pending.reduce((total, tx) => {\n const spent = owned((tx.vin ?? []).filter((v) => !v.txid || !pendingIds.has(v.txid)))\n const change = isTrusted(tx) ? owned((tx.vout ?? []).filter((o) => !consumed.has(`${tx.txid}:${o.n}`))) : 0n\n return total + (spent - change)\n }, 0n)\n}\n\n/** Blockbook REST transport (Trezor's indexer; QuickNode's Blockbook add-on speaks the same API). */\nexport class BlockbookClient implements BtcClient {\n private readonly base: string\n private readonly fetchFn: typeof fetch\n private readonly timeoutMs: number\n\n constructor(config: { url: string }, fetchFn: typeof fetch = globalThis.fetch, timeoutMs = DEFAULT_TIMEOUT_MS) {\n this.base = config.url.replace(/\\/+$/, '').replace(/\\/api$/, '')\n this.fetchFn = fetchFn\n this.timeoutMs = timeoutMs\n }\n\n async connect(): Promise<void> {}\n async close(): Promise<void> {}\n\n private async get<T>(path: string, check: (v: unknown) => v is T): Promise<T> {\n const url = `${this.base}/api${path}`\n const res = await fetchWithTimeout(this.fetchFn, url, undefined, this.timeoutMs, this.base)\n if (!res.ok) throw new NetworkError(`Blockbook request failed: ${res.status} ${res.statusText} (${url})`, { provider: this.base })\n let body: unknown\n try { body = await res.json() } catch (e) { throw new NetworkError(`Blockbook returned non-JSON for ${url}`, { provider: this.base, cause: e }) }\n if (!check(body)) throw new NetworkError(`Blockbook returned an unexpected shape for ${url}`, { provider: this.base })\n return body\n }\n\n async getBalance(address: string) {\n const data = await this.get(`/v2/address/${address}?details=txs`, (v): v is { balance: string; unconfirmedBalance: string; transactions?: BlockbookAddressTx[] } =>\n isRecord(v) && isIntString(v.balance) && isIntString(v.unconfirmedBalance) && (v.transactions === undefined || Array.isArray(v.transactions)))\n return { confirmed: BigInt(data.balance), unconfirmed: BigInt(data.unconfirmedBalance), unconfirmedOutgoing: unconfirmedOutgoing(data.transactions, address) }\n }\n\n async listUnspent(address: string): Promise<Utxo[]> {\n const data = await this.get(`/v2/utxo/${address}`, (v): v is Array<{ txid: string; vout: number; value: string; height?: number }> =>\n Array.isArray(v) && v.every((u) => isRecord(u) && typeof u.txid === 'string' && typeof u.vout === 'number' && isIntString(u.value)))\n return data.map((u) => ({ txid: u.txid, vout: u.vout, value: BigInt(u.value), height: u.height ?? -1 }))\n }\n\n async getHistory(address: string) {\n const items: Array<{ txid: string; height: number }> = []\n for (let page = 1; ; page++) {\n const data = await this.get(`/v2/address/${address}?details=txslight&pageSize=1000&page=${page}`, (v): v is { transactions?: Array<{ txid: string; blockHeight: number }>; totalPages?: number } =>\n isRecord(v) && (v.transactions === undefined || Array.isArray(v.transactions)))\n for (const tx of data.transactions ?? []) items.push({ txid: tx.txid, height: tx.blockHeight })\n if (page >= (data.totalPages ?? 1)) break\n }\n return items\n }\n\n /** One page of the address's transactions, newest first, with inputs / outputs (what the activity history reads). */\n async getAddressPage(address: string, page = 1, pageSize = 25): Promise<BlockbookAddressPage> {\n const data = await this.get(`/v2/address/${address}?details=txs&page=${page}&pageSize=${pageSize}`, (v): v is BlockbookAddressPage =>\n isRecord(v) && (v.transactions === undefined || (Array.isArray(v.transactions) && v.transactions.every(BlockbookClient.isTx))))\n const out: BlockbookAddressPage = { ...data }\n for (const tx of out.transactions ?? []) delete (tx as { hex?: string }).hex\n return out\n }\n\n /** A transaction with its inputs / outputs; undefined when Blockbook does not know it. */\n async getTransactionDetails(txid: string): Promise<BlockbookTxDetails | undefined> {\n try {\n const tx = await this.get(`/v2/tx/${txid}`, (v): v is BlockbookTxDetails => BlockbookClient.isTx(v))\n const out: BlockbookTxDetails = { ...tx }\n delete (out as { hex?: string }).hex\n return out\n } catch (e) {\n if (e instanceof NetworkError && /\\b(400|404)\\b/.test(e.message)) return undefined\n throw e\n }\n }\n\n private static isTx(v: unknown): v is BlockbookTx {\n return isRecord(v) && typeof v.txid === 'string' && typeof v.blockHeight === 'number' && typeof v.confirmations === 'number'\n }\n\n async getTransactionInfo(txid: string): Promise<BlockbookTx | undefined> {\n try { return await this.get(`/v2/tx/${txid}`, BlockbookClient.isTx) } catch (e) {\n if (e instanceof NetworkError && /\\b(400|404)\\b/.test(e.message)) return undefined\n throw e\n }\n }\n\n async getTransaction(txid: string): Promise<string> {\n const data = await this.get(`/v2/tx/${txid}`, BlockbookClient.isTx)\n if (typeof data.hex !== 'string' || !data.hex) throw new NetworkError(`Transaction ${txid} has no hex data`, { provider: this.base })\n return data.hex\n }\n\n async broadcast(rawTx: string): Promise<string> {\n const data = await this.get(`/v2/sendtx/${rawTx}`, (v): v is { result?: string; error?: { message?: string } | string } => isRecord(v))\n if (data.error) throw new Error(typeof data.error === 'string' ? data.error : data.error.message ?? 'broadcast failed')\n if (!data.result) throw new NetworkError('Blockbook returned no txid', { provider: this.base })\n return data.result\n }\n\n /** sat/vB. Blockbook reports BTC/kB (×1e5 → sat/vB); falls back to mempool.space when it has no estimate. */\n async estimateFee(blocks: number): Promise<number> {\n try {\n const data = await this.get(`/v1/estimatefee/${blocks}`, (v): v is { result?: string } | string => typeof v === 'string' || isRecord(v))\n const rate = Number(typeof data === 'string' ? data : data.result)\n if (rate > 0) return Math.max(rate * 100_000, 1)\n } catch { /* fall through */ }\n const res = await fetchWithTimeout(this.fetchFn, `${MEMPOOL_SPACE_URL}/api/v1/fees/recommended`, undefined, this.timeoutMs, MEMPOOL_SPACE_URL)\n if (!res.ok) throw new NetworkError('Fee estimation request failed', { provider: MEMPOOL_SPACE_URL })\n const d = (await res.json()) as { fastestFee: number; halfHourFee: number; hourFee: number; economyFee: number }\n const satPerVb = blocks <= 1 ? d.fastestFee : blocks <= 3 ? d.halfHourFee : blocks <= 6 ? d.hourFee : d.economyFee\n if (!satPerVb || satPerVb <= 0) throw new NetworkError('Fee estimation is unavailable', { provider: MEMPOOL_SPACE_URL })\n return satPerVb\n }\n\n async getBlockHeight(): Promise<number> {\n const data = await this.get('/v2', (v): v is { blockbook?: { bestHeight?: number } } => isRecord(v))\n const h = data.blockbook?.bestHeight\n if (typeof h !== 'number' || h <= 0) throw new NetworkError('Blockbook did not report a block height', { provider: this.base })\n return h\n }\n}\n","import { NetworkError } from '@anywalletkit/core'\n\nexport const DEFAULT_TIMEOUT_MS = 15_000\n\n/** fetch with a per-request timeout when the runtime has `AbortSignal.timeout` (Hermes needs runtime-hermes for it). */\nexport async function fetchWithTimeout(fetchFn: typeof fetch, url: string, init: RequestInit | undefined, timeoutMs: number, provider: string): Promise<Response> {\n const signal = typeof AbortSignal !== 'undefined' && typeof AbortSignal.timeout === 'function' ? AbortSignal.timeout(timeoutMs) : undefined\n try {\n return await fetchFn(url, { ...init, ...(signal ? { signal } : {}) })\n } catch (e) {\n throw new NetworkError(`Request failed: ${url}`, { provider, cause: e })\n }\n}\n\nexport const isRecord = (v: unknown): v is Record<string, unknown> => typeof v === 'object' && v !== null && !Array.isArray(v)\nexport const isHex64 = (v: unknown): v is string => typeof v === 'string' && /^[0-9a-fA-F]{64}$/.test(v)\nexport const isIntString = (v: unknown): v is string => typeof v === 'string' && /^-?\\d+$/.test(v)\n","/** Bitcoin mainnet, testnet or regtest. */\nexport type BtcNetwork = 'bitcoin' | 'testnet' | 'regtest'\n\n/** Address / script type the account spends from. BIP-84 p2wpkh (bc1q…) or BIP-86 p2tr (bc1p…). */\nexport type BtcAddressType = 'p2wpkh' | 'p2tr'\n\n/** Minimal chain-data client every transport implements. Values in satoshis, fee rates in sat/vB. */\nexport interface BtcClient {\n connect(): Promise<void>\n close(): Promise<void>\n getBalance(address: string): Promise<{ confirmed: bigint; unconfirmed: bigint; unconfirmedOutgoing?: bigint }>\n listUnspent(address: string): Promise<Utxo[]>\n getHistory(address: string): Promise<Array<{ txid: string; height: number }>>\n /** Raw transaction hex. */\n getTransaction(txid: string): Promise<string>\n /** Full tx record (used for receipts). */\n getTransactionInfo?(txid: string): Promise<BlockbookTx | undefined>\n /** Broadcast raw hex; returns the txid. */\n broadcast(rawTx: string): Promise<string>\n /** Fee rate in sat/vB for confirmation within `blocks`. */\n estimateFee(blocks: number): Promise<number>\n /** Current chain tip height (anti-fee-sniping locktime). Optional. */\n getBlockHeight?(): Promise<number>\n}\n\n/** An unspent output the account can spend. */\nexport interface Utxo {\n txid: string\n vout: number\n /** Satoshis. */\n value: bigint\n /** Block height; 0 or -1 while unconfirmed. */\n height: number\n}\n\n/** One transport to a Bitcoin indexer: Blockbook or Esplora over HTTP. */\nexport type BtcClientConfig =\n /** Trezor Blockbook REST (`https://btc1.trezor.io`, QuickNode's Blockbook add-on, …). */\n | { type: 'blockbook-http'; clientConfig: { url: string } }\n /** Esplora REST (`https://mempool.space/api`, `https://blockstream.info/api`). */\n | { type: 'esplora-http'; clientConfig: { url: string } }\n\n/**\n * Options for a Bitcoin wallet manager or account: transports, network, address type and fee\n * limits.\n */\nexport interface BtcConfig {\n /** One or more transports (config objects or ready `BtcClient`s). A list fails over in order. Omit for an offline (sign-only) wallet. */\n client?: BtcClientConfig | BtcClient | Array<BtcClientConfig | BtcClient>\n /** Network; default `bitcoin` (mainnet). */\n network?: BtcNetwork\n /** p2wpkh (BIP-84, default) or p2tr (BIP-86 taproot). Changes the derivation path and the address. */\n addressType?: BtcAddressType\n /** Extra attempts across the client list after the first failure (default 3). */\n retries?: number\n /** Per-request timeout in ms (default 15000). */\n timeoutMs?: number\n /** Max fee (sats) for `transfer`. */\n transferMaxFee?: bigint | number\n /** Max fee (sats) for `sendTransaction` / `signTransaction`. */\n transactionMaxFee?: bigint | number\n /** Fee-rate ceiling in sat/vB (default 500). Anything above is refused before signing or broadcast. */\n maxFeeRate?: number\n /** Coin-selection input cap (default 200). */\n maxInputs?: number\n /** Opt-in to replace-by-fee signalling (default true). */\n rbf?: boolean\n /** Set nLockTime to the current height so the tx cannot be mined into a reorg (default true; skipped when the transport has no `getBlockHeight`). */\n antiFeeSniping?: boolean\n /** Injectable fetch (tests, custom agents). Defaults to globalThis.fetch. */\n fetch?: typeof fetch\n}\n\n/** A spend. `value` in satoshis; `feeRate` in sat/vB (estimated for `confirmationTarget` blocks when omitted). */\nexport interface BtcSpend {\n to: string\n value: bigint | number | string\n feeRate?: bigint | number\n confirmationTarget?: number\n /** Override the account-level `rbf` default for this spend. */\n rbf?: boolean\n}\n\n/** `sendTransaction` accepts a spend or an already signed raw transaction hex. */\nexport type BtcTransaction = BtcSpend | string\n\n/** A Bitcoin transfer. Amount in satoshis. */\nexport interface BtcTransferOptions {\n /** Not supported on Bitcoin; present for the shared account interface. */\n token?: string\n recipient: string\n amount: bigint | number | string\n}\n\n/** A mined Bitcoin transaction. */\nexport interface BtcReceipt {\n hash: string\n /** Always 1 once mined — a Bitcoin transaction cannot fail after inclusion. */\n status: 1\n blockNumber: bigint\n confirmations: number\n /** Total fee in sats (when the transport reports it). */\n fee?: bigint\n hex?: string\n}\n\n/** Transport-neutral tx record (Blockbook's /api/v2/tx shape; Esplora is mapped onto it). */\nexport interface BlockbookTx {\n txid: string\n blockHeight: number\n confirmations: number\n fees?: string\n hex?: string\n blockTime?: number\n}\n\n/** The most one transaction can send (a sweep of every UTXO), after the fee. */\nexport interface BtcMaxSpendableResult {\n /** Max sats one transaction can send after the fee. 0n when nothing is spendable. */\n amount: bigint\n fee: bigint\n /** Always 0n: a sweep leaves no change. */\n changeValue: bigint\n /** Inputs the sweep would consume. */\n inputs: number\n feeRate: bigint\n}\n\n/** Problems a described transaction is flagged with. */\nexport type BtcWarning =\n /** Fee rate above `maxFeeRate` (also a hard error before signing/broadcast). */\n | 'high-fee-rate'\n /** Fee exceeds 10 % of the amount sent. */\n | 'fee-over-10pct-of-amount'\n /** An output is below its dust threshold. */\n | 'dust-output'\n /** Change was below dust and folded into the fee. */\n | 'no-change'\n\n/** One input of a described transaction: the UTXO it spends. */\nexport interface BtcTxInputDescription {\n txid: string\n vout: number\n value: bigint\n}\n\n/** One output of a described transaction, tagged as the recipient, our change, or unknown. */\nexport interface BtcTxOutputDescription {\n /** Undefined for scripts without an address form. */\n address: string | undefined\n value: bigint\n role: 'recipient' | 'change' | 'unknown'\n}\n\n/** \"What you sign\": the fully resolved transaction before (or after) signing. */\nexport interface BtcTxDescription {\n kind: 'btc-transfer'\n inputs: BtcTxInputDescription[]\n outputs: BtcTxOutputDescription[]\n /** Sats sent to non-change outputs. */\n amount: bigint\n fee: bigint\n /** sat/vB, rounded to 2 decimals. */\n feeRate: number\n vsize: number\n rbf: boolean\n lockTime: number\n /** Present once the transaction is signed. */\n txid?: string\n warnings: BtcWarning[]\n}\n\n/** CAIP-2 ids of the Bitcoin networks, by name. */\nexport const CAIP2_GENESIS: Record<BtcNetwork, string> = {\n bitcoin: 'bip122:000000000019d6689c085ae165831e93',\n testnet: 'bip122:000000000933ea01ad0ee984209779ba',\n regtest: 'bip122:0f9188f13cb7b2c71f2a335e3a4fc328',\n}\n","/**\n * Activity history for Bitcoin: a `HistorySource` over Blockbook's\n * `/api/v2/address/{a}?details=txs` pages (Trezor's indexer, QuickNode's\n * Blockbook add-on, any self-hosted instance), reusing the package's\n * `BlockbookClient` and failing over across several instances.\n *\n * One transaction = one native transfer in the owner's direction: a send is\n * what left to non-own outputs (fee separate), a receive is what landed on the\n * address. The cursor is the Blockbook page number. Explorer: mempool.space.\n */\nimport type { ChainTransfer, ChainTx, HistoryPage, HistoryQuery, HistorySource } from '@anywalletkit/core'\nimport { BlockbookClient, type BlockbookAddressPage, type BlockbookTxDetails } from './blockbook.js'\nimport { DEFAULT_TIMEOUT_MS } from './http.js'\nimport { CAIP2_GENESIS, type BtcNetwork } from './types.js'\n\n// ── Public types ─────────────────────────────────────────────────────────────\n\n/** Options for {@link createBtcHistory}. */\nexport interface BtcHistoryOptions {\n /** One Blockbook root (`https://btc1.trezor.io`). */\n blockbookUrl?: string\n /** Several roots, tried in order (failover). */\n blockbookUrls?: string[]\n /** `bitcoin` (default), `testnet`, `regtest`. */\n network?: BtcNetwork\n fetch?: typeof fetch\n /** Per request, ms. Default 15 000. */\n timeoutMs?: number\n /** Rows per Blockbook page (its max is 1000). Default: the query limit, capped at 100. */\n pageSize?: number\n}\n\n/** What a Bitcoin `ChainTx` was built from, and the address's own totals. */\nexport interface BtcHistoryRaw {\n /** The Blockbook transaction (vin / vout with addresses and values; `hex` dropped). */\n tx: BlockbookTxDetails\n /** Sum of inputs spent by the address, sats. */\n ownIn: bigint\n /** Sum of outputs paid to the address, sats. */\n ownOut: bigint\n}\n\n/** A `ChainTx` with the Blockbook transaction it was built from. */\nexport interface BtcChainTx extends ChainTx {\n raw: BtcHistoryRaw\n}\n\n/** One page of Bitcoin history. */\nexport interface BtcHistoryPage extends HistoryPage {\n items: BtcChainTx[]\n /** Blockbook page served / total pages. */\n page?: number\n totalPages?: number\n}\n\n/** Bitcoin history from a Blockbook instance. Build it with {@link createBtcHistory}. */\nexport interface BtcHistorySource extends HistorySource {\n listActivity(address: string, query?: HistoryQuery): Promise<BtcHistoryPage>\n getTransaction(hash: string, address: string): Promise<BtcChainTx | undefined>\n}\n\n/** Every configured Blockbook endpoint failed (or none was configured). */\nexport class HistoryUnavailableError extends Error {\n readonly chain: string\n readonly reason: string\n readonly attempts: readonly string[]\n constructor(chain: string, reason: string, attempts: readonly string[] = []) {\n super(`History unavailable for ${chain}: ${reason}`)\n this.name = 'HistoryUnavailableError'\n this.chain = chain\n this.reason = reason\n this.attempts = attempts\n }\n}\n\nconst DEFAULT_LIMIT = 25\nconst MAX_PAGE_SIZE = 100\n\n// ── Cursor: the next Blockbook page, base64 JSON ─────────────────────────────\n\n/** @internal Decoded form of a Bitcoin history cursor. */\nexport interface BtcHistoryCursor {\n v: 1\n /** Next page (1-based). */\n p: number\n /** Page size the pagination started with (changing it mid-way would skip or repeat rows). */\n s: number\n}\n\nconst B64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'\n\nfunction b64encode(s: string): string {\n let out = ''\n for (let i = 0; i < s.length; i += 3) {\n const c = [s.charCodeAt(i), s.charCodeAt(i + 1), s.charCodeAt(i + 2)]\n const n = (c[0]! << 16) | ((c[1]! || 0) << 8) | (c[2]! || 0)\n out += B64[(n >> 18) & 63]! + B64[(n >> 12) & 63]! + (Number.isNaN(c[1]) ? '=' : B64[(n >> 6) & 63]!) + (Number.isNaN(c[2]) ? '=' : B64[n & 63]!)\n }\n return out\n}\n\nfunction b64decode(s: string): string {\n const clean = s.replace(/[^A-Za-z0-9+/]/g, '')\n let out = ''\n for (let i = 0; i < clean.length; i += 4) {\n const c = [0, 1, 2, 3].map((k) => (i + k < clean.length ? B64.indexOf(clean[i + k]!) : -1))\n if (c[0]! < 0 || c[1]! < 0) throw new Error('bad base64')\n const n = (c[0]! << 18) | (c[1]! << 12) | ((c[2]! < 0 ? 0 : c[2]!) << 6) | (c[3]! < 0 ? 0 : c[3]!)\n out += String.fromCharCode((n >> 16) & 0xff)\n if (c[2]! >= 0) out += String.fromCharCode((n >> 8) & 0xff)\n if (c[3]! >= 0) out += String.fromCharCode(n & 0xff)\n }\n return out\n}\n\nexport function encodeCursor(c: BtcHistoryCursor): string {\n return b64encode(JSON.stringify(c))\n}\n\nexport function decodeCursor(s: string): BtcHistoryCursor {\n let parsed: unknown\n try {\n parsed = JSON.parse(b64decode(s))\n } catch {\n throw new Error('@anywalletkit/wallet-btc: malformed history cursor')\n }\n const c = parsed as Partial<BtcHistoryCursor> | null\n if (!c || c.v !== 1 || !Number.isInteger(c.p) || (c.p as number) < 1 || !Number.isInteger(c.s) || (c.s as number) < 1) throw new Error('@anywalletkit/wallet-btc: malformed history cursor')\n return { v: 1, p: c.p as number, s: c.s as number }\n}\n\n// ── Mapping ──────────────────────────────────────────────────────────────────\n\nconst big = (v: unknown): bigint => (typeof v === 'string' && /^-?\\d+$/.test(v) ? BigInt(v) : typeof v === 'number' ? BigInt(Math.trunc(v)) : 0n)\n\nexport function mapBlockbookTx(chain: string, address: string, tx: BlockbookTxDetails): BtcChainTx {\n const owns = (e: { isAddress?: boolean; addresses?: string[] }) => e.isAddress !== false && (e.addresses ?? []).includes(address)\n let ownIn = 0n, ownOut = 0n, sentToOthers = 0n\n for (const vin of tx.vin ?? []) if (owns(vin)) ownIn += big(vin.value)\n for (const vout of tx.vout ?? []) {\n if (owns(vout)) ownOut += big(vout.value)\n else sentToOthers += big(vout.value)\n }\n const firstInput = (tx.vin ?? []).find((v) => v.isAddress !== false && v.addresses?.[0])?.addresses?.[0]\n const firstOtherOutput = (tx.vout ?? []).find((v) => v.isAddress !== false && !owns(v) && v.addresses?.[0])?.addresses?.[0]\n const transfers: ChainTransfer[] = []\n let from: string, to: string | null, nativeValue: bigint\n if (ownIn > 0n) {\n // We spent inputs: a send (or a consolidation when every output is ours).\n from = address\n to = firstOtherOutput ?? address\n nativeValue = firstOtherOutput ? sentToOthers : ownOut\n if (nativeValue > 0n) transfers.push({ token: null, from: address, to, amount: nativeValue })\n } else {\n // Only outputs are ours: a receive (coinbase has no input address).\n from = firstInput ?? 'coinbase'\n to = address\n nativeValue = ownOut\n if (nativeValue > 0n) transfers.push({ token: null, from, to: address, amount: nativeValue })\n }\n const confirmed = tx.confirmations > 0 && tx.blockHeight > 0\n const out: BtcChainTx = {\n chain, hash: tx.txid, time: tx.blockTime ?? 0, status: confirmed ? 'confirmed' : 'pending', address, from, to, nativeValue, transfers,\n raw: { tx, ownIn, ownOut },\n }\n if (tx.fees !== undefined) out.fee = big(tx.fees)\n if (confirmed) out.block = BigInt(tx.blockHeight)\n return out\n}\n\n// ── Source ───────────────────────────────────────────────────────────────────\n\n/** mempool.space link for a transaction. */\nexport function btcExplorerTxUrl(hash: string, network: BtcNetwork = 'bitcoin'): string {\n return `https://mempool.space/${network === 'testnet' ? 'testnet/' : ''}tx/${hash}`\n}\n\n/**\n * A history source for Bitcoin addresses backed by Blockbook (Trezor's public instances,\n * QuickNode's add-on, or your own).\n *\n * @throws Error when no Blockbook URL is given.\n */\nexport function createBtcHistory(options: BtcHistoryOptions = {}): BtcHistorySource {\n const network = options.network ?? 'bitcoin'\n const chain = CAIP2_GENESIS[network]\n const urls = [...(options.blockbookUrls ?? []), ...(options.blockbookUrl ? [options.blockbookUrl] : [])]\n if (urls.length === 0) throw new Error('@anywalletkit/wallet-btc: createBtcHistory needs blockbookUrl or blockbookUrls')\n const fetchFn = options.fetch ?? globalThis.fetch\n if (typeof fetchFn !== 'function') throw new Error('@anywalletkit/wallet-btc: no global fetch; pass `fetch` in the options')\n const clients = urls.map((url) => ({ url, client: new BlockbookClient({ url }, fetchFn, options.timeoutMs ?? DEFAULT_TIMEOUT_MS) }))\n\n async function failover<T>(run: (client: BlockbookClient) => Promise<T>): Promise<T> {\n const attempts: string[] = []\n for (const { url, client } of clients) {\n try {\n return await run(client)\n } catch (e) {\n attempts.push(`${url}: ${e instanceof Error ? e.message : String(e)}`)\n }\n }\n throw new HistoryUnavailableError(chain, attempts[attempts.length - 1] ?? 'every Blockbook failed', attempts)\n }\n\n return {\n chain,\n\n async listActivity(address: string, query: HistoryQuery = {}): Promise<BtcHistoryPage> {\n const cursor = query.cursor ? decodeCursor(query.cursor) : undefined\n const pageSize = cursor?.s ?? Math.min(MAX_PAGE_SIZE, Math.max(1, Math.floor(options.pageSize ?? query.limit ?? DEFAULT_LIMIT)))\n const pageNo = cursor?.p ?? 1\n const data: BlockbookAddressPage = await failover((c) => c.getAddressPage(address, pageNo, pageSize))\n let items = (data.transactions ?? []).map((tx) => mapBlockbookTx(chain, address, tx))\n items.sort((a, b) => (b.block === undefined ? 1 : a.block === undefined ? -1 : (b.block > a.block ? 1 : b.block < a.block ? -1 : 0)) || b.time - a.time)\n const totalPages = data.totalPages ?? 1\n let more = pageNo < totalPages\n if (query.since !== undefined) {\n const since = query.since\n if (items.some((t) => t.status === 'confirmed' && t.time < since)) more = false\n items = items.filter((t) => t.status !== 'confirmed' || t.time >= since)\n }\n const page: BtcHistoryPage = { items, page: pageNo, totalPages }\n if (more) page.cursor = encodeCursor({ v: 1, p: pageNo + 1, s: pageSize })\n return page\n },\n\n async getTransaction(hash: string, address: string): Promise<BtcChainTx | undefined> {\n const tx = await failover((c) => c.getTransactionDetails(hash))\n return tx ? mapBlockbookTx(chain, address, tx) : undefined\n },\n\n explorerTxUrl(hash: string): string {\n return btcExplorerTxUrl(hash, network)\n },\n }\n}\n\n"],"mappings":"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","names":["NetworkError","NetworkError"]}
|