@anywalletkit/wallet-zcash 0.3.0 → 0.4.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/dist/{chunk-KICTVRL7.js → chunk-JIJF3MGJ.js} +1 -1
- package/dist/chunk-JIJF3MGJ.js.map +1 -0
- package/dist/{history-BpA-R7Tf.d.cts → history-CiZ6aFMT.d.cts} +1 -1
- package/dist/{history-BpA-R7Tf.d.ts → history-CiZ6aFMT.d.ts} +1 -1
- package/dist/history.cjs.map +1 -1
- package/dist/history.d.cts +1 -1
- package/dist/history.d.ts +1 -1
- package/dist/history.js +1 -1
- package/dist/index.cjs +9 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -6
- package/dist/index.d.ts +4 -6
- package/dist/index.js +10 -9
- package/dist/index.js.map +1 -1
- package/package.json +5 -4
- package/dist/chunk-KICTVRL7.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/blockchair.ts","../src/encoding.ts","../src/http.ts","../src/types.ts","../src/history.ts"],"sourcesContent":["/**\n * Blockchair REST transport (`https://api.blockchair.com/zcash`): public, CORS\n * open, no key needed at wallet volumes (one request every couple of seconds;\n * a `key` lifts the quota). Mainnet only — Blockchair indexes no Zcash\n * testnet. Address dashboards carry the UTXO set (mempool included, block_id\n * -1), `raw/transaction` the hex, `push/transaction` broadcasts.\n */\nimport { NetworkError } from '@anywalletkit/core'\nimport { hexToBytes } from './encoding.js'\nimport { DEFAULT_TIMEOUT_MS, fetchWithTimeout, isInt, isRecord, refusal, refusedStatus } from './http.js'\nimport type { SpentOutput, Utxo, ZcashClient, ZcashTxInfo } from './types.js'\n\n/** Default Blockchair API root for Zcash. */\nexport const BLOCKCHAIR_URL = 'https://api.blockchair.com/zcash'\n/** Blockchair caps the `utxo` list of an address dashboard at this many rows. */\nconst UTXO_LIMIT = 1000\n\ninterface BlockchairUtxo { block_id: number; transaction_hash: string; index: number; value: number }\ninterface BlockchairAddress { balance: number; unspent_output_count?: number; transaction_count?: number }\nexport interface BlockchairTxRow { block_id: number; hash: string; time?: string; fee?: number; input_count?: number; output_count?: number }\nexport interface BlockchairOutput { index: number; value: number; script_hex: string; recipient?: string }\nexport interface BlockchairInput extends BlockchairOutput { transaction_hash: string; spending_index?: number; spending_sequence?: number }\nexport interface BlockchairTxDashboard { transaction: BlockchairTxRow; inputs: BlockchairInput[]; outputs: BlockchairOutput[] }\ninterface Envelope<T> { data: T; context: { code: number; state?: number; error?: string } }\n\nconst isUtxo = (v: unknown): v is BlockchairUtxo => isRecord(v) && isInt(v.block_id) && typeof v.transaction_hash === 'string' && isInt(v.index) && typeof v.value === 'number'\nconst isOutput = (v: unknown): v is BlockchairOutput => isRecord(v) && isInt(v.index) && typeof v.value === 'number' && typeof v.script_hex === 'string'\nconst isDashboard = (v: unknown): v is BlockchairTxDashboard =>\n isRecord(v) && isRecord(v.transaction) && isInt(v.transaction.block_id) && typeof v.transaction.hash === 'string' && Array.isArray(v.inputs) && v.inputs.every(isOutput) && Array.isArray(v.outputs) && v.outputs.every(isOutput)\n\n/** \"2026-10-18 10:05:14\" (UTC) → unix seconds. */\nexport function blockchairTime(s: string | undefined): number | undefined {\n if (!s) return undefined\n const t = Date.parse(`${s.replace(' ', 'T')}Z`)\n return Number.isFinite(t) ? Math.floor(t / 1000) : undefined\n}\n\nexport class BlockchairClient implements ZcashClient {\n private readonly base: string\n private readonly key: string | undefined\n private readonly fetchFn: typeof fetch\n private readonly timeoutMs: number\n\n constructor(config: { url?: string; key?: string } = {}, fetchFn: typeof fetch = globalThis.fetch, timeoutMs = DEFAULT_TIMEOUT_MS) {\n this.base = (config.url ?? BLOCKCHAIR_URL).replace(/\\/+$/, '')\n this.key = config.key\n this.fetchFn = fetchFn\n this.timeoutMs = timeoutMs\n }\n\n async connect(): Promise<void> {}\n async close(): Promise<void> {}\n\n private url(path: string, query: Record<string, string> = {}): string {\n const q = new URLSearchParams(query)\n if (this.key) q.set('key', this.key)\n const s = q.toString()\n return `${this.base}/${path}${s ? `?${s}` : ''}`\n }\n\n private async request<T>(path: string, query: Record<string, string>, init: RequestInit | undefined, check: (v: unknown) => v is T): Promise<{ data: T; state: number | undefined }> {\n const url = this.url(path, query)\n const res = await fetchWithTimeout(this.fetchFn, url, init, this.timeoutMs, this.base)\n let body: unknown\n try { body = await res.json() } catch (e) {\n if (res.status === 402 || res.status === 429 || res.status === 430) throw new NetworkError(`Blockchair rate limit (${res.status})`, { provider: this.base })\n throw new NetworkError(`Blockchair returned non-JSON (${res.status}) for ${url}`, { provider: this.base, cause: e })\n }\n const env = body as Partial<Envelope<unknown>>\n const code = env.context?.code ?? res.status\n if (code === 402 || code === 429 || code === 430) throw new NetworkError(`Blockchair rate limit (${code})`, { provider: this.base })\n if (code === 404) throw new NotFound()\n if (code !== 200 || !res.ok) throw new NetworkError(`Blockchair request failed: ${code} ${env.context?.error ?? res.statusText} (${url})`, { provider: this.base })\n if (!check(env.data)) throw new NetworkError(`Blockchair returned an unexpected shape for ${url}`, { provider: this.base })\n return { data: env.data, state: env.context?.state }\n }\n\n private async dashboard(address: string): Promise<{ address: BlockchairAddress; utxo: BlockchairUtxo[]; transactions: string[]; state: number | undefined }> {\n const { data, state } = await this.request(`dashboards/address/${address}`, { limit: `0,${UTXO_LIMIT}` }, undefined, (v): v is Record<string, { address: BlockchairAddress; utxo: BlockchairUtxo[]; transactions?: string[] }> =>\n isRecord(v) && Object.values(v).every((a) => isRecord(a) && isRecord(a.address) && typeof a.address.balance === 'number' && Array.isArray(a.utxo) && a.utxo.every(isUtxo)))\n const entry = data[address] ?? Object.values(data)[0]\n if (!entry) throw new NetworkError(`Blockchair knows no address ${address}`, { provider: this.base })\n return { address: entry.address, utxo: entry.utxo, transactions: entry.transactions ?? [], state }\n }\n\n /** Transaction hashes of an address, newest first, paged by offset (what the activity history walks). */\n async listTransactions(address: string, limit: number, offset: number): Promise<{ hashes: string[]; total: number | undefined }> {\n const { data } = await this.request(`dashboards/address/${address}`, { limit: `${limit},0`, offset: `${offset},0` }, undefined, (v): v is Record<string, { address: BlockchairAddress; transactions?: string[] }> =>\n isRecord(v) && Object.values(v).every((a) => isRecord(a) && isRecord(a.address) && (a.transactions === undefined || Array.isArray(a.transactions))))\n const entry = data[address] ?? Object.values(data)[0]\n if (!entry) throw new NetworkError(`Blockchair knows no address ${address}`, { provider: this.base })\n return { hashes: (entry.transactions ?? []).filter((h): h is string => typeof h === 'string'), total: entry.address.transaction_count }\n }\n\n /** Confirmed = the UTXOs mined so far; unconfirmed = incoming mempool outputs. (Beyond 1000 UTXOs the dashboard balance is used.) */\n async getBalance(address: string): Promise<{ confirmed: bigint; unconfirmed: bigint }> {\n const d = await this.dashboard(address)\n let confirmed = 0n, unconfirmed = 0n\n for (const u of d.utxo) { if (u.block_id > 0) confirmed += BigInt(u.value); else unconfirmed += BigInt(u.value) }\n if ((d.address.unspent_output_count ?? d.utxo.length) > d.utxo.length) confirmed = BigInt(d.address.balance) - unconfirmed\n return { confirmed, unconfirmed }\n }\n\n async listUnspent(address: string): Promise<Utxo[]> {\n const d = await this.dashboard(address)\n return d.utxo.map((u) => ({ txid: u.transaction_hash, vout: u.index, value: BigInt(u.value), height: u.block_id > 0 ? u.block_id : -1 }))\n }\n\n async getTransaction(txid: string): Promise<string> {\n const { data } = await this.request(`raw/transaction/${txid}`, {}, undefined, (v): v is Record<string, { raw_transaction: string }> =>\n isRecord(v) && Object.values(v).every((t) => isRecord(t) && typeof t.raw_transaction === 'string'))\n const hex = (data[txid] ?? Object.values(data)[0])?.raw_transaction\n if (!hex) throw new NetworkError(`Transaction ${txid} has no raw data`, { provider: this.base })\n return hex\n }\n\n /** Inputs / outputs with addresses, values and scripts — what the activity history and prevout lookups read. */\n async getTransactionDashboard(txid: string): Promise<BlockchairTxDashboard | undefined> {\n try {\n const { data, state } = await this.request(`dashboards/transaction/${txid}`, {}, undefined, (v): v is Record<string, BlockchairTxDashboard | null> =>\n isRecord(v) && Object.values(v).every((t) => t === null || isDashboard(t)))\n const t = data[txid] ?? Object.values(data)[0]\n if (!t) return undefined\n return { ...t, transaction: { ...t.transaction, ...(state !== undefined ? { confirmations: t.transaction.block_id > 0 ? state - t.transaction.block_id + 1 : 0 } : {}) } } as BlockchairTxDashboard\n } catch (e) {\n if (e instanceof NotFound) return undefined\n throw e\n }\n }\n\n /** Several transactions in one call (Blockchair takes up to 10 comma-separated hashes). */\n async getTransactionDashboards(txids: string[]): Promise<Map<string, BlockchairTxDashboard>> {\n const out = new Map<string, BlockchairTxDashboard>()\n for (let i = 0; i < txids.length; i += 10) {\n const slice = txids.slice(i, i + 10)\n const { data, state } = await this.request(`dashboards/transactions/${slice.join(',')}`, {}, undefined, (v): v is Record<string, BlockchairTxDashboard | null> =>\n isRecord(v) && Object.values(v).every((t) => t === null || isDashboard(t)))\n for (const [hash, t] of Object.entries(data)) {\n if (!t) continue\n const confirmations = state !== undefined && t.transaction.block_id > 0 ? state - t.transaction.block_id + 1 : 0\n out.set(hash, { ...t, transaction: { ...t.transaction, confirmations } } as BlockchairTxDashboard)\n }\n }\n return out\n }\n\n async getOutput(txid: string, vout: number): Promise<SpentOutput | undefined> {\n const d = await this.getTransactionDashboard(txid)\n const o = d?.outputs.find((x) => x.index === vout)\n return o ? { value: BigInt(o.value), script: hexToBytes(o.script_hex) } : undefined\n }\n\n async getTransactionInfo(txid: string): Promise<ZcashTxInfo | undefined> {\n const d = await this.getTransactionDashboard(txid)\n if (!d) return undefined\n const t = d.transaction as BlockchairTxRow & { confirmations?: number }\n const info: ZcashTxInfo = { txid: t.hash, blockHeight: t.block_id > 0 ? t.block_id : -1, confirmations: t.confirmations ?? 0 }\n if (typeof t.fee === 'number') info.fee = BigInt(t.fee)\n const time = blockchairTime(t.time)\n if (time !== undefined) info.blockTime = time\n return info\n }\n\n async broadcast(rawTx: string): Promise<string> {\n const body = `data=${encodeURIComponent(rawTx)}`\n const url = this.url('push/transaction')\n const res = await fetchWithTimeout(this.fetchFn, url, { method: 'POST', headers: { 'content-type': 'application/x-www-form-urlencoded' }, body }, this.timeoutMs, this.base)\n let env: Partial<Envelope<{ transaction_hash?: string } | null>> = {}\n let parsed = false\n try { env = (await res.json()) as typeof env; parsed = true } catch { /* handled below */ }\n const hash = env.data?.transaction_hash\n if (hash) return hash\n const reason = env.context?.error\n // The node's verdict — an error it gave, with a 4xx (not 408) or a 200 — is a refusal: nothing was\n // taken. A proxy's HTML 502, a 5xx, a timeout or an unreadable body may have been (round 3, M12).\n if (parsed && reason && (res.ok || refusedStatus(res.status))) throw refusal(new Error(`Broadcast rejected: ${reason}`))\n throw new NetworkError(`Blockchair broadcast: no answer to rely on (${res.status} ${res.statusText})`, { provider: this.base })\n }\n\n async getBlockHeight(): Promise<number> {\n const { data } = await this.request('stats', {}, undefined, (v): v is { best_block_height: number } => isRecord(v) && isInt(v.best_block_height))\n if (data.best_block_height <= 0) throw new NetworkError('Blockchair reported no block height', { provider: this.base })\n return data.best_block_height\n }\n}\n\nclass NotFound extends Error { constructor() { super('not found'); this.name = 'NotFound' } }\n","/** Byte helpers for the Zcash wire format (little-endian integers, Bitcoin CompactSize). */\nexport { bytesToHex, hexToBytes, concatBytes, utf8ToBytes } from '@noble/hashes/utils.js'\n\nexport function compactSize(n: number): Uint8Array {\n if (!Number.isInteger(n) || n < 0) throw new Error(`CompactSize: ${n} is not a non-negative integer`)\n if (n < 0xfd) return Uint8Array.of(n)\n if (n <= 0xffff) return Uint8Array.of(0xfd, n & 0xff, n >>> 8)\n if (n <= 0xffffffff) return Uint8Array.of(0xfe, n & 0xff, (n >>> 8) & 0xff, (n >>> 16) & 0xff, n >>> 24)\n throw new Error('CompactSize: value too large')\n}\n\nexport function u32le(n: number): Uint8Array {\n if (!Number.isInteger(n) || n < 0 || n > 0xffffffff) throw new Error(`u32: ${n} out of range`)\n return Uint8Array.of(n & 0xff, (n >>> 8) & 0xff, (n >>> 16) & 0xff, n >>> 24)\n}\n\n/** Signed 64-bit little-endian (two's complement). Amounts are never negative here, but ZIP-244 types the field as signed. */\nexport function i64le(v: bigint): Uint8Array {\n if (v < -(1n << 63n) || v >= 1n << 63n) throw new Error(`i64: ${v} out of range`)\n let x = v < 0n ? v + (1n << 64n) : v\n const out = new Uint8Array(8)\n for (let i = 0; i < 8; i++) { out[i] = Number(x & 0xffn); x >>= 8n }\n return out\n}\n\nexport class Writer {\n private readonly parts: Uint8Array[] = []\n u8(n: number): this { this.parts.push(Uint8Array.of(n & 0xff)); return this }\n u32(n: number): this { this.parts.push(u32le(n)); return this }\n i64(v: bigint): this { this.parts.push(i64le(v)); return this }\n bytes(b: Uint8Array): this { this.parts.push(b); return this }\n compact(n: number): this { this.parts.push(compactSize(n)); return this }\n /** CompactSize length prefix + bytes (the \"field encoding\" of a script). */\n varBytes(b: Uint8Array): this { return this.compact(b.length).bytes(b) }\n finish(): Uint8Array {\n const len = this.parts.reduce((s, p) => s + p.length, 0)\n const out = new Uint8Array(len)\n let o = 0\n for (const p of this.parts) { out.set(p, o); o += p.length }\n return out\n }\n}\n\nexport class Reader {\n offset = 0\n constructor(private readonly buf: Uint8Array) {}\n get remaining(): number { return this.buf.length - this.offset }\n private need(n: number): void {\n if (this.offset + n > this.buf.length) throw new Error('Transaction truncated')\n }\n u8(): number { this.need(1); return this.buf[this.offset++]! }\n u32(): number {\n this.need(4)\n const b = this.buf\n const o = this.offset\n this.offset += 4\n return (b[o]! | (b[o + 1]! << 8) | (b[o + 2]! << 16)) + b[o + 3]! * 0x1000000\n }\n i64(): bigint {\n this.need(8)\n let v = 0n\n for (let i = 7; i >= 0; i--) v = (v << 8n) | BigInt(this.buf[this.offset + i]!)\n this.offset += 8\n return v >= 1n << 63n ? v - (1n << 64n) : v\n }\n bytes(n: number): Uint8Array { this.need(n); const out = this.buf.slice(this.offset, this.offset + n); this.offset += n; return out }\n compact(): number {\n const first = this.u8()\n if (first < 0xfd) return first\n if (first === 0xfd) { this.need(2); const v = this.buf[this.offset]! | (this.buf[this.offset + 1]! << 8); this.offset += 2; return v }\n if (first === 0xfe) return this.u32()\n throw new Error('CompactSize: 64-bit lengths are not supported')\n }\n varBytes(): Uint8Array { return this.bytes(this.compact()) }\n}\n\n/** Display ↔ internal byte order of a 32-byte hash (Bitcoin convention: hex is shown reversed). */\nexport function reverseBytes(b: Uint8Array): Uint8Array {\n return Uint8Array.from(b).reverse()\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\n/** An HTTP status that is the server refusing the request itself: 4xx, but not 408 (request timeout). */\nexport const refusedStatus = (status: number): boolean => status >= 400 && status < 500 && status !== 408\n\n/** Mark an error as a node's answer refusing the request: nothing was taken (round 3, M12). */\nexport function refusal<E extends Error>(e: E): E {\n return Object.assign(e, { answered: true })\n}\n\n/**\n * An endpoint answered with a refusal (HTTP 4xx other than 408 with a reason, or an error body):\n * nothing was taken. A thrown fetch, a timeout, a 5xx or a body that cannot be read may have been.\n */\nexport function isAnsweredRefusal(e: unknown): boolean {\n return (e as { answered?: unknown } | null)?.answered === true\n}\n\n/** The node says it already holds the transaction (an earlier attempt delivered it): it is out, not refused. */\nexport function isAlreadyKnown(e: unknown): boolean {\n for (let x: unknown = e, depth = 0; x instanceof Error && depth < 5; x = x.cause, depth++) {\n if (/txn-already-(in-mempool|known)|already (known|in (the )?(mempool|block ?chain))/i.test(x.message)) return true\n }\n return false\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)\nexport const isInt = (v: unknown): v is number => typeof v === 'number' && Number.isInteger(v)\n","/** Zcash mainnet or testnet. */\nexport type ZcashNetwork = 'mainnet' | 'testnet'\n\n/** CAIP-2 ids the SDK uses for Zcash (the swap2 catalog already names `zcash:mainnet`). */\nexport const CAIP2: Record<ZcashNetwork, string> = { mainnet: 'zcash:mainnet', testnet: 'zcash:testnet' }\n\n/** An unspent transparent output the account can spend. */\nexport interface Utxo {\n txid: string\n vout: number\n /** Zatoshis. */\n value: bigint\n /** Block height; -1 while in the mempool. */\n height: number\n}\n\n/** A previous output a transaction spends — ZIP-244 signs its value AND script. */\nexport interface SpentOutput {\n value: bigint\n script: Uint8Array\n}\n\n/** Transport-neutral transaction record (receipts, confirmations). */\nexport interface ZcashTxInfo {\n txid: string\n /** -1 or 0 while unconfirmed. */\n blockHeight: number\n confirmations: number\n fee?: bigint\n /** Unix seconds. */\n blockTime?: number\n}\n\n/** Minimal chain-data client every transport implements. Values in zatoshis. */\nexport interface ZcashClient {\n connect(): Promise<void>\n close(): Promise<void>\n getBalance(address: string): Promise<{ confirmed: bigint; unconfirmed: bigint }>\n listUnspent(address: string): Promise<Utxo[]>\n /** Raw transaction hex (any version — only used to read prevouts and for receipts). */\n getTransaction(txid: string): Promise<string>\n /** Value + scriptPubKey of one output of an existing transaction (what signing a spend of it needs). */\n getOutput(txid: string, vout: number): Promise<SpentOutput | undefined>\n getTransactionInfo(txid: string): Promise<ZcashTxInfo | undefined>\n /** Broadcast raw hex; returns the txid. */\n broadcast(rawTx: string): Promise<string>\n /** Current chain tip height (expiry height, anti-fee-sniping lock time, consensus branch selection). */\n getBlockHeight(): Promise<number>\n}\n\n/** One transport to a Zcash indexer: Blockchair or a Blockbook instance. */\nexport type ZcashClientConfig =\n /** Blockchair's public REST API (`https://api.blockchair.com/zcash`; optional API key). Mainnet only. */\n | { type: 'blockchair'; clientConfig?: { url?: string; key?: string } }\n /** A Zcash Blockbook (NOWNodes `https://zec-blockbook.nownodes.io` with an `api-key` header, a self-hosted instance, …). */\n | { type: 'blockbook-http'; clientConfig: { url: string; headers?: Record<string, string> } }\n\n/**\n * Options for a Zcash wallet manager or account: transports, network and fee limits. Transparent\n * addresses only.\n */\nexport interface ZcashConfig {\n /** One or more transports (config objects or ready `ZcashClient`s). A list fails over in order. Omit for an offline (sign-only) wallet. */\n client?: ZcashClientConfig | ZcashClient | Array<ZcashClientConfig | ZcashClient>\n network?: ZcashNetwork\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 (zatoshis) for `transfer`. */\n transferMaxFee?: bigint | number\n /** Max fee (zatoshis) for `sendTransaction` / `signTransaction`. */\n transactionMaxFee?: bigint | number\n /** Hard fee ceiling in zatoshis for any transaction this account signs or broadcasts (default 1 000 000 = 0.01 ZEC). */\n maxFee?: bigint | number\n /** Blocks after the next block (tip + 1) at which an unmined transaction expires (ZIP-203; default 40, the zcashd/Zebra default). 0 = never. */\n expiryDelta?: number\n /** Set nLockTime to the tip height so the transaction cannot be mined into a reorged block (default true). */\n antiFeeSniping?: boolean\n /**\n * Consensus branch id to sign under. Default on mainnet: the one in force at\n * tip + 1 (`branchIdForHeight`) — set this when a network upgrade activates\n * before the package learns its id. Required on testnet and regtest, whose\n * upgrades activate at other heights.\n */\n consensusBranchId?: number\n /** Coin-selection input cap (default 200). */\n maxInputs?: number\n /** Injectable fetch (tests, custom agents). Defaults to globalThis.fetch. */\n fetch?: typeof fetch\n}\n\n/** A spend. `value` in zatoshis. `fee` overrides the ZIP-317 conventional fee (still subject to `maxFee`). */\nexport interface ZcashSpend {\n to: string\n value: bigint | number | string\n fee?: bigint | number\n}\n\n/** `sendTransaction` accepts a spend or an already signed raw transaction hex. */\nexport type ZcashTransaction = ZcashSpend | string\n\n/** A transparent ZEC transfer. Amount in zatoshis. */\nexport interface ZcashTransferOptions {\n /** Not supported on Zcash; present for the shared account interface. */\n token?: string\n recipient: string\n amount: bigint | number | string\n}\n\n/** A mined Zcash transaction. */\nexport interface ZcashReceipt {\n hash: string\n /** Always 1 once mined — a transparent transaction cannot fail after inclusion. */\n status: 1\n blockNumber: bigint\n confirmations: number\n fee?: bigint\n}\n\n/** The most one transaction can send (a sweep of every UTXO), after the fee. */\nexport interface ZcashMaxSpendableResult {\n /** Max zatoshis 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: number\n}\n\n/** Problems a described transaction is flagged with. */\nexport type ZcashWarning =\n /** Fee exceeds 10 % of the amount sent. */\n | 'fee-over-10pct-of-amount'\n /** Fee is below the ZIP-317 conventional fee — nodes may not relay it. */\n | 'fee-below-conventional'\n /** An output is below the dust floor. */\n | 'dust-output'\n /** Change was below dust and folded into the fee. */\n | 'no-change'\n /** No expiry height: the transaction stays valid in mempools indefinitely. */\n | 'no-expiry'\n\n/** One input of a described transaction: the UTXO it spends. */\nexport interface ZcashTxInputDescription {\n txid: string\n vout: number\n value: bigint\n address: string | undefined\n}\n\n/** One output of a described transaction, tagged as the recipient, our change, or unknown. */\nexport interface ZcashTxOutputDescription {\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 ZcashTxDescription {\n kind: 'zcash-transfer'\n version: 5\n consensusBranchId: number\n inputs: ZcashTxInputDescription[]\n outputs: ZcashTxOutputDescription[]\n /** Zatoshis sent to non-change outputs. */\n amount: bigint\n fee: bigint\n /** The ZIP-317 fee this transaction's shape calls for. */\n conventionalFee: bigint\n /** Serialized size in bytes. */\n size: number\n lockTime: number\n expiryHeight: number\n /** Present once the transaction is signed. */\n txid?: string\n warnings: ZcashWarning[]\n}\n","/**\n * Activity history for Zcash transparent addresses: a `HistorySource` over\n * Blockchair's address dashboard (transaction hashes, newest first) and\n * transaction dashboards (inputs / outputs with addresses and values, fetched\n * ten at a time). Shielded legs of a transaction show up only as the\n * transparent value that entered or left it.\n */\nimport type { ChainTransfer, ChainTx, HistoryPage, HistoryQuery, HistorySource } from '@anywalletkit/core'\nimport { BlockchairClient, blockchairTime, type BlockchairTxDashboard } from './blockchair.js'\nimport { DEFAULT_TIMEOUT_MS } from './http.js'\nimport { CAIP2 } from './types.js'\n\n/** Options for {@link createZcashHistory}. */\nexport interface ZcashHistoryOptions {\n /** Blockchair base (`https://api.blockchair.com/zcash`); optional API key. */\n blockchairUrl?: string\n key?: string\n fetch?: typeof fetch\n timeoutMs?: number\n /** Rows per page (max 100). Default: the query limit, capped at 100. */\n pageSize?: number\n}\n\nexport interface ZcashHistoryRaw {\n tx: BlockchairTxDashboard\n ownIn: bigint\n ownOut: bigint\n}\n\nexport interface ZcashChainTx extends ChainTx { raw: ZcashHistoryRaw }\n\nexport interface ZcashHistoryPage extends HistoryPage {\n items: ZcashChainTx[]\n offset: number\n total?: number\n}\n\n/** Zcash transparent-address history from Blockchair. Build it with {@link createZcashHistory}. */\nexport interface ZcashHistorySource extends HistorySource {\n listActivity(address: string, query?: HistoryQuery): Promise<ZcashHistoryPage>\n getTransaction(hash: string, address: string): Promise<ZcashChainTx | undefined>\n}\n\n/** The history backend failed. */\nexport class HistoryUnavailableError extends Error {\n readonly chain: string\n readonly reason: string\n constructor(chain: string, reason: string) {\n super(`History unavailable for ${chain}: ${reason}`)\n this.name = 'HistoryUnavailableError'\n this.chain = chain\n this.reason = reason\n }\n}\n\nconst DEFAULT_LIMIT = 25\nconst MAX_PAGE_SIZE = 100\n\nexport interface ZcashHistoryCursor { v: 1; o: number; s: number }\n\nexport function encodeCursor(c: ZcashHistoryCursor): string {\n return `${c.v}:${c.o}:${c.s}`\n}\n\nexport function decodeCursor(s: string): ZcashHistoryCursor {\n const m = /^1:(\\d+):(\\d+)$/.exec(s)\n if (!m) throw new Error('@anywalletkit/wallet-zcash: malformed history cursor')\n const o = Number(m[1]), size = Number(m[2])\n if (size < 1) throw new Error('@anywalletkit/wallet-zcash: malformed history cursor')\n return { v: 1, o, s: size }\n}\n\nexport function mapDashboardTx(chain: string, address: string, d: BlockchairTxDashboard): ZcashChainTx {\n let ownIn = 0n, ownOut = 0n, sentToOthers = 0n\n for (const i of d.inputs) if (i.recipient === address) ownIn += BigInt(i.value)\n for (const o of d.outputs) { if (o.recipient === address) ownOut += BigInt(o.value); else sentToOthers += BigInt(o.value) }\n const firstInput = d.inputs.find((i) => i.recipient)?.recipient\n const firstOther = d.outputs.find((o) => o.recipient && o.recipient !== address)?.recipient\n const transfers: ChainTransfer[] = []\n let from: string, to: string | null, nativeValue: bigint\n if (ownIn > 0n) {\n from = address\n to = firstOther ?? address\n nativeValue = firstOther ? sentToOthers : ownOut\n if (nativeValue > 0n) transfers.push({ token: null, from: address, to, amount: nativeValue })\n } else {\n from = firstInput ?? (d.inputs.length === 0 ? 'shielded' : 'coinbase')\n to = address\n nativeValue = ownOut\n if (nativeValue > 0n) transfers.push({ token: null, from, to: address, amount: nativeValue })\n }\n const t = d.transaction as BlockchairTxDashboard['transaction'] & { confirmations?: number }\n const confirmed = t.block_id > 0\n const out: ZcashChainTx = {\n chain, hash: t.hash, time: blockchairTime(t.time) ?? 0, status: confirmed ? 'confirmed' : 'pending', address, from, to, nativeValue, transfers,\n raw: { tx: d, ownIn, ownOut },\n }\n if (typeof t.fee === 'number') out.fee = BigInt(t.fee)\n if (confirmed) out.block = BigInt(t.block_id)\n return out\n}\n\n/** Blockchair link for a transaction. */\nexport function zcashExplorerTxUrl(hash: string): string {\n return `https://blockchair.com/zcash/transaction/${hash}`\n}\n\n/**\n * A history source for transparent Zcash addresses backed by Blockchair (mainnet).\n *\n * @throws Error when no `fetch` is available.\n */\nexport function createZcashHistory(options: ZcashHistoryOptions = {}): ZcashHistorySource {\n const chain = CAIP2.mainnet\n const fetchFn = options.fetch ?? globalThis.fetch\n if (typeof fetchFn !== 'function') throw new Error('@anywalletkit/wallet-zcash: no global fetch; pass `fetch` in the options')\n const client = new BlockchairClient({ ...(options.blockchairUrl ? { url: options.blockchairUrl } : {}), ...(options.key ? { key: options.key } : {}) }, fetchFn, options.timeoutMs ?? DEFAULT_TIMEOUT_MS)\n const wrap = async <T>(run: () => Promise<T>): Promise<T> => {\n try { return await run() } catch (e) { throw new HistoryUnavailableError(chain, e instanceof Error ? e.message : String(e)) }\n }\n\n return {\n chain,\n\n async listActivity(address: string, query: HistoryQuery = {}): Promise<ZcashHistoryPage> {\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 offset = cursor?.o ?? 0\n const { hashes, total } = await wrap(() => client.listTransactions(address, pageSize, offset))\n const dashboards = hashes.length ? await wrap(() => client.getTransactionDashboards(hashes)) : new Map()\n let items = hashes.map((h) => dashboards.get(h)).filter((d): d is BlockchairTxDashboard => !!d).map((d) => mapDashboardTx(chain, address, d))\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 let more = total !== undefined ? offset + hashes.length < total : hashes.length === pageSize\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: ZcashHistoryPage = { items, offset, ...(total !== undefined ? { total } : {}) }\n if (more) page.cursor = encodeCursor({ v: 1, o: offset + hashes.length, s: pageSize })\n return page\n },\n\n async getTransaction(hash: string, address: string): Promise<ZcashChainTx | undefined> {\n const d = await wrap(() => client.getTransactionDashboard(hash))\n return d ? mapDashboardTx(chain, address, d) : undefined\n },\n\n explorerTxUrl: zcashExplorerTxUrl,\n }\n}\n"],"mappings":"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","names":["NetworkError","NetworkError","t"]}
|
|
@@ -302,4 +302,4 @@ declare function zcashExplorerTxUrl(hash: string): string;
|
|
|
302
302
|
*/
|
|
303
303
|
declare function createZcashHistory(options?: ZcashHistoryOptions): ZcashHistorySource;
|
|
304
304
|
|
|
305
|
-
export {
|
|
305
|
+
export { decodeCursor as A, BLOCKCHAIR_URL as B, CAIP2 as C, encodeCursor as D, mapDashboardTx as E, zcashExplorerTxUrl as F, HistoryUnavailableError as H, type SpentOutput as S, type Utxo as U, type ZcashNetwork as Z, type ZcashTxDescription as a, type ZcashClient as b, type ZcashTxInfo as c, type ZcashConfig as d, type ZcashSpend as e, type ZcashTransferOptions as f, type ZcashMaxSpendableResult as g, type ZcashReceipt as h, type ZcashTransaction as i, BlockchairClient as j, type BlockchairInput as k, type BlockchairOutput as l, type BlockchairTxDashboard as m, type BlockchairTxRow as n, type ZcashChainTx as o, type ZcashClientConfig as p, type ZcashHistoryCursor as q, type ZcashHistoryOptions as r, type ZcashHistoryPage as s, type ZcashHistoryRaw as t, type ZcashHistorySource as u, type ZcashTxInputDescription as v, type ZcashTxOutputDescription as w, type ZcashWarning as x, blockchairTime as y, createZcashHistory as z };
|
|
@@ -302,4 +302,4 @@ declare function zcashExplorerTxUrl(hash: string): string;
|
|
|
302
302
|
*/
|
|
303
303
|
declare function createZcashHistory(options?: ZcashHistoryOptions): ZcashHistorySource;
|
|
304
304
|
|
|
305
|
-
export {
|
|
305
|
+
export { decodeCursor as A, BLOCKCHAIR_URL as B, CAIP2 as C, encodeCursor as D, mapDashboardTx as E, zcashExplorerTxUrl as F, HistoryUnavailableError as H, type SpentOutput as S, type Utxo as U, type ZcashNetwork as Z, type ZcashTxDescription as a, type ZcashClient as b, type ZcashTxInfo as c, type ZcashConfig as d, type ZcashSpend as e, type ZcashTransferOptions as f, type ZcashMaxSpendableResult as g, type ZcashReceipt as h, type ZcashTransaction as i, BlockchairClient as j, type BlockchairInput as k, type BlockchairOutput as l, type BlockchairTxDashboard as m, type BlockchairTxRow as n, type ZcashChainTx as o, type ZcashClientConfig as p, type ZcashHistoryCursor as q, type ZcashHistoryOptions as r, type ZcashHistoryPage as s, type ZcashHistoryRaw as t, type ZcashHistorySource as u, type ZcashTxInputDescription as v, type ZcashTxOutputDescription as w, type ZcashWarning as x, blockchairTime as y, createZcashHistory as z };
|
package/dist/history.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/history.ts","../src/blockchair.ts","../src/encoding.ts","../src/http.ts","../src/types.ts"],"sourcesContent":["/**\n * Activity history for Zcash transparent addresses: a `HistorySource` over\n * Blockchair's address dashboard (transaction hashes, newest first) and\n * transaction dashboards (inputs / outputs with addresses and values, fetched\n * ten at a time). Shielded legs of a transaction show up only as the\n * transparent value that entered or left it.\n */\nimport type { ChainTransfer, ChainTx, HistoryPage, HistoryQuery, HistorySource } from '@anywalletkit/core'\nimport { BlockchairClient, blockchairTime, type BlockchairTxDashboard } from './blockchair.js'\nimport { DEFAULT_TIMEOUT_MS } from './http.js'\nimport { CAIP2 } from './types.js'\n\n/** Options for {@link createZcashHistory}. */\nexport interface ZcashHistoryOptions {\n /** Blockchair base (`https://api.blockchair.com/zcash`); optional API key. */\n blockchairUrl?: string\n key?: string\n fetch?: typeof fetch\n timeoutMs?: number\n /** Rows per page (max 100). Default: the query limit, capped at 100. */\n pageSize?: number\n}\n\nexport interface ZcashHistoryRaw {\n tx: BlockchairTxDashboard\n ownIn: bigint\n ownOut: bigint\n}\n\nexport interface ZcashChainTx extends ChainTx { raw: ZcashHistoryRaw }\n\nexport interface ZcashHistoryPage extends HistoryPage {\n items: ZcashChainTx[]\n offset: number\n total?: number\n}\n\n/** Zcash transparent-address history from Blockchair. Build it with {@link createZcashHistory}. */\nexport interface ZcashHistorySource extends HistorySource {\n listActivity(address: string, query?: HistoryQuery): Promise<ZcashHistoryPage>\n getTransaction(hash: string, address: string): Promise<ZcashChainTx | undefined>\n}\n\n/** The history backend failed. */\nexport class HistoryUnavailableError extends Error {\n readonly chain: string\n readonly reason: string\n constructor(chain: string, reason: string) {\n super(`History unavailable for ${chain}: ${reason}`)\n this.name = 'HistoryUnavailableError'\n this.chain = chain\n this.reason = reason\n }\n}\n\nconst DEFAULT_LIMIT = 25\nconst MAX_PAGE_SIZE = 100\n\nexport interface ZcashHistoryCursor { v: 1; o: number; s: number }\n\nexport function encodeCursor(c: ZcashHistoryCursor): string {\n return `${c.v}:${c.o}:${c.s}`\n}\n\nexport function decodeCursor(s: string): ZcashHistoryCursor {\n const m = /^1:(\\d+):(\\d+)$/.exec(s)\n if (!m) throw new Error('@anywalletkit/wallet-zcash: malformed history cursor')\n const o = Number(m[1]), size = Number(m[2])\n if (size < 1) throw new Error('@anywalletkit/wallet-zcash: malformed history cursor')\n return { v: 1, o, s: size }\n}\n\nexport function mapDashboardTx(chain: string, address: string, d: BlockchairTxDashboard): ZcashChainTx {\n let ownIn = 0n, ownOut = 0n, sentToOthers = 0n\n for (const i of d.inputs) if (i.recipient === address) ownIn += BigInt(i.value)\n for (const o of d.outputs) { if (o.recipient === address) ownOut += BigInt(o.value); else sentToOthers += BigInt(o.value) }\n const firstInput = d.inputs.find((i) => i.recipient)?.recipient\n const firstOther = d.outputs.find((o) => o.recipient && o.recipient !== address)?.recipient\n const transfers: ChainTransfer[] = []\n let from: string, to: string | null, nativeValue: bigint\n if (ownIn > 0n) {\n from = address\n to = firstOther ?? address\n nativeValue = firstOther ? sentToOthers : ownOut\n if (nativeValue > 0n) transfers.push({ token: null, from: address, to, amount: nativeValue })\n } else {\n from = firstInput ?? (d.inputs.length === 0 ? 'shielded' : 'coinbase')\n to = address\n nativeValue = ownOut\n if (nativeValue > 0n) transfers.push({ token: null, from, to: address, amount: nativeValue })\n }\n const t = d.transaction as BlockchairTxDashboard['transaction'] & { confirmations?: number }\n const confirmed = t.block_id > 0\n const out: ZcashChainTx = {\n chain, hash: t.hash, time: blockchairTime(t.time) ?? 0, status: confirmed ? 'confirmed' : 'pending', address, from, to, nativeValue, transfers,\n raw: { tx: d, ownIn, ownOut },\n }\n if (typeof t.fee === 'number') out.fee = BigInt(t.fee)\n if (confirmed) out.block = BigInt(t.block_id)\n return out\n}\n\n/** Blockchair link for a transaction. */\nexport function zcashExplorerTxUrl(hash: string): string {\n return `https://blockchair.com/zcash/transaction/${hash}`\n}\n\n/**\n * A history source for transparent Zcash addresses backed by Blockchair (mainnet).\n *\n * @throws Error when no `fetch` is available.\n */\nexport function createZcashHistory(options: ZcashHistoryOptions = {}): ZcashHistorySource {\n const chain = CAIP2.mainnet\n const fetchFn = options.fetch ?? globalThis.fetch\n if (typeof fetchFn !== 'function') throw new Error('@anywalletkit/wallet-zcash: no global fetch; pass `fetch` in the options')\n const client = new BlockchairClient({ ...(options.blockchairUrl ? { url: options.blockchairUrl } : {}), ...(options.key ? { key: options.key } : {}) }, fetchFn, options.timeoutMs ?? DEFAULT_TIMEOUT_MS)\n const wrap = async <T>(run: () => Promise<T>): Promise<T> => {\n try { return await run() } catch (e) { throw new HistoryUnavailableError(chain, e instanceof Error ? e.message : String(e)) }\n }\n\n return {\n chain,\n\n async listActivity(address: string, query: HistoryQuery = {}): Promise<ZcashHistoryPage> {\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 offset = cursor?.o ?? 0\n const { hashes, total } = await wrap(() => client.listTransactions(address, pageSize, offset))\n const dashboards = hashes.length ? await wrap(() => client.getTransactionDashboards(hashes)) : new Map()\n let items = hashes.map((h) => dashboards.get(h)).filter((d): d is BlockchairTxDashboard => !!d).map((d) => mapDashboardTx(chain, address, d))\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 let more = total !== undefined ? offset + hashes.length < total : hashes.length === pageSize\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: ZcashHistoryPage = { items, offset, ...(total !== undefined ? { total } : {}) }\n if (more) page.cursor = encodeCursor({ v: 1, o: offset + hashes.length, s: pageSize })\n return page\n },\n\n async getTransaction(hash: string, address: string): Promise<ZcashChainTx | undefined> {\n const d = await wrap(() => client.getTransactionDashboard(hash))\n return d ? mapDashboardTx(chain, address, d) : undefined\n },\n\n explorerTxUrl: zcashExplorerTxUrl,\n }\n}\n","/**\n * Blockchair REST transport (`https://api.blockchair.com/zcash`): public, CORS\n * open, no key needed at wallet volumes (one request every couple of seconds;\n * a `key` lifts the quota). Mainnet only — Blockchair indexes no Zcash\n * testnet. Address dashboards carry the UTXO set (mempool included, block_id\n * -1), `raw/transaction` the hex, `push/transaction` broadcasts.\n */\nimport { NetworkError } from '@anywalletkit/core'\nimport { hexToBytes } from './encoding.js'\nimport { DEFAULT_TIMEOUT_MS, fetchWithTimeout, isInt, isRecord, refusal, refusedStatus } from './http.js'\nimport type { SpentOutput, Utxo, ZcashClient, ZcashTxInfo } from './types.js'\n\n/** Default Blockchair API root for Zcash. */\nexport const BLOCKCHAIR_URL = 'https://api.blockchair.com/zcash'\n/** Blockchair caps the `utxo` list of an address dashboard at this many rows. */\nconst UTXO_LIMIT = 1000\n\ninterface BlockchairUtxo { block_id: number; transaction_hash: string; index: number; value: number }\ninterface BlockchairAddress { balance: number; unspent_output_count?: number; transaction_count?: number }\ninterface BlockchairTxRow { block_id: number; hash: string; time?: string; fee?: number; input_count?: number; output_count?: number }\ninterface BlockchairOutput { index: number; value: number; script_hex: string; recipient?: string }\ninterface BlockchairInput extends BlockchairOutput { transaction_hash: string; spending_index?: number; spending_sequence?: number }\nexport interface BlockchairTxDashboard { transaction: BlockchairTxRow; inputs: BlockchairInput[]; outputs: BlockchairOutput[] }\ninterface Envelope<T> { data: T; context: { code: number; state?: number; error?: string } }\n\nconst isUtxo = (v: unknown): v is BlockchairUtxo => isRecord(v) && isInt(v.block_id) && typeof v.transaction_hash === 'string' && isInt(v.index) && typeof v.value === 'number'\nconst isOutput = (v: unknown): v is BlockchairOutput => isRecord(v) && isInt(v.index) && typeof v.value === 'number' && typeof v.script_hex === 'string'\nconst isDashboard = (v: unknown): v is BlockchairTxDashboard =>\n isRecord(v) && isRecord(v.transaction) && isInt(v.transaction.block_id) && typeof v.transaction.hash === 'string' && Array.isArray(v.inputs) && v.inputs.every(isOutput) && Array.isArray(v.outputs) && v.outputs.every(isOutput)\n\n/** \"2026-10-18 10:05:14\" (UTC) → unix seconds. */\nexport function blockchairTime(s: string | undefined): number | undefined {\n if (!s) return undefined\n const t = Date.parse(`${s.replace(' ', 'T')}Z`)\n return Number.isFinite(t) ? Math.floor(t / 1000) : undefined\n}\n\nexport class BlockchairClient implements ZcashClient {\n private readonly base: string\n private readonly key: string | undefined\n private readonly fetchFn: typeof fetch\n private readonly timeoutMs: number\n\n constructor(config: { url?: string; key?: string } = {}, fetchFn: typeof fetch = globalThis.fetch, timeoutMs = DEFAULT_TIMEOUT_MS) {\n this.base = (config.url ?? BLOCKCHAIR_URL).replace(/\\/+$/, '')\n this.key = config.key\n this.fetchFn = fetchFn\n this.timeoutMs = timeoutMs\n }\n\n async connect(): Promise<void> {}\n async close(): Promise<void> {}\n\n private url(path: string, query: Record<string, string> = {}): string {\n const q = new URLSearchParams(query)\n if (this.key) q.set('key', this.key)\n const s = q.toString()\n return `${this.base}/${path}${s ? `?${s}` : ''}`\n }\n\n private async request<T>(path: string, query: Record<string, string>, init: RequestInit | undefined, check: (v: unknown) => v is T): Promise<{ data: T; state: number | undefined }> {\n const url = this.url(path, query)\n const res = await fetchWithTimeout(this.fetchFn, url, init, this.timeoutMs, this.base)\n let body: unknown\n try { body = await res.json() } catch (e) {\n if (res.status === 402 || res.status === 429 || res.status === 430) throw new NetworkError(`Blockchair rate limit (${res.status})`, { provider: this.base })\n throw new NetworkError(`Blockchair returned non-JSON (${res.status}) for ${url}`, { provider: this.base, cause: e })\n }\n const env = body as Partial<Envelope<unknown>>\n const code = env.context?.code ?? res.status\n if (code === 402 || code === 429 || code === 430) throw new NetworkError(`Blockchair rate limit (${code})`, { provider: this.base })\n if (code === 404) throw new NotFound()\n if (code !== 200 || !res.ok) throw new NetworkError(`Blockchair request failed: ${code} ${env.context?.error ?? res.statusText} (${url})`, { provider: this.base })\n if (!check(env.data)) throw new NetworkError(`Blockchair returned an unexpected shape for ${url}`, { provider: this.base })\n return { data: env.data, state: env.context?.state }\n }\n\n private async dashboard(address: string): Promise<{ address: BlockchairAddress; utxo: BlockchairUtxo[]; transactions: string[]; state: number | undefined }> {\n const { data, state } = await this.request(`dashboards/address/${address}`, { limit: `0,${UTXO_LIMIT}` }, undefined, (v): v is Record<string, { address: BlockchairAddress; utxo: BlockchairUtxo[]; transactions?: string[] }> =>\n isRecord(v) && Object.values(v).every((a) => isRecord(a) && isRecord(a.address) && typeof a.address.balance === 'number' && Array.isArray(a.utxo) && a.utxo.every(isUtxo)))\n const entry = data[address] ?? Object.values(data)[0]\n if (!entry) throw new NetworkError(`Blockchair knows no address ${address}`, { provider: this.base })\n return { address: entry.address, utxo: entry.utxo, transactions: entry.transactions ?? [], state }\n }\n\n /** Transaction hashes of an address, newest first, paged by offset (what the activity history walks). */\n async listTransactions(address: string, limit: number, offset: number): Promise<{ hashes: string[]; total: number | undefined }> {\n const { data } = await this.request(`dashboards/address/${address}`, { limit: `${limit},0`, offset: `${offset},0` }, undefined, (v): v is Record<string, { address: BlockchairAddress; transactions?: string[] }> =>\n isRecord(v) && Object.values(v).every((a) => isRecord(a) && isRecord(a.address) && (a.transactions === undefined || Array.isArray(a.transactions))))\n const entry = data[address] ?? Object.values(data)[0]\n if (!entry) throw new NetworkError(`Blockchair knows no address ${address}`, { provider: this.base })\n return { hashes: (entry.transactions ?? []).filter((h): h is string => typeof h === 'string'), total: entry.address.transaction_count }\n }\n\n /** Confirmed = the UTXOs mined so far; unconfirmed = incoming mempool outputs. (Beyond 1000 UTXOs the dashboard balance is used.) */\n async getBalance(address: string): Promise<{ confirmed: bigint; unconfirmed: bigint }> {\n const d = await this.dashboard(address)\n let confirmed = 0n, unconfirmed = 0n\n for (const u of d.utxo) { if (u.block_id > 0) confirmed += BigInt(u.value); else unconfirmed += BigInt(u.value) }\n if ((d.address.unspent_output_count ?? d.utxo.length) > d.utxo.length) confirmed = BigInt(d.address.balance) - unconfirmed\n return { confirmed, unconfirmed }\n }\n\n async listUnspent(address: string): Promise<Utxo[]> {\n const d = await this.dashboard(address)\n return d.utxo.map((u) => ({ txid: u.transaction_hash, vout: u.index, value: BigInt(u.value), height: u.block_id > 0 ? u.block_id : -1 }))\n }\n\n async getTransaction(txid: string): Promise<string> {\n const { data } = await this.request(`raw/transaction/${txid}`, {}, undefined, (v): v is Record<string, { raw_transaction: string }> =>\n isRecord(v) && Object.values(v).every((t) => isRecord(t) && typeof t.raw_transaction === 'string'))\n const hex = (data[txid] ?? Object.values(data)[0])?.raw_transaction\n if (!hex) throw new NetworkError(`Transaction ${txid} has no raw data`, { provider: this.base })\n return hex\n }\n\n /** Inputs / outputs with addresses, values and scripts — what the activity history and prevout lookups read. */\n async getTransactionDashboard(txid: string): Promise<BlockchairTxDashboard | undefined> {\n try {\n const { data, state } = await this.request(`dashboards/transaction/${txid}`, {}, undefined, (v): v is Record<string, BlockchairTxDashboard | null> =>\n isRecord(v) && Object.values(v).every((t) => t === null || isDashboard(t)))\n const t = data[txid] ?? Object.values(data)[0]\n if (!t) return undefined\n return { ...t, transaction: { ...t.transaction, ...(state !== undefined ? { confirmations: t.transaction.block_id > 0 ? state - t.transaction.block_id + 1 : 0 } : {}) } } as BlockchairTxDashboard\n } catch (e) {\n if (e instanceof NotFound) return undefined\n throw e\n }\n }\n\n /** Several transactions in one call (Blockchair takes up to 10 comma-separated hashes). */\n async getTransactionDashboards(txids: string[]): Promise<Map<string, BlockchairTxDashboard>> {\n const out = new Map<string, BlockchairTxDashboard>()\n for (let i = 0; i < txids.length; i += 10) {\n const slice = txids.slice(i, i + 10)\n const { data, state } = await this.request(`dashboards/transactions/${slice.join(',')}`, {}, undefined, (v): v is Record<string, BlockchairTxDashboard | null> =>\n isRecord(v) && Object.values(v).every((t) => t === null || isDashboard(t)))\n for (const [hash, t] of Object.entries(data)) {\n if (!t) continue\n const confirmations = state !== undefined && t.transaction.block_id > 0 ? state - t.transaction.block_id + 1 : 0\n out.set(hash, { ...t, transaction: { ...t.transaction, confirmations } } as BlockchairTxDashboard)\n }\n }\n return out\n }\n\n async getOutput(txid: string, vout: number): Promise<SpentOutput | undefined> {\n const d = await this.getTransactionDashboard(txid)\n const o = d?.outputs.find((x) => x.index === vout)\n return o ? { value: BigInt(o.value), script: hexToBytes(o.script_hex) } : undefined\n }\n\n async getTransactionInfo(txid: string): Promise<ZcashTxInfo | undefined> {\n const d = await this.getTransactionDashboard(txid)\n if (!d) return undefined\n const t = d.transaction as BlockchairTxRow & { confirmations?: number }\n const info: ZcashTxInfo = { txid: t.hash, blockHeight: t.block_id > 0 ? t.block_id : -1, confirmations: t.confirmations ?? 0 }\n if (typeof t.fee === 'number') info.fee = BigInt(t.fee)\n const time = blockchairTime(t.time)\n if (time !== undefined) info.blockTime = time\n return info\n }\n\n async broadcast(rawTx: string): Promise<string> {\n const body = `data=${encodeURIComponent(rawTx)}`\n const url = this.url('push/transaction')\n const res = await fetchWithTimeout(this.fetchFn, url, { method: 'POST', headers: { 'content-type': 'application/x-www-form-urlencoded' }, body }, this.timeoutMs, this.base)\n let env: Partial<Envelope<{ transaction_hash?: string } | null>> = {}\n let parsed = false\n try { env = (await res.json()) as typeof env; parsed = true } catch { /* handled below */ }\n const hash = env.data?.transaction_hash\n if (hash) return hash\n const reason = env.context?.error\n // The node's verdict — an error it gave, with a 4xx (not 408) or a 200 — is a refusal: nothing was\n // taken. A proxy's HTML 502, a 5xx, a timeout or an unreadable body may have been (round 3, M12).\n if (parsed && reason && (res.ok || refusedStatus(res.status))) throw refusal(new Error(`Broadcast rejected: ${reason}`))\n throw new NetworkError(`Blockchair broadcast: no answer to rely on (${res.status} ${res.statusText})`, { provider: this.base })\n }\n\n async getBlockHeight(): Promise<number> {\n const { data } = await this.request('stats', {}, undefined, (v): v is { best_block_height: number } => isRecord(v) && isInt(v.best_block_height))\n if (data.best_block_height <= 0) throw new NetworkError('Blockchair reported no block height', { provider: this.base })\n return data.best_block_height\n }\n}\n\nclass NotFound extends Error { constructor() { super('not found'); this.name = 'NotFound' } }\n","/** Byte helpers for the Zcash wire format (little-endian integers, Bitcoin CompactSize). */\nexport { bytesToHex, hexToBytes, concatBytes, utf8ToBytes } from '@noble/hashes/utils.js'\n\nexport function compactSize(n: number): Uint8Array {\n if (!Number.isInteger(n) || n < 0) throw new Error(`CompactSize: ${n} is not a non-negative integer`)\n if (n < 0xfd) return Uint8Array.of(n)\n if (n <= 0xffff) return Uint8Array.of(0xfd, n & 0xff, n >>> 8)\n if (n <= 0xffffffff) return Uint8Array.of(0xfe, n & 0xff, (n >>> 8) & 0xff, (n >>> 16) & 0xff, n >>> 24)\n throw new Error('CompactSize: value too large')\n}\n\nexport function u32le(n: number): Uint8Array {\n if (!Number.isInteger(n) || n < 0 || n > 0xffffffff) throw new Error(`u32: ${n} out of range`)\n return Uint8Array.of(n & 0xff, (n >>> 8) & 0xff, (n >>> 16) & 0xff, n >>> 24)\n}\n\n/** Signed 64-bit little-endian (two's complement). Amounts are never negative here, but ZIP-244 types the field as signed. */\nexport function i64le(v: bigint): Uint8Array {\n if (v < -(1n << 63n) || v >= 1n << 63n) throw new Error(`i64: ${v} out of range`)\n let x = v < 0n ? v + (1n << 64n) : v\n const out = new Uint8Array(8)\n for (let i = 0; i < 8; i++) { out[i] = Number(x & 0xffn); x >>= 8n }\n return out\n}\n\nexport class Writer {\n private readonly parts: Uint8Array[] = []\n u8(n: number): this { this.parts.push(Uint8Array.of(n & 0xff)); return this }\n u32(n: number): this { this.parts.push(u32le(n)); return this }\n i64(v: bigint): this { this.parts.push(i64le(v)); return this }\n bytes(b: Uint8Array): this { this.parts.push(b); return this }\n compact(n: number): this { this.parts.push(compactSize(n)); return this }\n /** CompactSize length prefix + bytes (the \"field encoding\" of a script). */\n varBytes(b: Uint8Array): this { return this.compact(b.length).bytes(b) }\n finish(): Uint8Array {\n const len = this.parts.reduce((s, p) => s + p.length, 0)\n const out = new Uint8Array(len)\n let o = 0\n for (const p of this.parts) { out.set(p, o); o += p.length }\n return out\n }\n}\n\nexport class Reader {\n offset = 0\n constructor(private readonly buf: Uint8Array) {}\n get remaining(): number { return this.buf.length - this.offset }\n private need(n: number): void {\n if (this.offset + n > this.buf.length) throw new Error('Transaction truncated')\n }\n u8(): number { this.need(1); return this.buf[this.offset++]! }\n u32(): number {\n this.need(4)\n const b = this.buf\n const o = this.offset\n this.offset += 4\n return (b[o]! | (b[o + 1]! << 8) | (b[o + 2]! << 16)) + b[o + 3]! * 0x1000000\n }\n i64(): bigint {\n this.need(8)\n let v = 0n\n for (let i = 7; i >= 0; i--) v = (v << 8n) | BigInt(this.buf[this.offset + i]!)\n this.offset += 8\n return v >= 1n << 63n ? v - (1n << 64n) : v\n }\n bytes(n: number): Uint8Array { this.need(n); const out = this.buf.slice(this.offset, this.offset + n); this.offset += n; return out }\n compact(): number {\n const first = this.u8()\n if (first < 0xfd) return first\n if (first === 0xfd) { this.need(2); const v = this.buf[this.offset]! | (this.buf[this.offset + 1]! << 8); this.offset += 2; return v }\n if (first === 0xfe) return this.u32()\n throw new Error('CompactSize: 64-bit lengths are not supported')\n }\n varBytes(): Uint8Array { return this.bytes(this.compact()) }\n}\n\n/** Display ↔ internal byte order of a 32-byte hash (Bitcoin convention: hex is shown reversed). */\nexport function reverseBytes(b: Uint8Array): Uint8Array {\n return Uint8Array.from(b).reverse()\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\n/** An HTTP status that is the server refusing the request itself: 4xx, but not 408 (request timeout). */\nexport const refusedStatus = (status: number): boolean => status >= 400 && status < 500 && status !== 408\n\n/** Mark an error as a node's answer refusing the request: nothing was taken (round 3, M12). */\nexport function refusal<E extends Error>(e: E): E {\n return Object.assign(e, { answered: true })\n}\n\n/**\n * An endpoint answered with a refusal (HTTP 4xx other than 408 with a reason, or an error body):\n * nothing was taken. A thrown fetch, a timeout, a 5xx or a body that cannot be read may have been.\n */\nexport function isAnsweredRefusal(e: unknown): boolean {\n return (e as { answered?: unknown } | null)?.answered === true\n}\n\n/** The node says it already holds the transaction (an earlier attempt delivered it): it is out, not refused. */\nexport function isAlreadyKnown(e: unknown): boolean {\n for (let x: unknown = e, depth = 0; x instanceof Error && depth < 5; x = x.cause, depth++) {\n if (/txn-already-(in-mempool|known)|already (known|in (the )?(mempool|block ?chain))/i.test(x.message)) return true\n }\n return false\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)\nexport const isInt = (v: unknown): v is number => typeof v === 'number' && Number.isInteger(v)\n","/** Zcash mainnet or testnet. */\nexport type ZcashNetwork = 'mainnet' | 'testnet'\n\n/** CAIP-2 ids the SDK uses for Zcash (the swap2 catalog already names `zcash:mainnet`). */\nexport const CAIP2: Record<ZcashNetwork, string> = { mainnet: 'zcash:mainnet', testnet: 'zcash:testnet' }\n\n/** An unspent transparent output the account can spend. */\nexport interface Utxo {\n txid: string\n vout: number\n /** Zatoshis. */\n value: bigint\n /** Block height; -1 while in the mempool. */\n height: number\n}\n\n/** A previous output a transaction spends — ZIP-244 signs its value AND script. */\nexport interface SpentOutput {\n value: bigint\n script: Uint8Array\n}\n\n/** Transport-neutral transaction record (receipts, confirmations). */\nexport interface ZcashTxInfo {\n txid: string\n /** -1 or 0 while unconfirmed. */\n blockHeight: number\n confirmations: number\n fee?: bigint\n /** Unix seconds. */\n blockTime?: number\n}\n\n/** Minimal chain-data client every transport implements. Values in zatoshis. */\nexport interface ZcashClient {\n connect(): Promise<void>\n close(): Promise<void>\n getBalance(address: string): Promise<{ confirmed: bigint; unconfirmed: bigint }>\n listUnspent(address: string): Promise<Utxo[]>\n /** Raw transaction hex (any version — only used to read prevouts and for receipts). */\n getTransaction(txid: string): Promise<string>\n /** Value + scriptPubKey of one output of an existing transaction (what signing a spend of it needs). */\n getOutput(txid: string, vout: number): Promise<SpentOutput | undefined>\n getTransactionInfo(txid: string): Promise<ZcashTxInfo | undefined>\n /** Broadcast raw hex; returns the txid. */\n broadcast(rawTx: string): Promise<string>\n /** Current chain tip height (expiry height, anti-fee-sniping lock time, consensus branch selection). */\n getBlockHeight(): Promise<number>\n}\n\n/** One transport to a Zcash indexer: Blockchair or a Blockbook instance. */\nexport type ZcashClientConfig =\n /** Blockchair's public REST API (`https://api.blockchair.com/zcash`; optional API key). Mainnet only. */\n | { type: 'blockchair'; clientConfig?: { url?: string; key?: string } }\n /** A Zcash Blockbook (NOWNodes `https://zec-blockbook.nownodes.io` with an `api-key` header, a self-hosted instance, …). */\n | { type: 'blockbook-http'; clientConfig: { url: string; headers?: Record<string, string> } }\n\n/**\n * Options for a Zcash wallet manager or account: transports, network and fee limits. Transparent\n * addresses only.\n */\nexport interface ZcashConfig {\n /** One or more transports (config objects or ready `ZcashClient`s). A list fails over in order. Omit for an offline (sign-only) wallet. */\n client?: ZcashClientConfig | ZcashClient | Array<ZcashClientConfig | ZcashClient>\n network?: ZcashNetwork\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 (zatoshis) for `transfer`. */\n transferMaxFee?: bigint | number\n /** Max fee (zatoshis) for `sendTransaction` / `signTransaction`. */\n transactionMaxFee?: bigint | number\n /** Hard fee ceiling in zatoshis for any transaction this account signs or broadcasts (default 1 000 000 = 0.01 ZEC). */\n maxFee?: bigint | number\n /** Blocks after the next block (tip + 1) at which an unmined transaction expires (ZIP-203; default 40, the zcashd/Zebra default). 0 = never. */\n expiryDelta?: number\n /** Set nLockTime to the tip height so the transaction cannot be mined into a reorged block (default true). */\n antiFeeSniping?: boolean\n /**\n * Consensus branch id to sign under. Default on mainnet: the one in force at\n * tip + 1 (`branchIdForHeight`) — set this when a network upgrade activates\n * before the package learns its id. Required on testnet and regtest, whose\n * upgrades activate at other heights.\n */\n consensusBranchId?: number\n /** Coin-selection input cap (default 200). */\n maxInputs?: number\n /** Injectable fetch (tests, custom agents). Defaults to globalThis.fetch. */\n fetch?: typeof fetch\n}\n\n/** A spend. `value` in zatoshis. `fee` overrides the ZIP-317 conventional fee (still subject to `maxFee`). */\nexport interface ZcashSpend {\n to: string\n value: bigint | number | string\n fee?: bigint | number\n}\n\n/** `sendTransaction` accepts a spend or an already signed raw transaction hex. */\nexport type ZcashTransaction = ZcashSpend | string\n\n/** A transparent ZEC transfer. Amount in zatoshis. */\nexport interface ZcashTransferOptions {\n /** Not supported on Zcash; present for the shared account interface. */\n token?: string\n recipient: string\n amount: bigint | number | string\n}\n\n/** A mined Zcash transaction. */\nexport interface ZcashReceipt {\n hash: string\n /** Always 1 once mined — a transparent transaction cannot fail after inclusion. */\n status: 1\n blockNumber: bigint\n confirmations: number\n fee?: bigint\n}\n\n/** The most one transaction can send (a sweep of every UTXO), after the fee. */\nexport interface ZcashMaxSpendableResult {\n /** Max zatoshis 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: number\n}\n\n/** Problems a described transaction is flagged with. */\nexport type ZcashWarning =\n /** Fee exceeds 10 % of the amount sent. */\n | 'fee-over-10pct-of-amount'\n /** Fee is below the ZIP-317 conventional fee — nodes may not relay it. */\n | 'fee-below-conventional'\n /** An output is below the dust floor. */\n | 'dust-output'\n /** Change was below dust and folded into the fee. */\n | 'no-change'\n /** No expiry height: the transaction stays valid in mempools indefinitely. */\n | 'no-expiry'\n\n/** One input of a described transaction: the UTXO it spends. */\nexport interface ZcashTxInputDescription {\n txid: string\n vout: number\n value: bigint\n address: string | undefined\n}\n\n/** One output of a described transaction, tagged as the recipient, our change, or unknown. */\nexport interface ZcashTxOutputDescription {\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 ZcashTxDescription {\n kind: 'zcash-transfer'\n version: 5\n consensusBranchId: number\n inputs: ZcashTxInputDescription[]\n outputs: ZcashTxOutputDescription[]\n /** Zatoshis sent to non-change outputs. */\n amount: bigint\n fee: bigint\n /** The ZIP-317 fee this transaction's shape calls for. */\n conventionalFee: bigint\n /** Serialized size in bytes. */\n size: number\n lockTime: number\n expiryHeight: number\n /** Present once the transaction is signed. */\n txid?: string\n warnings: ZcashWarning[]\n}\n"],"mappings":"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","names":["import_core","t"]}
|
|
1
|
+
{"version":3,"sources":["../src/history.ts","../src/blockchair.ts","../src/encoding.ts","../src/http.ts","../src/types.ts"],"sourcesContent":["/**\n * Activity history for Zcash transparent addresses: a `HistorySource` over\n * Blockchair's address dashboard (transaction hashes, newest first) and\n * transaction dashboards (inputs / outputs with addresses and values, fetched\n * ten at a time). Shielded legs of a transaction show up only as the\n * transparent value that entered or left it.\n */\nimport type { ChainTransfer, ChainTx, HistoryPage, HistoryQuery, HistorySource } from '@anywalletkit/core'\nimport { BlockchairClient, blockchairTime, type BlockchairTxDashboard } from './blockchair.js'\nimport { DEFAULT_TIMEOUT_MS } from './http.js'\nimport { CAIP2 } from './types.js'\n\n/** Options for {@link createZcashHistory}. */\nexport interface ZcashHistoryOptions {\n /** Blockchair base (`https://api.blockchair.com/zcash`); optional API key. */\n blockchairUrl?: string\n key?: string\n fetch?: typeof fetch\n timeoutMs?: number\n /** Rows per page (max 100). Default: the query limit, capped at 100. */\n pageSize?: number\n}\n\nexport interface ZcashHistoryRaw {\n tx: BlockchairTxDashboard\n ownIn: bigint\n ownOut: bigint\n}\n\nexport interface ZcashChainTx extends ChainTx { raw: ZcashHistoryRaw }\n\nexport interface ZcashHistoryPage extends HistoryPage {\n items: ZcashChainTx[]\n offset: number\n total?: number\n}\n\n/** Zcash transparent-address history from Blockchair. Build it with {@link createZcashHistory}. */\nexport interface ZcashHistorySource extends HistorySource {\n listActivity(address: string, query?: HistoryQuery): Promise<ZcashHistoryPage>\n getTransaction(hash: string, address: string): Promise<ZcashChainTx | undefined>\n}\n\n/** The history backend failed. */\nexport class HistoryUnavailableError extends Error {\n readonly chain: string\n readonly reason: string\n constructor(chain: string, reason: string) {\n super(`History unavailable for ${chain}: ${reason}`)\n this.name = 'HistoryUnavailableError'\n this.chain = chain\n this.reason = reason\n }\n}\n\nconst DEFAULT_LIMIT = 25\nconst MAX_PAGE_SIZE = 100\n\nexport interface ZcashHistoryCursor { v: 1; o: number; s: number }\n\nexport function encodeCursor(c: ZcashHistoryCursor): string {\n return `${c.v}:${c.o}:${c.s}`\n}\n\nexport function decodeCursor(s: string): ZcashHistoryCursor {\n const m = /^1:(\\d+):(\\d+)$/.exec(s)\n if (!m) throw new Error('@anywalletkit/wallet-zcash: malformed history cursor')\n const o = Number(m[1]), size = Number(m[2])\n if (size < 1) throw new Error('@anywalletkit/wallet-zcash: malformed history cursor')\n return { v: 1, o, s: size }\n}\n\nexport function mapDashboardTx(chain: string, address: string, d: BlockchairTxDashboard): ZcashChainTx {\n let ownIn = 0n, ownOut = 0n, sentToOthers = 0n\n for (const i of d.inputs) if (i.recipient === address) ownIn += BigInt(i.value)\n for (const o of d.outputs) { if (o.recipient === address) ownOut += BigInt(o.value); else sentToOthers += BigInt(o.value) }\n const firstInput = d.inputs.find((i) => i.recipient)?.recipient\n const firstOther = d.outputs.find((o) => o.recipient && o.recipient !== address)?.recipient\n const transfers: ChainTransfer[] = []\n let from: string, to: string | null, nativeValue: bigint\n if (ownIn > 0n) {\n from = address\n to = firstOther ?? address\n nativeValue = firstOther ? sentToOthers : ownOut\n if (nativeValue > 0n) transfers.push({ token: null, from: address, to, amount: nativeValue })\n } else {\n from = firstInput ?? (d.inputs.length === 0 ? 'shielded' : 'coinbase')\n to = address\n nativeValue = ownOut\n if (nativeValue > 0n) transfers.push({ token: null, from, to: address, amount: nativeValue })\n }\n const t = d.transaction as BlockchairTxDashboard['transaction'] & { confirmations?: number }\n const confirmed = t.block_id > 0\n const out: ZcashChainTx = {\n chain, hash: t.hash, time: blockchairTime(t.time) ?? 0, status: confirmed ? 'confirmed' : 'pending', address, from, to, nativeValue, transfers,\n raw: { tx: d, ownIn, ownOut },\n }\n if (typeof t.fee === 'number') out.fee = BigInt(t.fee)\n if (confirmed) out.block = BigInt(t.block_id)\n return out\n}\n\n/** Blockchair link for a transaction. */\nexport function zcashExplorerTxUrl(hash: string): string {\n return `https://blockchair.com/zcash/transaction/${hash}`\n}\n\n/**\n * A history source for transparent Zcash addresses backed by Blockchair (mainnet).\n *\n * @throws Error when no `fetch` is available.\n */\nexport function createZcashHistory(options: ZcashHistoryOptions = {}): ZcashHistorySource {\n const chain = CAIP2.mainnet\n const fetchFn = options.fetch ?? globalThis.fetch\n if (typeof fetchFn !== 'function') throw new Error('@anywalletkit/wallet-zcash: no global fetch; pass `fetch` in the options')\n const client = new BlockchairClient({ ...(options.blockchairUrl ? { url: options.blockchairUrl } : {}), ...(options.key ? { key: options.key } : {}) }, fetchFn, options.timeoutMs ?? DEFAULT_TIMEOUT_MS)\n const wrap = async <T>(run: () => Promise<T>): Promise<T> => {\n try { return await run() } catch (e) { throw new HistoryUnavailableError(chain, e instanceof Error ? e.message : String(e)) }\n }\n\n return {\n chain,\n\n async listActivity(address: string, query: HistoryQuery = {}): Promise<ZcashHistoryPage> {\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 offset = cursor?.o ?? 0\n const { hashes, total } = await wrap(() => client.listTransactions(address, pageSize, offset))\n const dashboards = hashes.length ? await wrap(() => client.getTransactionDashboards(hashes)) : new Map()\n let items = hashes.map((h) => dashboards.get(h)).filter((d): d is BlockchairTxDashboard => !!d).map((d) => mapDashboardTx(chain, address, d))\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 let more = total !== undefined ? offset + hashes.length < total : hashes.length === pageSize\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: ZcashHistoryPage = { items, offset, ...(total !== undefined ? { total } : {}) }\n if (more) page.cursor = encodeCursor({ v: 1, o: offset + hashes.length, s: pageSize })\n return page\n },\n\n async getTransaction(hash: string, address: string): Promise<ZcashChainTx | undefined> {\n const d = await wrap(() => client.getTransactionDashboard(hash))\n return d ? mapDashboardTx(chain, address, d) : undefined\n },\n\n explorerTxUrl: zcashExplorerTxUrl,\n }\n}\n","/**\n * Blockchair REST transport (`https://api.blockchair.com/zcash`): public, CORS\n * open, no key needed at wallet volumes (one request every couple of seconds;\n * a `key` lifts the quota). Mainnet only — Blockchair indexes no Zcash\n * testnet. Address dashboards carry the UTXO set (mempool included, block_id\n * -1), `raw/transaction` the hex, `push/transaction` broadcasts.\n */\nimport { NetworkError } from '@anywalletkit/core'\nimport { hexToBytes } from './encoding.js'\nimport { DEFAULT_TIMEOUT_MS, fetchWithTimeout, isInt, isRecord, refusal, refusedStatus } from './http.js'\nimport type { SpentOutput, Utxo, ZcashClient, ZcashTxInfo } from './types.js'\n\n/** Default Blockchair API root for Zcash. */\nexport const BLOCKCHAIR_URL = 'https://api.blockchair.com/zcash'\n/** Blockchair caps the `utxo` list of an address dashboard at this many rows. */\nconst UTXO_LIMIT = 1000\n\ninterface BlockchairUtxo { block_id: number; transaction_hash: string; index: number; value: number }\ninterface BlockchairAddress { balance: number; unspent_output_count?: number; transaction_count?: number }\nexport interface BlockchairTxRow { block_id: number; hash: string; time?: string; fee?: number; input_count?: number; output_count?: number }\nexport interface BlockchairOutput { index: number; value: number; script_hex: string; recipient?: string }\nexport interface BlockchairInput extends BlockchairOutput { transaction_hash: string; spending_index?: number; spending_sequence?: number }\nexport interface BlockchairTxDashboard { transaction: BlockchairTxRow; inputs: BlockchairInput[]; outputs: BlockchairOutput[] }\ninterface Envelope<T> { data: T; context: { code: number; state?: number; error?: string } }\n\nconst isUtxo = (v: unknown): v is BlockchairUtxo => isRecord(v) && isInt(v.block_id) && typeof v.transaction_hash === 'string' && isInt(v.index) && typeof v.value === 'number'\nconst isOutput = (v: unknown): v is BlockchairOutput => isRecord(v) && isInt(v.index) && typeof v.value === 'number' && typeof v.script_hex === 'string'\nconst isDashboard = (v: unknown): v is BlockchairTxDashboard =>\n isRecord(v) && isRecord(v.transaction) && isInt(v.transaction.block_id) && typeof v.transaction.hash === 'string' && Array.isArray(v.inputs) && v.inputs.every(isOutput) && Array.isArray(v.outputs) && v.outputs.every(isOutput)\n\n/** \"2026-10-18 10:05:14\" (UTC) → unix seconds. */\nexport function blockchairTime(s: string | undefined): number | undefined {\n if (!s) return undefined\n const t = Date.parse(`${s.replace(' ', 'T')}Z`)\n return Number.isFinite(t) ? Math.floor(t / 1000) : undefined\n}\n\nexport class BlockchairClient implements ZcashClient {\n private readonly base: string\n private readonly key: string | undefined\n private readonly fetchFn: typeof fetch\n private readonly timeoutMs: number\n\n constructor(config: { url?: string; key?: string } = {}, fetchFn: typeof fetch = globalThis.fetch, timeoutMs = DEFAULT_TIMEOUT_MS) {\n this.base = (config.url ?? BLOCKCHAIR_URL).replace(/\\/+$/, '')\n this.key = config.key\n this.fetchFn = fetchFn\n this.timeoutMs = timeoutMs\n }\n\n async connect(): Promise<void> {}\n async close(): Promise<void> {}\n\n private url(path: string, query: Record<string, string> = {}): string {\n const q = new URLSearchParams(query)\n if (this.key) q.set('key', this.key)\n const s = q.toString()\n return `${this.base}/${path}${s ? `?${s}` : ''}`\n }\n\n private async request<T>(path: string, query: Record<string, string>, init: RequestInit | undefined, check: (v: unknown) => v is T): Promise<{ data: T; state: number | undefined }> {\n const url = this.url(path, query)\n const res = await fetchWithTimeout(this.fetchFn, url, init, this.timeoutMs, this.base)\n let body: unknown\n try { body = await res.json() } catch (e) {\n if (res.status === 402 || res.status === 429 || res.status === 430) throw new NetworkError(`Blockchair rate limit (${res.status})`, { provider: this.base })\n throw new NetworkError(`Blockchair returned non-JSON (${res.status}) for ${url}`, { provider: this.base, cause: e })\n }\n const env = body as Partial<Envelope<unknown>>\n const code = env.context?.code ?? res.status\n if (code === 402 || code === 429 || code === 430) throw new NetworkError(`Blockchair rate limit (${code})`, { provider: this.base })\n if (code === 404) throw new NotFound()\n if (code !== 200 || !res.ok) throw new NetworkError(`Blockchair request failed: ${code} ${env.context?.error ?? res.statusText} (${url})`, { provider: this.base })\n if (!check(env.data)) throw new NetworkError(`Blockchair returned an unexpected shape for ${url}`, { provider: this.base })\n return { data: env.data, state: env.context?.state }\n }\n\n private async dashboard(address: string): Promise<{ address: BlockchairAddress; utxo: BlockchairUtxo[]; transactions: string[]; state: number | undefined }> {\n const { data, state } = await this.request(`dashboards/address/${address}`, { limit: `0,${UTXO_LIMIT}` }, undefined, (v): v is Record<string, { address: BlockchairAddress; utxo: BlockchairUtxo[]; transactions?: string[] }> =>\n isRecord(v) && Object.values(v).every((a) => isRecord(a) && isRecord(a.address) && typeof a.address.balance === 'number' && Array.isArray(a.utxo) && a.utxo.every(isUtxo)))\n const entry = data[address] ?? Object.values(data)[0]\n if (!entry) throw new NetworkError(`Blockchair knows no address ${address}`, { provider: this.base })\n return { address: entry.address, utxo: entry.utxo, transactions: entry.transactions ?? [], state }\n }\n\n /** Transaction hashes of an address, newest first, paged by offset (what the activity history walks). */\n async listTransactions(address: string, limit: number, offset: number): Promise<{ hashes: string[]; total: number | undefined }> {\n const { data } = await this.request(`dashboards/address/${address}`, { limit: `${limit},0`, offset: `${offset},0` }, undefined, (v): v is Record<string, { address: BlockchairAddress; transactions?: string[] }> =>\n isRecord(v) && Object.values(v).every((a) => isRecord(a) && isRecord(a.address) && (a.transactions === undefined || Array.isArray(a.transactions))))\n const entry = data[address] ?? Object.values(data)[0]\n if (!entry) throw new NetworkError(`Blockchair knows no address ${address}`, { provider: this.base })\n return { hashes: (entry.transactions ?? []).filter((h): h is string => typeof h === 'string'), total: entry.address.transaction_count }\n }\n\n /** Confirmed = the UTXOs mined so far; unconfirmed = incoming mempool outputs. (Beyond 1000 UTXOs the dashboard balance is used.) */\n async getBalance(address: string): Promise<{ confirmed: bigint; unconfirmed: bigint }> {\n const d = await this.dashboard(address)\n let confirmed = 0n, unconfirmed = 0n\n for (const u of d.utxo) { if (u.block_id > 0) confirmed += BigInt(u.value); else unconfirmed += BigInt(u.value) }\n if ((d.address.unspent_output_count ?? d.utxo.length) > d.utxo.length) confirmed = BigInt(d.address.balance) - unconfirmed\n return { confirmed, unconfirmed }\n }\n\n async listUnspent(address: string): Promise<Utxo[]> {\n const d = await this.dashboard(address)\n return d.utxo.map((u) => ({ txid: u.transaction_hash, vout: u.index, value: BigInt(u.value), height: u.block_id > 0 ? u.block_id : -1 }))\n }\n\n async getTransaction(txid: string): Promise<string> {\n const { data } = await this.request(`raw/transaction/${txid}`, {}, undefined, (v): v is Record<string, { raw_transaction: string }> =>\n isRecord(v) && Object.values(v).every((t) => isRecord(t) && typeof t.raw_transaction === 'string'))\n const hex = (data[txid] ?? Object.values(data)[0])?.raw_transaction\n if (!hex) throw new NetworkError(`Transaction ${txid} has no raw data`, { provider: this.base })\n return hex\n }\n\n /** Inputs / outputs with addresses, values and scripts — what the activity history and prevout lookups read. */\n async getTransactionDashboard(txid: string): Promise<BlockchairTxDashboard | undefined> {\n try {\n const { data, state } = await this.request(`dashboards/transaction/${txid}`, {}, undefined, (v): v is Record<string, BlockchairTxDashboard | null> =>\n isRecord(v) && Object.values(v).every((t) => t === null || isDashboard(t)))\n const t = data[txid] ?? Object.values(data)[0]\n if (!t) return undefined\n return { ...t, transaction: { ...t.transaction, ...(state !== undefined ? { confirmations: t.transaction.block_id > 0 ? state - t.transaction.block_id + 1 : 0 } : {}) } } as BlockchairTxDashboard\n } catch (e) {\n if (e instanceof NotFound) return undefined\n throw e\n }\n }\n\n /** Several transactions in one call (Blockchair takes up to 10 comma-separated hashes). */\n async getTransactionDashboards(txids: string[]): Promise<Map<string, BlockchairTxDashboard>> {\n const out = new Map<string, BlockchairTxDashboard>()\n for (let i = 0; i < txids.length; i += 10) {\n const slice = txids.slice(i, i + 10)\n const { data, state } = await this.request(`dashboards/transactions/${slice.join(',')}`, {}, undefined, (v): v is Record<string, BlockchairTxDashboard | null> =>\n isRecord(v) && Object.values(v).every((t) => t === null || isDashboard(t)))\n for (const [hash, t] of Object.entries(data)) {\n if (!t) continue\n const confirmations = state !== undefined && t.transaction.block_id > 0 ? state - t.transaction.block_id + 1 : 0\n out.set(hash, { ...t, transaction: { ...t.transaction, confirmations } } as BlockchairTxDashboard)\n }\n }\n return out\n }\n\n async getOutput(txid: string, vout: number): Promise<SpentOutput | undefined> {\n const d = await this.getTransactionDashboard(txid)\n const o = d?.outputs.find((x) => x.index === vout)\n return o ? { value: BigInt(o.value), script: hexToBytes(o.script_hex) } : undefined\n }\n\n async getTransactionInfo(txid: string): Promise<ZcashTxInfo | undefined> {\n const d = await this.getTransactionDashboard(txid)\n if (!d) return undefined\n const t = d.transaction as BlockchairTxRow & { confirmations?: number }\n const info: ZcashTxInfo = { txid: t.hash, blockHeight: t.block_id > 0 ? t.block_id : -1, confirmations: t.confirmations ?? 0 }\n if (typeof t.fee === 'number') info.fee = BigInt(t.fee)\n const time = blockchairTime(t.time)\n if (time !== undefined) info.blockTime = time\n return info\n }\n\n async broadcast(rawTx: string): Promise<string> {\n const body = `data=${encodeURIComponent(rawTx)}`\n const url = this.url('push/transaction')\n const res = await fetchWithTimeout(this.fetchFn, url, { method: 'POST', headers: { 'content-type': 'application/x-www-form-urlencoded' }, body }, this.timeoutMs, this.base)\n let env: Partial<Envelope<{ transaction_hash?: string } | null>> = {}\n let parsed = false\n try { env = (await res.json()) as typeof env; parsed = true } catch { /* handled below */ }\n const hash = env.data?.transaction_hash\n if (hash) return hash\n const reason = env.context?.error\n // The node's verdict — an error it gave, with a 4xx (not 408) or a 200 — is a refusal: nothing was\n // taken. A proxy's HTML 502, a 5xx, a timeout or an unreadable body may have been (round 3, M12).\n if (parsed && reason && (res.ok || refusedStatus(res.status))) throw refusal(new Error(`Broadcast rejected: ${reason}`))\n throw new NetworkError(`Blockchair broadcast: no answer to rely on (${res.status} ${res.statusText})`, { provider: this.base })\n }\n\n async getBlockHeight(): Promise<number> {\n const { data } = await this.request('stats', {}, undefined, (v): v is { best_block_height: number } => isRecord(v) && isInt(v.best_block_height))\n if (data.best_block_height <= 0) throw new NetworkError('Blockchair reported no block height', { provider: this.base })\n return data.best_block_height\n }\n}\n\nclass NotFound extends Error { constructor() { super('not found'); this.name = 'NotFound' } }\n","/** Byte helpers for the Zcash wire format (little-endian integers, Bitcoin CompactSize). */\nexport { bytesToHex, hexToBytes, concatBytes, utf8ToBytes } from '@noble/hashes/utils.js'\n\nexport function compactSize(n: number): Uint8Array {\n if (!Number.isInteger(n) || n < 0) throw new Error(`CompactSize: ${n} is not a non-negative integer`)\n if (n < 0xfd) return Uint8Array.of(n)\n if (n <= 0xffff) return Uint8Array.of(0xfd, n & 0xff, n >>> 8)\n if (n <= 0xffffffff) return Uint8Array.of(0xfe, n & 0xff, (n >>> 8) & 0xff, (n >>> 16) & 0xff, n >>> 24)\n throw new Error('CompactSize: value too large')\n}\n\nexport function u32le(n: number): Uint8Array {\n if (!Number.isInteger(n) || n < 0 || n > 0xffffffff) throw new Error(`u32: ${n} out of range`)\n return Uint8Array.of(n & 0xff, (n >>> 8) & 0xff, (n >>> 16) & 0xff, n >>> 24)\n}\n\n/** Signed 64-bit little-endian (two's complement). Amounts are never negative here, but ZIP-244 types the field as signed. */\nexport function i64le(v: bigint): Uint8Array {\n if (v < -(1n << 63n) || v >= 1n << 63n) throw new Error(`i64: ${v} out of range`)\n let x = v < 0n ? v + (1n << 64n) : v\n const out = new Uint8Array(8)\n for (let i = 0; i < 8; i++) { out[i] = Number(x & 0xffn); x >>= 8n }\n return out\n}\n\nexport class Writer {\n private readonly parts: Uint8Array[] = []\n u8(n: number): this { this.parts.push(Uint8Array.of(n & 0xff)); return this }\n u32(n: number): this { this.parts.push(u32le(n)); return this }\n i64(v: bigint): this { this.parts.push(i64le(v)); return this }\n bytes(b: Uint8Array): this { this.parts.push(b); return this }\n compact(n: number): this { this.parts.push(compactSize(n)); return this }\n /** CompactSize length prefix + bytes (the \"field encoding\" of a script). */\n varBytes(b: Uint8Array): this { return this.compact(b.length).bytes(b) }\n finish(): Uint8Array {\n const len = this.parts.reduce((s, p) => s + p.length, 0)\n const out = new Uint8Array(len)\n let o = 0\n for (const p of this.parts) { out.set(p, o); o += p.length }\n return out\n }\n}\n\nexport class Reader {\n offset = 0\n constructor(private readonly buf: Uint8Array) {}\n get remaining(): number { return this.buf.length - this.offset }\n private need(n: number): void {\n if (this.offset + n > this.buf.length) throw new Error('Transaction truncated')\n }\n u8(): number { this.need(1); return this.buf[this.offset++]! }\n u32(): number {\n this.need(4)\n const b = this.buf\n const o = this.offset\n this.offset += 4\n return (b[o]! | (b[o + 1]! << 8) | (b[o + 2]! << 16)) + b[o + 3]! * 0x1000000\n }\n i64(): bigint {\n this.need(8)\n let v = 0n\n for (let i = 7; i >= 0; i--) v = (v << 8n) | BigInt(this.buf[this.offset + i]!)\n this.offset += 8\n return v >= 1n << 63n ? v - (1n << 64n) : v\n }\n bytes(n: number): Uint8Array { this.need(n); const out = this.buf.slice(this.offset, this.offset + n); this.offset += n; return out }\n compact(): number {\n const first = this.u8()\n if (first < 0xfd) return first\n if (first === 0xfd) { this.need(2); const v = this.buf[this.offset]! | (this.buf[this.offset + 1]! << 8); this.offset += 2; return v }\n if (first === 0xfe) return this.u32()\n throw new Error('CompactSize: 64-bit lengths are not supported')\n }\n varBytes(): Uint8Array { return this.bytes(this.compact()) }\n}\n\n/** Display ↔ internal byte order of a 32-byte hash (Bitcoin convention: hex is shown reversed). */\nexport function reverseBytes(b: Uint8Array): Uint8Array {\n return Uint8Array.from(b).reverse()\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\n/** An HTTP status that is the server refusing the request itself: 4xx, but not 408 (request timeout). */\nexport const refusedStatus = (status: number): boolean => status >= 400 && status < 500 && status !== 408\n\n/** Mark an error as a node's answer refusing the request: nothing was taken (round 3, M12). */\nexport function refusal<E extends Error>(e: E): E {\n return Object.assign(e, { answered: true })\n}\n\n/**\n * An endpoint answered with a refusal (HTTP 4xx other than 408 with a reason, or an error body):\n * nothing was taken. A thrown fetch, a timeout, a 5xx or a body that cannot be read may have been.\n */\nexport function isAnsweredRefusal(e: unknown): boolean {\n return (e as { answered?: unknown } | null)?.answered === true\n}\n\n/** The node says it already holds the transaction (an earlier attempt delivered it): it is out, not refused. */\nexport function isAlreadyKnown(e: unknown): boolean {\n for (let x: unknown = e, depth = 0; x instanceof Error && depth < 5; x = x.cause, depth++) {\n if (/txn-already-(in-mempool|known)|already (known|in (the )?(mempool|block ?chain))/i.test(x.message)) return true\n }\n return false\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)\nexport const isInt = (v: unknown): v is number => typeof v === 'number' && Number.isInteger(v)\n","/** Zcash mainnet or testnet. */\nexport type ZcashNetwork = 'mainnet' | 'testnet'\n\n/** CAIP-2 ids the SDK uses for Zcash (the swap2 catalog already names `zcash:mainnet`). */\nexport const CAIP2: Record<ZcashNetwork, string> = { mainnet: 'zcash:mainnet', testnet: 'zcash:testnet' }\n\n/** An unspent transparent output the account can spend. */\nexport interface Utxo {\n txid: string\n vout: number\n /** Zatoshis. */\n value: bigint\n /** Block height; -1 while in the mempool. */\n height: number\n}\n\n/** A previous output a transaction spends — ZIP-244 signs its value AND script. */\nexport interface SpentOutput {\n value: bigint\n script: Uint8Array\n}\n\n/** Transport-neutral transaction record (receipts, confirmations). */\nexport interface ZcashTxInfo {\n txid: string\n /** -1 or 0 while unconfirmed. */\n blockHeight: number\n confirmations: number\n fee?: bigint\n /** Unix seconds. */\n blockTime?: number\n}\n\n/** Minimal chain-data client every transport implements. Values in zatoshis. */\nexport interface ZcashClient {\n connect(): Promise<void>\n close(): Promise<void>\n getBalance(address: string): Promise<{ confirmed: bigint; unconfirmed: bigint }>\n listUnspent(address: string): Promise<Utxo[]>\n /** Raw transaction hex (any version — only used to read prevouts and for receipts). */\n getTransaction(txid: string): Promise<string>\n /** Value + scriptPubKey of one output of an existing transaction (what signing a spend of it needs). */\n getOutput(txid: string, vout: number): Promise<SpentOutput | undefined>\n getTransactionInfo(txid: string): Promise<ZcashTxInfo | undefined>\n /** Broadcast raw hex; returns the txid. */\n broadcast(rawTx: string): Promise<string>\n /** Current chain tip height (expiry height, anti-fee-sniping lock time, consensus branch selection). */\n getBlockHeight(): Promise<number>\n}\n\n/** One transport to a Zcash indexer: Blockchair or a Blockbook instance. */\nexport type ZcashClientConfig =\n /** Blockchair's public REST API (`https://api.blockchair.com/zcash`; optional API key). Mainnet only. */\n | { type: 'blockchair'; clientConfig?: { url?: string; key?: string } }\n /** A Zcash Blockbook (NOWNodes `https://zec-blockbook.nownodes.io` with an `api-key` header, a self-hosted instance, …). */\n | { type: 'blockbook-http'; clientConfig: { url: string; headers?: Record<string, string> } }\n\n/**\n * Options for a Zcash wallet manager or account: transports, network and fee limits. Transparent\n * addresses only.\n */\nexport interface ZcashConfig {\n /** One or more transports (config objects or ready `ZcashClient`s). A list fails over in order. Omit for an offline (sign-only) wallet. */\n client?: ZcashClientConfig | ZcashClient | Array<ZcashClientConfig | ZcashClient>\n network?: ZcashNetwork\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 (zatoshis) for `transfer`. */\n transferMaxFee?: bigint | number\n /** Max fee (zatoshis) for `sendTransaction` / `signTransaction`. */\n transactionMaxFee?: bigint | number\n /** Hard fee ceiling in zatoshis for any transaction this account signs or broadcasts (default 1 000 000 = 0.01 ZEC). */\n maxFee?: bigint | number\n /** Blocks after the next block (tip + 1) at which an unmined transaction expires (ZIP-203; default 40, the zcashd/Zebra default). 0 = never. */\n expiryDelta?: number\n /** Set nLockTime to the tip height so the transaction cannot be mined into a reorged block (default true). */\n antiFeeSniping?: boolean\n /**\n * Consensus branch id to sign under. Default on mainnet: the one in force at\n * tip + 1 (`branchIdForHeight`) — set this when a network upgrade activates\n * before the package learns its id. Required on testnet and regtest, whose\n * upgrades activate at other heights.\n */\n consensusBranchId?: number\n /** Coin-selection input cap (default 200). */\n maxInputs?: number\n /** Injectable fetch (tests, custom agents). Defaults to globalThis.fetch. */\n fetch?: typeof fetch\n}\n\n/** A spend. `value` in zatoshis. `fee` overrides the ZIP-317 conventional fee (still subject to `maxFee`). */\nexport interface ZcashSpend {\n to: string\n value: bigint | number | string\n fee?: bigint | number\n}\n\n/** `sendTransaction` accepts a spend or an already signed raw transaction hex. */\nexport type ZcashTransaction = ZcashSpend | string\n\n/** A transparent ZEC transfer. Amount in zatoshis. */\nexport interface ZcashTransferOptions {\n /** Not supported on Zcash; present for the shared account interface. */\n token?: string\n recipient: string\n amount: bigint | number | string\n}\n\n/** A mined Zcash transaction. */\nexport interface ZcashReceipt {\n hash: string\n /** Always 1 once mined — a transparent transaction cannot fail after inclusion. */\n status: 1\n blockNumber: bigint\n confirmations: number\n fee?: bigint\n}\n\n/** The most one transaction can send (a sweep of every UTXO), after the fee. */\nexport interface ZcashMaxSpendableResult {\n /** Max zatoshis 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: number\n}\n\n/** Problems a described transaction is flagged with. */\nexport type ZcashWarning =\n /** Fee exceeds 10 % of the amount sent. */\n | 'fee-over-10pct-of-amount'\n /** Fee is below the ZIP-317 conventional fee — nodes may not relay it. */\n | 'fee-below-conventional'\n /** An output is below the dust floor. */\n | 'dust-output'\n /** Change was below dust and folded into the fee. */\n | 'no-change'\n /** No expiry height: the transaction stays valid in mempools indefinitely. */\n | 'no-expiry'\n\n/** One input of a described transaction: the UTXO it spends. */\nexport interface ZcashTxInputDescription {\n txid: string\n vout: number\n value: bigint\n address: string | undefined\n}\n\n/** One output of a described transaction, tagged as the recipient, our change, or unknown. */\nexport interface ZcashTxOutputDescription {\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 ZcashTxDescription {\n kind: 'zcash-transfer'\n version: 5\n consensusBranchId: number\n inputs: ZcashTxInputDescription[]\n outputs: ZcashTxOutputDescription[]\n /** Zatoshis sent to non-change outputs. */\n amount: bigint\n fee: bigint\n /** The ZIP-317 fee this transaction's shape calls for. */\n conventionalFee: bigint\n /** Serialized size in bytes. */\n size: number\n lockTime: number\n expiryHeight: number\n /** Present once the transaction is signed. */\n txid?: string\n warnings: ZcashWarning[]\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACOA,IAAAA,eAA6B;;;ACN7B,mBAAiE;;;ACDjE,kBAA6B;AAEtB,IAAM,qBAAqB;AAGlC,eAAsB,iBAAiB,SAAuB,KAAa,MAA+B,WAAmB,UAAqC;AAChK,QAAM,SAAS,OAAO,gBAAgB,eAAe,OAAO,YAAY,YAAY,aAAa,YAAY,QAAQ,SAAS,IAAI;AAClI,MAAI;AACF,WAAO,MAAM,QAAQ,KAAK,EAAE,GAAG,MAAM,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC,EAAG,CAAC;AAAA,EACtE,SAAS,GAAG;AACV,UAAM,IAAI,yBAAa,mBAAmB,GAAG,IAAI,EAAE,UAAU,OAAO,EAAE,CAAC;AAAA,EACzE;AACF;AAGO,IAAM,gBAAgB,CAAC,WAA4B,UAAU,OAAO,SAAS,OAAO,WAAW;AAG/F,SAAS,QAAyB,GAAS;AAChD,SAAO,OAAO,OAAO,GAAG,EAAE,UAAU,KAAK,CAAC;AAC5C;AAkBO,IAAM,WAAW,CAAC,MAA6C,OAAO,MAAM,YAAY,MAAM,QAAQ,CAAC,MAAM,QAAQ,CAAC;AAGtH,IAAM,QAAQ,CAAC,MAA4B,OAAO,MAAM,YAAY,OAAO,UAAU,CAAC;;;AF5BtF,IAAM,iBAAiB;AAE9B,IAAM,aAAa;AAUnB,IAAM,SAAS,CAAC,MAAoC,SAAS,CAAC,KAAK,MAAM,EAAE,QAAQ,KAAK,OAAO,EAAE,qBAAqB,YAAY,MAAM,EAAE,KAAK,KAAK,OAAO,EAAE,UAAU;AACvK,IAAM,WAAW,CAAC,MAAsC,SAAS,CAAC,KAAK,MAAM,EAAE,KAAK,KAAK,OAAO,EAAE,UAAU,YAAY,OAAO,EAAE,eAAe;AAChJ,IAAM,cAAc,CAAC,MACnB,SAAS,CAAC,KAAK,SAAS,EAAE,WAAW,KAAK,MAAM,EAAE,YAAY,QAAQ,KAAK,OAAO,EAAE,YAAY,SAAS,YAAY,MAAM,QAAQ,EAAE,MAAM,KAAK,EAAE,OAAO,MAAM,QAAQ,KAAK,MAAM,QAAQ,EAAE,OAAO,KAAK,EAAE,QAAQ,MAAM,QAAQ;AAG3N,SAAS,eAAe,GAA2C;AACxE,MAAI,CAAC,EAAG,QAAO;AACf,QAAM,IAAI,KAAK,MAAM,GAAG,EAAE,QAAQ,KAAK,GAAG,CAAC,GAAG;AAC9C,SAAO,OAAO,SAAS,CAAC,IAAI,KAAK,MAAM,IAAI,GAAI,IAAI;AACrD;AAEO,IAAM,mBAAN,MAA8C;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,YAAY,SAAyC,CAAC,GAAG,UAAwB,WAAW,OAAO,YAAY,oBAAoB;AACjI,SAAK,QAAQ,OAAO,OAAO,gBAAgB,QAAQ,QAAQ,EAAE;AAC7D,SAAK,MAAM,OAAO;AAClB,SAAK,UAAU;AACf,SAAK,YAAY;AAAA,EACnB;AAAA,EAEA,MAAM,UAAyB;AAAA,EAAC;AAAA,EAChC,MAAM,QAAuB;AAAA,EAAC;AAAA,EAEtB,IAAI,MAAc,QAAgC,CAAC,GAAW;AACpE,UAAM,IAAI,IAAI,gBAAgB,KAAK;AACnC,QAAI,KAAK,IAAK,GAAE,IAAI,OAAO,KAAK,GAAG;AACnC,UAAM,IAAI,EAAE,SAAS;AACrB,WAAO,GAAG,KAAK,IAAI,IAAI,IAAI,GAAG,IAAI,IAAI,CAAC,KAAK,EAAE;AAAA,EAChD;AAAA,EAEA,MAAc,QAAW,MAAc,OAA+B,MAA+B,OAAgF;AACnL,UAAM,MAAM,KAAK,IAAI,MAAM,KAAK;AAChC,UAAM,MAAM,MAAM,iBAAiB,KAAK,SAAS,KAAK,MAAM,KAAK,WAAW,KAAK,IAAI;AACrF,QAAI;AACJ,QAAI;AAAE,aAAO,MAAM,IAAI,KAAK;AAAA,IAAE,SAAS,GAAG;AACxC,UAAI,IAAI,WAAW,OAAO,IAAI,WAAW,OAAO,IAAI,WAAW,IAAK,OAAM,IAAI,0BAAa,0BAA0B,IAAI,MAAM,KAAK,EAAE,UAAU,KAAK,KAAK,CAAC;AAC3J,YAAM,IAAI,0BAAa,iCAAiC,IAAI,MAAM,SAAS,GAAG,IAAI,EAAE,UAAU,KAAK,MAAM,OAAO,EAAE,CAAC;AAAA,IACrH;AACA,UAAM,MAAM;AACZ,UAAM,OAAO,IAAI,SAAS,QAAQ,IAAI;AACtC,QAAI,SAAS,OAAO,SAAS,OAAO,SAAS,IAAK,OAAM,IAAI,0BAAa,0BAA0B,IAAI,KAAK,EAAE,UAAU,KAAK,KAAK,CAAC;AACnI,QAAI,SAAS,IAAK,OAAM,IAAI,SAAS;AACrC,QAAI,SAAS,OAAO,CAAC,IAAI,GAAI,OAAM,IAAI,0BAAa,8BAA8B,IAAI,IAAI,IAAI,SAAS,SAAS,IAAI,UAAU,KAAK,GAAG,KAAK,EAAE,UAAU,KAAK,KAAK,CAAC;AAClK,QAAI,CAAC,MAAM,IAAI,IAAI,EAAG,OAAM,IAAI,0BAAa,+CAA+C,GAAG,IAAI,EAAE,UAAU,KAAK,KAAK,CAAC;AAC1H,WAAO,EAAE,MAAM,IAAI,MAAM,OAAO,IAAI,SAAS,MAAM;AAAA,EACrD;AAAA,EAEA,MAAc,UAAU,SAAqI;AAC3J,UAAM,EAAE,MAAM,MAAM,IAAI,MAAM,KAAK,QAAQ,sBAAsB,OAAO,IAAI,EAAE,OAAO,KAAK,UAAU,GAAG,GAAG,QAAW,CAAC,MACpH,SAAS,CAAC,KAAK,OAAO,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,SAAS,CAAC,KAAK,SAAS,EAAE,OAAO,KAAK,OAAO,EAAE,QAAQ,YAAY,YAAY,MAAM,QAAQ,EAAE,IAAI,KAAK,EAAE,KAAK,MAAM,MAAM,CAAC,CAAC;AAC5K,UAAM,QAAQ,KAAK,OAAO,KAAK,OAAO,OAAO,IAAI,EAAE,CAAC;AACpD,QAAI,CAAC,MAAO,OAAM,IAAI,0BAAa,+BAA+B,OAAO,IAAI,EAAE,UAAU,KAAK,KAAK,CAAC;AACpG,WAAO,EAAE,SAAS,MAAM,SAAS,MAAM,MAAM,MAAM,cAAc,MAAM,gBAAgB,CAAC,GAAG,MAAM;AAAA,EACnG;AAAA;AAAA,EAGA,MAAM,iBAAiB,SAAiB,OAAe,QAA0E;AAC/H,UAAM,EAAE,KAAK,IAAI,MAAM,KAAK,QAAQ,sBAAsB,OAAO,IAAI,EAAE,OAAO,GAAG,KAAK,MAAM,QAAQ,GAAG,MAAM,KAAK,GAAG,QAAW,CAAC,MAC/H,SAAS,CAAC,KAAK,OAAO,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,SAAS,CAAC,KAAK,SAAS,EAAE,OAAO,MAAM,EAAE,iBAAiB,UAAa,MAAM,QAAQ,EAAE,YAAY,EAAE,CAAC;AACrJ,UAAM,QAAQ,KAAK,OAAO,KAAK,OAAO,OAAO,IAAI,EAAE,CAAC;AACpD,QAAI,CAAC,MAAO,OAAM,IAAI,0BAAa,+BAA+B,OAAO,IAAI,EAAE,UAAU,KAAK,KAAK,CAAC;AACpG,WAAO,EAAE,SAAS,MAAM,gBAAgB,CAAC,GAAG,OAAO,CAAC,MAAmB,OAAO,MAAM,QAAQ,GAAG,OAAO,MAAM,QAAQ,kBAAkB;AAAA,EACxI;AAAA;AAAA,EAGA,MAAM,WAAW,SAAsE;AACrF,UAAM,IAAI,MAAM,KAAK,UAAU,OAAO;AACtC,QAAI,YAAY,IAAI,cAAc;AAClC,eAAW,KAAK,EAAE,MAAM;AAAE,UAAI,EAAE,WAAW,EAAG,cAAa,OAAO,EAAE,KAAK;AAAA,UAAQ,gBAAe,OAAO,EAAE,KAAK;AAAA,IAAE;AAChH,SAAK,EAAE,QAAQ,wBAAwB,EAAE,KAAK,UAAU,EAAE,KAAK,OAAQ,aAAY,OAAO,EAAE,QAAQ,OAAO,IAAI;AAC/G,WAAO,EAAE,WAAW,YAAY;AAAA,EAClC;AAAA,EAEA,MAAM,YAAY,SAAkC;AAClD,UAAM,IAAI,MAAM,KAAK,UAAU,OAAO;AACtC,WAAO,EAAE,KAAK,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,kBAAkB,MAAM,EAAE,OAAO,OAAO,OAAO,EAAE,KAAK,GAAG,QAAQ,EAAE,WAAW,IAAI,EAAE,WAAW,GAAG,EAAE;AAAA,EAC1I;AAAA,EAEA,MAAM,eAAe,MAA+B;AAClD,UAAM,EAAE,KAAK,IAAI,MAAM,KAAK,QAAQ,mBAAmB,IAAI,IAAI,CAAC,GAAG,QAAW,CAAC,MAC7E,SAAS,CAAC,KAAK,OAAO,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,SAAS,CAAC,KAAK,OAAO,EAAE,oBAAoB,QAAQ,CAAC;AACpG,UAAM,OAAO,KAAK,IAAI,KAAK,OAAO,OAAO,IAAI,EAAE,CAAC,IAAI;AACpD,QAAI,CAAC,IAAK,OAAM,IAAI,0BAAa,eAAe,IAAI,oBAAoB,EAAE,UAAU,KAAK,KAAK,CAAC;AAC/F,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,MAAM,wBAAwB,MAA0D;AACtF,QAAI;AACF,YAAM,EAAE,MAAM,MAAM,IAAI,MAAM,KAAK,QAAQ,0BAA0B,IAAI,IAAI,CAAC,GAAG,QAAW,CAAC,MAC3F,SAAS,CAAC,KAAK,OAAO,OAAO,CAAC,EAAE,MAAM,CAACC,OAAMA,OAAM,QAAQ,YAAYA,EAAC,CAAC,CAAC;AAC5E,YAAM,IAAI,KAAK,IAAI,KAAK,OAAO,OAAO,IAAI,EAAE,CAAC;AAC7C,UAAI,CAAC,EAAG,QAAO;AACf,aAAO,EAAE,GAAG,GAAG,aAAa,EAAE,GAAG,EAAE,aAAa,GAAI,UAAU,SAAY,EAAE,eAAe,EAAE,YAAY,WAAW,IAAI,QAAQ,EAAE,YAAY,WAAW,IAAI,EAAE,IAAI,CAAC,EAAG,EAAE;AAAA,IAC3K,SAAS,GAAG;AACV,UAAI,aAAa,SAAU,QAAO;AAClC,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,yBAAyB,OAA8D;AAC3F,UAAM,MAAM,oBAAI,IAAmC;AACnD,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,IAAI;AACzC,YAAM,QAAQ,MAAM,MAAM,GAAG,IAAI,EAAE;AACnC,YAAM,EAAE,MAAM,MAAM,IAAI,MAAM,KAAK,QAAQ,2BAA2B,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,GAAG,QAAW,CAAC,MACvG,SAAS,CAAC,KAAK,OAAO,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,MAAM,QAAQ,YAAY,CAAC,CAAC,CAAC;AAC5E,iBAAW,CAAC,MAAM,CAAC,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC5C,YAAI,CAAC,EAAG;AACR,cAAM,gBAAgB,UAAU,UAAa,EAAE,YAAY,WAAW,IAAI,QAAQ,EAAE,YAAY,WAAW,IAAI;AAC/G,YAAI,IAAI,MAAM,EAAE,GAAG,GAAG,aAAa,EAAE,GAAG,EAAE,aAAa,cAAc,EAAE,CAA0B;AAAA,MACnG;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,UAAU,MAAc,MAAgD;AAC5E,UAAM,IAAI,MAAM,KAAK,wBAAwB,IAAI;AACjD,UAAM,IAAI,GAAG,QAAQ,KAAK,CAAC,MAAM,EAAE,UAAU,IAAI;AACjD,WAAO,IAAI,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,YAAQ,yBAAW,EAAE,UAAU,EAAE,IAAI;AAAA,EAC5E;AAAA,EAEA,MAAM,mBAAmB,MAAgD;AACvE,UAAM,IAAI,MAAM,KAAK,wBAAwB,IAAI;AACjD,QAAI,CAAC,EAAG,QAAO;AACf,UAAM,IAAI,EAAE;AACZ,UAAM,OAAoB,EAAE,MAAM,EAAE,MAAM,aAAa,EAAE,WAAW,IAAI,EAAE,WAAW,IAAI,eAAe,EAAE,iBAAiB,EAAE;AAC7H,QAAI,OAAO,EAAE,QAAQ,SAAU,MAAK,MAAM,OAAO,EAAE,GAAG;AACtD,UAAM,OAAO,eAAe,EAAE,IAAI;AAClC,QAAI,SAAS,OAAW,MAAK,YAAY;AACzC,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,UAAU,OAAgC;AAC9C,UAAM,OAAO,QAAQ,mBAAmB,KAAK,CAAC;AAC9C,UAAM,MAAM,KAAK,IAAI,kBAAkB;AACvC,UAAM,MAAM,MAAM,iBAAiB,KAAK,SAAS,KAAK,EAAE,QAAQ,QAAQ,SAAS,EAAE,gBAAgB,oCAAoC,GAAG,KAAK,GAAG,KAAK,WAAW,KAAK,IAAI;AAC3K,QAAI,MAA+D,CAAC;AACpE,QAAI,SAAS;AACb,QAAI;AAAE,YAAO,MAAM,IAAI,KAAK;AAAkB,eAAS;AAAA,IAAK,QAAQ;AAAA,IAAsB;AAC1F,UAAM,OAAO,IAAI,MAAM;AACvB,QAAI,KAAM,QAAO;AACjB,UAAM,SAAS,IAAI,SAAS;AAG5B,QAAI,UAAU,WAAW,IAAI,MAAM,cAAc,IAAI,MAAM,GAAI,OAAM,QAAQ,IAAI,MAAM,uBAAuB,MAAM,EAAE,CAAC;AACvH,UAAM,IAAI,0BAAa,+CAA+C,IAAI,MAAM,IAAI,IAAI,UAAU,KAAK,EAAE,UAAU,KAAK,KAAK,CAAC;AAAA,EAChI;AAAA,EAEA,MAAM,iBAAkC;AACtC,UAAM,EAAE,KAAK,IAAI,MAAM,KAAK,QAAQ,SAAS,CAAC,GAAG,QAAW,CAAC,MAA0C,SAAS,CAAC,KAAK,MAAM,EAAE,iBAAiB,CAAC;AAChJ,QAAI,KAAK,qBAAqB,EAAG,OAAM,IAAI,0BAAa,uCAAuC,EAAE,UAAU,KAAK,KAAK,CAAC;AACtH,WAAO,KAAK;AAAA,EACd;AACF;AAEA,IAAM,WAAN,cAAuB,MAAM;AAAA,EAAE,cAAc;AAAE,UAAM,WAAW;AAAG,SAAK,OAAO;AAAA,EAAW;AAAE;;;AGtLrF,IAAM,QAAsC,EAAE,SAAS,iBAAiB,SAAS,gBAAgB;;;AJwCjG,IAAM,0BAAN,cAAsC,MAAM;AAAA,EACxC;AAAA,EACA;AAAA,EACT,YAAY,OAAe,QAAgB;AACzC,UAAM,2BAA2B,KAAK,KAAK,MAAM,EAAE;AACnD,SAAK,OAAO;AACZ,SAAK,QAAQ;AACb,SAAK,SAAS;AAAA,EAChB;AACF;AAEA,IAAM,gBAAgB;AACtB,IAAM,gBAAgB;AAIf,SAAS,aAAa,GAA+B;AAC1D,SAAO,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;AAC7B;AAEO,SAAS,aAAa,GAA+B;AAC1D,QAAM,IAAI,kBAAkB,KAAK,CAAC;AAClC,MAAI,CAAC,EAAG,OAAM,IAAI,MAAM,sDAAsD;AAC9E,QAAM,IAAI,OAAO,EAAE,CAAC,CAAC,GAAG,OAAO,OAAO,EAAE,CAAC,CAAC;AAC1C,MAAI,OAAO,EAAG,OAAM,IAAI,MAAM,sDAAsD;AACpF,SAAO,EAAE,GAAG,GAAG,GAAG,GAAG,KAAK;AAC5B;AAEO,SAAS,eAAe,OAAe,SAAiB,GAAwC;AACrG,MAAI,QAAQ,IAAI,SAAS,IAAI,eAAe;AAC5C,aAAW,KAAK,EAAE,OAAQ,KAAI,EAAE,cAAc,QAAS,UAAS,OAAO,EAAE,KAAK;AAC9E,aAAW,KAAK,EAAE,SAAS;AAAE,QAAI,EAAE,cAAc,QAAS,WAAU,OAAO,EAAE,KAAK;AAAA,QAAQ,iBAAgB,OAAO,EAAE,KAAK;AAAA,EAAE;AAC1H,QAAM,aAAa,EAAE,OAAO,KAAK,CAAC,MAAM,EAAE,SAAS,GAAG;AACtD,QAAM,aAAa,EAAE,QAAQ,KAAK,CAAC,MAAM,EAAE,aAAa,EAAE,cAAc,OAAO,GAAG;AAClF,QAAM,YAA6B,CAAC;AACpC,MAAI,MAAc,IAAmB;AACrC,MAAI,QAAQ,IAAI;AACd,WAAO;AACP,SAAK,cAAc;AACnB,kBAAc,aAAa,eAAe;AAC1C,QAAI,cAAc,GAAI,WAAU,KAAK,EAAE,OAAO,MAAM,MAAM,SAAS,IAAI,QAAQ,YAAY,CAAC;AAAA,EAC9F,OAAO;AACL,WAAO,eAAe,EAAE,OAAO,WAAW,IAAI,aAAa;AAC3D,SAAK;AACL,kBAAc;AACd,QAAI,cAAc,GAAI,WAAU,KAAK,EAAE,OAAO,MAAM,MAAM,IAAI,SAAS,QAAQ,YAAY,CAAC;AAAA,EAC9F;AACA,QAAM,IAAI,EAAE;AACZ,QAAM,YAAY,EAAE,WAAW;AAC/B,QAAM,MAAoB;AAAA,IACxB;AAAA,IAAO,MAAM,EAAE;AAAA,IAAM,MAAM,eAAe,EAAE,IAAI,KAAK;AAAA,IAAG,QAAQ,YAAY,cAAc;AAAA,IAAW;AAAA,IAAS;AAAA,IAAM;AAAA,IAAI;AAAA,IAAa;AAAA,IACrI,KAAK,EAAE,IAAI,GAAG,OAAO,OAAO;AAAA,EAC9B;AACA,MAAI,OAAO,EAAE,QAAQ,SAAU,KAAI,MAAM,OAAO,EAAE,GAAG;AACrD,MAAI,UAAW,KAAI,QAAQ,OAAO,EAAE,QAAQ;AAC5C,SAAO;AACT;AAGO,SAAS,mBAAmB,MAAsB;AACvD,SAAO,4CAA4C,IAAI;AACzD;AAOO,SAAS,mBAAmB,UAA+B,CAAC,GAAuB;AACxF,QAAM,QAAQ,MAAM;AACpB,QAAM,UAAU,QAAQ,SAAS,WAAW;AAC5C,MAAI,OAAO,YAAY,WAAY,OAAM,IAAI,MAAM,0EAA0E;AAC7H,QAAM,SAAS,IAAI,iBAAiB,EAAE,GAAI,QAAQ,gBAAgB,EAAE,KAAK,QAAQ,cAAc,IAAI,CAAC,GAAI,GAAI,QAAQ,MAAM,EAAE,KAAK,QAAQ,IAAI,IAAI,CAAC,EAAG,GAAG,SAAS,QAAQ,aAAa,kBAAkB;AACxM,QAAM,OAAO,OAAU,QAAsC;AAC3D,QAAI;AAAE,aAAO,MAAM,IAAI;AAAA,IAAE,SAAS,GAAG;AAAE,YAAM,IAAI,wBAAwB,OAAO,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAC;AAAA,IAAE;AAAA,EAC9H;AAEA,SAAO;AAAA,IACL;AAAA,IAEA,MAAM,aAAa,SAAiB,QAAsB,CAAC,GAA8B;AACvF,YAAM,SAAS,MAAM,SAAS,aAAa,MAAM,MAAM,IAAI;AAC3D,YAAM,WAAW,QAAQ,KAAK,KAAK,IAAI,eAAe,KAAK,IAAI,GAAG,KAAK,MAAM,QAAQ,YAAY,MAAM,SAAS,aAAa,CAAC,CAAC;AAC/H,YAAM,SAAS,QAAQ,KAAK;AAC5B,YAAM,EAAE,QAAQ,MAAM,IAAI,MAAM,KAAK,MAAM,OAAO,iBAAiB,SAAS,UAAU,MAAM,CAAC;AAC7F,YAAM,aAAa,OAAO,SAAS,MAAM,KAAK,MAAM,OAAO,yBAAyB,MAAM,CAAC,IAAI,oBAAI,IAAI;AACvG,UAAI,QAAQ,OAAO,IAAI,CAAC,MAAM,WAAW,IAAI,CAAC,CAAC,EAAE,OAAO,CAAC,MAAkC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,eAAe,OAAO,SAAS,CAAC,CAAC;AAC5I,YAAM,KAAK,CAAC,GAAG,OAAO,EAAE,UAAU,SAAY,IAAI,EAAE,UAAU,SAAY,KAAM,EAAE,QAAQ,EAAE,QAAQ,IAAI,EAAE,QAAQ,EAAE,QAAQ,KAAK,MAAO,EAAE,OAAO,EAAE,IAAI;AACvJ,UAAI,OAAO,UAAU,SAAY,SAAS,OAAO,SAAS,QAAQ,OAAO,WAAW;AACpF,UAAI,MAAM,UAAU,QAAW;AAC7B,cAAM,QAAQ,MAAM;AACpB,YAAI,MAAM,KAAK,CAAC,MAAM,EAAE,WAAW,eAAe,EAAE,OAAO,KAAK,EAAG,QAAO;AAC1E,gBAAQ,MAAM,OAAO,CAAC,MAAM,EAAE,WAAW,eAAe,EAAE,QAAQ,KAAK;AAAA,MACzE;AACA,YAAM,OAAyB,EAAE,OAAO,QAAQ,GAAI,UAAU,SAAY,EAAE,MAAM,IAAI,CAAC,EAAG;AAC1F,UAAI,KAAM,MAAK,SAAS,aAAa,EAAE,GAAG,GAAG,GAAG,SAAS,OAAO,QAAQ,GAAG,SAAS,CAAC;AACrF,aAAO;AAAA,IACT;AAAA,IAEA,MAAM,eAAe,MAAc,SAAoD;AACrF,YAAM,IAAI,MAAM,KAAK,MAAM,OAAO,wBAAwB,IAAI,CAAC;AAC/D,aAAO,IAAI,eAAe,OAAO,SAAS,CAAC,IAAI;AAAA,IACjD;AAAA,IAEA,eAAe;AAAA,EACjB;AACF;","names":["import_core","t"]}
|
package/dist/history.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import '@anywalletkit/core';
|
|
2
|
-
export { H as HistoryUnavailableError,
|
|
2
|
+
export { H as HistoryUnavailableError, o as ZcashChainTx, q as ZcashHistoryCursor, r as ZcashHistoryOptions, s as ZcashHistoryPage, t as ZcashHistoryRaw, u as ZcashHistorySource, z as createZcashHistory, A as decodeCursor, D as encodeCursor, E as mapDashboardTx, F as zcashExplorerTxUrl } from './history-CiZ6aFMT.cjs';
|
package/dist/history.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import '@anywalletkit/core';
|
|
2
|
-
export { H as HistoryUnavailableError,
|
|
2
|
+
export { H as HistoryUnavailableError, o as ZcashChainTx, q as ZcashHistoryCursor, r as ZcashHistoryOptions, s as ZcashHistoryPage, t as ZcashHistoryRaw, u as ZcashHistorySource, z as createZcashHistory, A as decodeCursor, D as encodeCursor, E as mapDashboardTx, F as zcashExplorerTxUrl } from './history-CiZ6aFMT.js';
|
package/dist/history.js
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -128,7 +128,8 @@ function encodeAddress(kind, hash, network) {
|
|
|
128
128
|
return b58.encode(Uint8Array.of(a, b, ...hash));
|
|
129
129
|
}
|
|
130
130
|
function decodeAddress(address, network) {
|
|
131
|
-
|
|
131
|
+
if (typeof address !== "string" || /\s/.test(address)) throw new Error(`Invalid Zcash address: it carries whitespace or an invisible character (${JSON.stringify(address)}).`);
|
|
132
|
+
const a = address;
|
|
132
133
|
if (/^u1|^utest/i.test(a)) throw new Error(`Unified address (${a.slice(0, 6)}\u2026) \u2014 shielded receivers are not supported; use a transparent t-address.`);
|
|
133
134
|
if (/^zs1|^ztestsapling/i.test(a)) throw new Error("Sapling shielded address (zs1\u2026) \u2014 this wallet sends to transparent t-addresses only.");
|
|
134
135
|
if (/^zc/i.test(a) && a.length > 90) throw new Error("Sprout address (zc\u2026) \u2014 the Sprout pool is deprecated; use a transparent t-address.");
|
|
@@ -1159,7 +1160,7 @@ var WalletAccountZcash = class _WalletAccountZcash extends WalletAccountReadOnly
|
|
|
1159
1160
|
return { lockTime, expiryHeight, consensusBranchId };
|
|
1160
1161
|
}
|
|
1161
1162
|
/** Sign every input through the signer; the scriptSig is `<DER ‖ 0x01> <pubkey>`. */
|
|
1162
|
-
async signInputs(tx, spent) {
|
|
1163
|
+
async #signInputs(tx, spent) {
|
|
1163
1164
|
for (let i = 0; i < tx.inputs.length; i++) {
|
|
1164
1165
|
const digest = sighashAll(tx, i, spent);
|
|
1165
1166
|
const rs = await this.signer.sign(digest, { scheme: "ecdsa", context: "zcash-sighash" });
|
|
@@ -1167,7 +1168,7 @@ var WalletAccountZcash = class _WalletAccountZcash extends WalletAccountReadOnly
|
|
|
1167
1168
|
tx.inputs[i].scriptSig = p2pkhScriptSig(der, this.publicKey);
|
|
1168
1169
|
}
|
|
1169
1170
|
}
|
|
1170
|
-
async signSpend(spend) {
|
|
1171
|
+
async #signSpend(spend) {
|
|
1171
1172
|
this.live();
|
|
1172
1173
|
const plan = await this.planSpend(spend);
|
|
1173
1174
|
const params = await this.chainParams();
|
|
@@ -1179,7 +1180,7 @@ var WalletAccountZcash = class _WalletAccountZcash extends WalletAccountReadOnly
|
|
|
1179
1180
|
const spent = plan.utxos.map((u) => ({ value: u.value, script: this.scriptPubKey }));
|
|
1180
1181
|
const have = plan.utxos.reduce((s, u) => s + u.value, 0n);
|
|
1181
1182
|
if (have < plan.amount + plan.fee) throw new import_core7.InsufficientFundsError(plan.amount + plan.fee, have, "ZEC");
|
|
1182
|
-
await this
|
|
1183
|
+
await this.#signInputs(tx, spent);
|
|
1183
1184
|
const ctx = this.ctx({ to: spend.to, value: plan.amount });
|
|
1184
1185
|
const desc = describeTransaction(tx, spent, ctx);
|
|
1185
1186
|
assertSafe(desc, ctx);
|
|
@@ -1211,7 +1212,7 @@ var WalletAccountZcash = class _WalletAccountZcash extends WalletAccountReadOnly
|
|
|
1211
1212
|
/** "What you sign": the fully resolved spend (signed, NOT broadcast) or a caller's raw hex. */
|
|
1212
1213
|
async describeTransaction(tx) {
|
|
1213
1214
|
if (typeof tx === "string") return (await this.describeRaw(tx)).desc;
|
|
1214
|
-
return (await this
|
|
1215
|
+
return (await this.#signSpend(tx)).desc;
|
|
1215
1216
|
}
|
|
1216
1217
|
/** 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. */
|
|
1217
1218
|
async signTransaction(tx, options = {}) {
|
|
@@ -1221,7 +1222,7 @@ var WalletAccountZcash = class _WalletAccountZcash extends WalletAccountReadOnly
|
|
|
1221
1222
|
this.checkMax(desc.fee, (0, import_core7.feeLimit)(this._config.transactionMaxFee, options), "transaction");
|
|
1222
1223
|
return tx;
|
|
1223
1224
|
}
|
|
1224
|
-
const built = await this
|
|
1225
|
+
const built = await this.#signSpend(tx);
|
|
1225
1226
|
this.checkMax(built.fee, (0, import_core7.feeLimit)(this._config.transactionMaxFee, options), "transaction");
|
|
1226
1227
|
return built.hex;
|
|
1227
1228
|
}
|
|
@@ -1239,7 +1240,7 @@ var WalletAccountZcash = class _WalletAccountZcash extends WalletAccountReadOnly
|
|
|
1239
1240
|
hash = txid(parsed);
|
|
1240
1241
|
fee = desc.fee;
|
|
1241
1242
|
} else {
|
|
1242
|
-
const built = await this
|
|
1243
|
+
const built = await this.#signSpend(tx);
|
|
1243
1244
|
rawHex = built.hex;
|
|
1244
1245
|
hash = built.txid;
|
|
1245
1246
|
fee = built.fee;
|
|
@@ -1252,7 +1253,7 @@ var WalletAccountZcash = class _WalletAccountZcash extends WalletAccountReadOnly
|
|
|
1252
1253
|
if (o.token) throw new Error("Tokens are not supported on the zcash blockchain.");
|
|
1253
1254
|
this.live();
|
|
1254
1255
|
const client = this.requireClient("transfer");
|
|
1255
|
-
const built = await this
|
|
1256
|
+
const built = await this.#signSpend({ to: o.recipient, value: o.amount });
|
|
1256
1257
|
this.checkMax(built.fee, (0, import_core7.feeLimit)(this._config.transferMaxFee, writeOptions), "transfer");
|
|
1257
1258
|
return { hash: await this.broadcast(client, built.hex, built.txid), fee: built.fee };
|
|
1258
1259
|
}
|