@anywalletkit/wallet-zcash 0.2.3 → 0.2.4

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.
@@ -374,7 +374,7 @@ function createZcashHistory(options = {}) {
374
374
  const { hashes, total } = await wrap(() => client.listTransactions(address, pageSize, offset));
375
375
  const dashboards = hashes.length ? await wrap(() => client.getTransactionDashboards(hashes)) : /* @__PURE__ */ new Map();
376
376
  let items = hashes.map((h) => dashboards.get(h)).filter((d) => !!d).map((d) => mapDashboardTx(chain, address, d));
377
- items.sort((a, b) => (b.block === void 0 ? 1 : a.block === void 0 ? -1 : Number(b.block - a.block)) || b.time - a.time);
377
+ items.sort((a, b) => (b.block === void 0 ? 1 : a.block === void 0 ? -1 : b.block > a.block ? 1 : b.block < a.block ? -1 : 0) || b.time - a.time);
378
378
  let more = total !== void 0 ? offset + hashes.length < total : hashes.length === pageSize;
379
379
  if (query.since !== void 0) {
380
380
  const since = query.since;
@@ -418,4 +418,4 @@ export {
418
418
  zcashExplorerTxUrl,
419
419
  createZcashHistory
420
420
  };
421
- //# sourceMappingURL=chunk-GJBPCXQK.js.map
421
+ //# sourceMappingURL=chunk-6C7LNZNX.js.map
@@ -1 +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 } 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 try { env = (await res.json()) as typeof env } catch { /* handled below */ }\n const hash = env.data?.transaction_hash\n if (hash) return hash\n const reason = env.context?.error ?? `${res.status} ${res.statusText}`\n // A rejected transaction is the node's verdict, not a transport failure — a plain Error (not NetworkError), so failover does not retry it elsewhere.\n throw new Error(`Broadcast rejected: ${reason}`)\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\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 tip 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: picked from the tip height\n * (`branchIdForHeight`) — set this when a network upgrade activates before\n * the package learns its id.\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 : Number(b.block - a.block)) || 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"]}
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 } 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 try { env = (await res.json()) as typeof env } catch { /* handled below */ }\n const hash = env.data?.transaction_hash\n if (hash) return hash\n const reason = env.context?.error ?? `${res.status} ${res.statusText}`\n // A rejected transaction is the node's verdict, not a transport failure — a plain Error (not NetworkError), so failover does not retry it elsewhere.\n throw new Error(`Broadcast rejected: ${reason}`)\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\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 tip 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: picked from the tip height\n * (`branchIdForHeight`) — set this when a network upgrade activates before\n * the package learns its id.\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"]}
package/dist/history.cjs CHANGED
@@ -291,7 +291,7 @@ function createZcashHistory(options = {}) {
291
291
  const { hashes, total } = await wrap(() => client.listTransactions(address, pageSize, offset));
292
292
  const dashboards = hashes.length ? await wrap(() => client.getTransactionDashboards(hashes)) : /* @__PURE__ */ new Map();
293
293
  let items = hashes.map((h) => dashboards.get(h)).filter((d) => !!d).map((d) => mapDashboardTx(chain, address, d));
294
- items.sort((a, b) => (b.block === void 0 ? 1 : a.block === void 0 ? -1 : Number(b.block - a.block)) || b.time - a.time);
294
+ items.sort((a, b) => (b.block === void 0 ? 1 : a.block === void 0 ? -1 : b.block > a.block ? 1 : b.block < a.block ? -1 : 0) || b.time - a.time);
295
295
  let more = total !== void 0 ? offset + hashes.length < total : hashes.length === pageSize;
296
296
  if (query.since !== void 0) {
297
297
  const since = query.since;
@@ -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 : Number(b.block - a.block)) || 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 } 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 try { env = (await res.json()) as typeof env } catch { /* handled below */ }\n const hash = env.data?.transaction_hash\n if (hash) return hash\n const reason = env.context?.error ?? `${res.status} ${res.statusText}`\n // A rejected transaction is the node's verdict, not a transport failure — a plain Error (not NetworkError), so failover does not retry it elsewhere.\n throw new Error(`Broadcast rejected: ${reason}`)\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\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 tip 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: picked from the tip height\n * (`branchIdForHeight`) — set this when a network upgrade activates before\n * the package learns its id.\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 } 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 try { env = (await res.json()) as typeof env } catch { /* handled below */ }\n const hash = env.data?.transaction_hash\n if (hash) return hash\n const reason = env.context?.error ?? `${res.status} ${res.statusText}`\n // A rejected transaction is the node's verdict, not a transport failure — a plain Error (not NetworkError), so failover does not retry it elsewhere.\n throw new Error(`Broadcast rejected: ${reason}`)\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\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 tip 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: picked from the tip height\n * (`branchIdForHeight`) — set this when a network upgrade activates before\n * the package learns its id.\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"]}
package/dist/history.js CHANGED
@@ -5,7 +5,7 @@ import {
5
5
  encodeCursor,
6
6
  mapDashboardTx,
7
7
  zcashExplorerTxUrl
8
- } from "./chunk-GJBPCXQK.js";
8
+ } from "./chunk-6C7LNZNX.js";
9
9
  export {
10
10
  HistoryUnavailableError,
11
11
  createZcashHistory,
package/dist/index.cjs CHANGED
@@ -1143,18 +1143,18 @@ var WalletAccountZcash = class _WalletAccountZcash extends WalletAccountReadOnly
1143
1143
  return (await this.buildSignedTransaction(tx)).desc;
1144
1144
  }
1145
1145
  /** Sign without broadcasting. Returns the raw transaction hex. Raw hex input is returned unchanged. */
1146
- async signTransaction(tx) {
1146
+ async signTransaction(tx, options = {}) {
1147
1147
  this.live();
1148
1148
  if (typeof tx === "string") return tx;
1149
1149
  const built = await this.buildSignedTransaction(tx);
1150
- this.checkMax(built.fee, this._config.transactionMaxFee, "transaction");
1150
+ this.checkMax(built.fee, (0, import_core7.feeLimit)(this._config.transactionMaxFee, options), "transaction");
1151
1151
  return built.hex;
1152
1152
  }
1153
1153
  async quoteSendTransaction(tx) {
1154
1154
  if (typeof tx === "string") return { fee: (await this.describeRaw(tx)).desc.fee };
1155
1155
  return super.quoteSendTransaction(tx);
1156
1156
  }
1157
- async sendTransaction(tx) {
1157
+ async sendTransaction(tx, options = {}) {
1158
1158
  this.live();
1159
1159
  const client = this.requireClient("send transactions");
1160
1160
  let rawHex, hash, fee;
@@ -1169,17 +1169,17 @@ var WalletAccountZcash = class _WalletAccountZcash extends WalletAccountReadOnly
1169
1169
  hash = built.txid;
1170
1170
  fee = built.fee;
1171
1171
  }
1172
- this.checkMax(fee, this._config.transactionMaxFee, "transaction");
1172
+ this.checkMax(fee, (0, import_core7.feeLimit)(this._config.transactionMaxFee, options), "transaction");
1173
1173
  const id = await client.broadcast(rawHex);
1174
1174
  return { hash: id || hash, fee };
1175
1175
  }
1176
1176
  /** Native ZEC only (`token` is rejected). Subject to `transferMaxFee`. */
1177
- async transfer(o) {
1177
+ async transfer(o, writeOptions = {}) {
1178
1178
  if (o.token) throw new Error("Tokens are not supported on the zcash blockchain.");
1179
1179
  this.live();
1180
1180
  const client = this.requireClient("transfer");
1181
1181
  const built = await this.buildSignedTransaction({ to: o.recipient, value: o.amount });
1182
- this.checkMax(built.fee, this._config.transferMaxFee, "transfer");
1182
+ this.checkMax(built.fee, (0, import_core7.feeLimit)(this._config.transferMaxFee, writeOptions), "transfer");
1183
1183
  const id = await client.broadcast(built.hex);
1184
1184
  return { hash: id || built.txid, fee: built.fee };
1185
1185
  }
@@ -1213,29 +1213,25 @@ var WalletManagerZcash = class extends import_core8.WalletManager {
1213
1213
  if (cached) return cached;
1214
1214
  const external = this.externalSigner();
1215
1215
  if (external) return this.fromSigner(external, full);
1216
- const signer = import_core8.LocalSigner.leafFromSeed(this.seedBytes(), "secp256k1", full);
1217
- const account = new WalletAccountZcash(signer, signer.publicKey, full, this._config);
1218
- this._accounts.set(full, account);
1219
- return account;
1216
+ return this.cachedAccount(full, () => {
1217
+ const signer = import_core8.LocalSigner.leafFromSeed(this.seedBytes(), "secp256k1", full);
1218
+ return new WalletAccountZcash(signer, signer.publicKey, full, this._config);
1219
+ });
1220
1220
  }
1221
1221
  async fromSigner(signer, path) {
1222
1222
  this.requireSigner("secp256k1");
1223
- let leaf = signer;
1223
+ let rel;
1224
1224
  let key = "external";
1225
1225
  if ((0, import_core8.isSeedSigner)(signer)) {
1226
1226
  if (path === signer.path) key = path;
1227
1227
  else if (path.startsWith(`${signer.path}/`)) {
1228
- leaf = await (signer.deriveLeaf ?? signer.derive).call(signer, path.slice(signer.path.length + 1));
1228
+ rel = path.slice(signer.path.length + 1);
1229
1229
  key = path;
1230
1230
  } else throw new import_core8.SignerError(`The injected signer sits at ${signer.path}; it cannot provide ${path}.`);
1231
1231
  } else if (path !== `${this.basePath}/0'/0/0` && path !== "external") {
1232
1232
  throw new import_core8.SignerError(`An external signer has one account; ${path} is not derivable from it.`);
1233
1233
  }
1234
- const cached = this._accounts.get(key);
1235
- if (cached) return cached;
1236
- const account = new WalletAccountZcash(leaf, await leaf.getPublicKey(), key, this._config);
1237
- this._accounts.set(key, account);
1238
- return account;
1234
+ return this.signerAccount(key, signer, rel, (leaf, publicKey) => new WalletAccountZcash(leaf, publicKey, key, this._config));
1239
1235
  }
1240
1236
  /** A read-only account for any transparent address, with this manager's config. */
1241
1237
  getReadOnlyAccount(address) {
@@ -1334,7 +1330,7 @@ function createZcashHistory(options = {}) {
1334
1330
  const { hashes, total } = await wrap(() => client.listTransactions(address, pageSize, offset));
1335
1331
  const dashboards = hashes.length ? await wrap(() => client.getTransactionDashboards(hashes)) : /* @__PURE__ */ new Map();
1336
1332
  let items = hashes.map((h2) => dashboards.get(h2)).filter((d) => !!d).map((d) => mapDashboardTx(chain, address, d));
1337
- items.sort((a, b) => (b.block === void 0 ? 1 : a.block === void 0 ? -1 : Number(b.block - a.block)) || b.time - a.time);
1333
+ items.sort((a, b) => (b.block === void 0 ? 1 : a.block === void 0 ? -1 : b.block > a.block ? 1 : b.block < a.block ? -1 : 0) || b.time - a.time);
1338
1334
  let more = total !== void 0 ? offset + hashes.length < total : hashes.length === pageSize;
1339
1335
  if (query.since !== void 0) {
1340
1336
  const since = query.since;