@anywalletkit/wallet-zcash 0.0.0-stage → 0.2.1

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.
@@ -0,0 +1,421 @@
1
+ // src/blockchair.ts
2
+ import { NetworkError as NetworkError2 } from "@anywalletkit/core";
3
+
4
+ // src/encoding.ts
5
+ import { bytesToHex, hexToBytes, concatBytes, utf8ToBytes } from "@noble/hashes/utils.js";
6
+ function compactSize(n) {
7
+ if (!Number.isInteger(n) || n < 0) throw new Error(`CompactSize: ${n} is not a non-negative integer`);
8
+ if (n < 253) return Uint8Array.of(n);
9
+ if (n <= 65535) return Uint8Array.of(253, n & 255, n >>> 8);
10
+ if (n <= 4294967295) return Uint8Array.of(254, n & 255, n >>> 8 & 255, n >>> 16 & 255, n >>> 24);
11
+ throw new Error("CompactSize: value too large");
12
+ }
13
+ function u32le(n) {
14
+ if (!Number.isInteger(n) || n < 0 || n > 4294967295) throw new Error(`u32: ${n} out of range`);
15
+ return Uint8Array.of(n & 255, n >>> 8 & 255, n >>> 16 & 255, n >>> 24);
16
+ }
17
+ function i64le(v) {
18
+ if (v < -(1n << 63n) || v >= 1n << 63n) throw new Error(`i64: ${v} out of range`);
19
+ let x = v < 0n ? v + (1n << 64n) : v;
20
+ const out = new Uint8Array(8);
21
+ for (let i = 0; i < 8; i++) {
22
+ out[i] = Number(x & 0xffn);
23
+ x >>= 8n;
24
+ }
25
+ return out;
26
+ }
27
+ var Writer = class {
28
+ parts = [];
29
+ u8(n) {
30
+ this.parts.push(Uint8Array.of(n & 255));
31
+ return this;
32
+ }
33
+ u32(n) {
34
+ this.parts.push(u32le(n));
35
+ return this;
36
+ }
37
+ i64(v) {
38
+ this.parts.push(i64le(v));
39
+ return this;
40
+ }
41
+ bytes(b) {
42
+ this.parts.push(b);
43
+ return this;
44
+ }
45
+ compact(n) {
46
+ this.parts.push(compactSize(n));
47
+ return this;
48
+ }
49
+ /** CompactSize length prefix + bytes (the "field encoding" of a script). */
50
+ varBytes(b) {
51
+ return this.compact(b.length).bytes(b);
52
+ }
53
+ finish() {
54
+ const len = this.parts.reduce((s, p) => s + p.length, 0);
55
+ const out = new Uint8Array(len);
56
+ let o = 0;
57
+ for (const p of this.parts) {
58
+ out.set(p, o);
59
+ o += p.length;
60
+ }
61
+ return out;
62
+ }
63
+ };
64
+ var Reader = class {
65
+ constructor(buf) {
66
+ this.buf = buf;
67
+ }
68
+ buf;
69
+ offset = 0;
70
+ get remaining() {
71
+ return this.buf.length - this.offset;
72
+ }
73
+ need(n) {
74
+ if (this.offset + n > this.buf.length) throw new Error("Transaction truncated");
75
+ }
76
+ u8() {
77
+ this.need(1);
78
+ return this.buf[this.offset++];
79
+ }
80
+ u32() {
81
+ this.need(4);
82
+ const b = this.buf;
83
+ const o = this.offset;
84
+ this.offset += 4;
85
+ return (b[o] | b[o + 1] << 8 | b[o + 2] << 16) + b[o + 3] * 16777216;
86
+ }
87
+ i64() {
88
+ this.need(8);
89
+ let v = 0n;
90
+ for (let i = 7; i >= 0; i--) v = v << 8n | BigInt(this.buf[this.offset + i]);
91
+ this.offset += 8;
92
+ return v >= 1n << 63n ? v - (1n << 64n) : v;
93
+ }
94
+ bytes(n) {
95
+ this.need(n);
96
+ const out = this.buf.slice(this.offset, this.offset + n);
97
+ this.offset += n;
98
+ return out;
99
+ }
100
+ compact() {
101
+ const first = this.u8();
102
+ if (first < 253) return first;
103
+ if (first === 253) {
104
+ this.need(2);
105
+ const v = this.buf[this.offset] | this.buf[this.offset + 1] << 8;
106
+ this.offset += 2;
107
+ return v;
108
+ }
109
+ if (first === 254) return this.u32();
110
+ throw new Error("CompactSize: 64-bit lengths are not supported");
111
+ }
112
+ varBytes() {
113
+ return this.bytes(this.compact());
114
+ }
115
+ };
116
+ function reverseBytes(b) {
117
+ return Uint8Array.from(b).reverse();
118
+ }
119
+
120
+ // src/http.ts
121
+ import { NetworkError } from "@anywalletkit/core";
122
+ var DEFAULT_TIMEOUT_MS = 15e3;
123
+ async function fetchWithTimeout(fetchFn, url, init, timeoutMs, provider) {
124
+ const signal = typeof AbortSignal !== "undefined" && typeof AbortSignal.timeout === "function" ? AbortSignal.timeout(timeoutMs) : void 0;
125
+ try {
126
+ return await fetchFn(url, { ...init, ...signal ? { signal } : {} });
127
+ } catch (e) {
128
+ throw new NetworkError(`Request failed: ${url}`, { provider, cause: e });
129
+ }
130
+ }
131
+ var isRecord = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
132
+ var isIntString = (v) => typeof v === "string" && /^-?\d+$/.test(v);
133
+ var isInt = (v) => typeof v === "number" && Number.isInteger(v);
134
+
135
+ // src/blockchair.ts
136
+ var BLOCKCHAIR_URL = "https://api.blockchair.com/zcash";
137
+ var UTXO_LIMIT = 1e3;
138
+ var isUtxo = (v) => isRecord(v) && isInt(v.block_id) && typeof v.transaction_hash === "string" && isInt(v.index) && typeof v.value === "number";
139
+ var isOutput = (v) => isRecord(v) && isInt(v.index) && typeof v.value === "number" && typeof v.script_hex === "string";
140
+ var isDashboard = (v) => 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);
141
+ function blockchairTime(s) {
142
+ if (!s) return void 0;
143
+ const t = Date.parse(`${s.replace(" ", "T")}Z`);
144
+ return Number.isFinite(t) ? Math.floor(t / 1e3) : void 0;
145
+ }
146
+ var BlockchairClient = class {
147
+ base;
148
+ key;
149
+ fetchFn;
150
+ timeoutMs;
151
+ constructor(config = {}, fetchFn = globalThis.fetch, timeoutMs = DEFAULT_TIMEOUT_MS) {
152
+ this.base = (config.url ?? BLOCKCHAIR_URL).replace(/\/+$/, "");
153
+ this.key = config.key;
154
+ this.fetchFn = fetchFn;
155
+ this.timeoutMs = timeoutMs;
156
+ }
157
+ async connect() {
158
+ }
159
+ async close() {
160
+ }
161
+ url(path, query = {}) {
162
+ const q = new URLSearchParams(query);
163
+ if (this.key) q.set("key", this.key);
164
+ const s = q.toString();
165
+ return `${this.base}/${path}${s ? `?${s}` : ""}`;
166
+ }
167
+ async request(path, query, init, check) {
168
+ const url = this.url(path, query);
169
+ const res = await fetchWithTimeout(this.fetchFn, url, init, this.timeoutMs, this.base);
170
+ let body;
171
+ try {
172
+ body = await res.json();
173
+ } catch (e) {
174
+ if (res.status === 402 || res.status === 429 || res.status === 430) throw new NetworkError2(`Blockchair rate limit (${res.status})`, { provider: this.base });
175
+ throw new NetworkError2(`Blockchair returned non-JSON (${res.status}) for ${url}`, { provider: this.base, cause: e });
176
+ }
177
+ const env = body;
178
+ const code = env.context?.code ?? res.status;
179
+ if (code === 402 || code === 429 || code === 430) throw new NetworkError2(`Blockchair rate limit (${code})`, { provider: this.base });
180
+ if (code === 404) throw new NotFound();
181
+ if (code !== 200 || !res.ok) throw new NetworkError2(`Blockchair request failed: ${code} ${env.context?.error ?? res.statusText} (${url})`, { provider: this.base });
182
+ if (!check(env.data)) throw new NetworkError2(`Blockchair returned an unexpected shape for ${url}`, { provider: this.base });
183
+ return { data: env.data, state: env.context?.state };
184
+ }
185
+ async dashboard(address) {
186
+ const { data, state } = await this.request(`dashboards/address/${address}`, { limit: `0,${UTXO_LIMIT}` }, void 0, (v) => 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)));
187
+ const entry = data[address] ?? Object.values(data)[0];
188
+ if (!entry) throw new NetworkError2(`Blockchair knows no address ${address}`, { provider: this.base });
189
+ return { address: entry.address, utxo: entry.utxo, transactions: entry.transactions ?? [], state };
190
+ }
191
+ /** Transaction hashes of an address, newest first, paged by offset (what the activity history walks). */
192
+ async listTransactions(address, limit, offset) {
193
+ const { data } = await this.request(`dashboards/address/${address}`, { limit: `${limit},0`, offset: `${offset},0` }, void 0, (v) => isRecord(v) && Object.values(v).every((a) => isRecord(a) && isRecord(a.address) && (a.transactions === void 0 || Array.isArray(a.transactions))));
194
+ const entry = data[address] ?? Object.values(data)[0];
195
+ if (!entry) throw new NetworkError2(`Blockchair knows no address ${address}`, { provider: this.base });
196
+ return { hashes: (entry.transactions ?? []).filter((h) => typeof h === "string"), total: entry.address.transaction_count };
197
+ }
198
+ /** Confirmed = the UTXOs mined so far; unconfirmed = incoming mempool outputs. (Beyond 1000 UTXOs the dashboard balance is used.) */
199
+ async getBalance(address) {
200
+ const d = await this.dashboard(address);
201
+ let confirmed = 0n, unconfirmed = 0n;
202
+ for (const u of d.utxo) {
203
+ if (u.block_id > 0) confirmed += BigInt(u.value);
204
+ else unconfirmed += BigInt(u.value);
205
+ }
206
+ if ((d.address.unspent_output_count ?? d.utxo.length) > d.utxo.length) confirmed = BigInt(d.address.balance) - unconfirmed;
207
+ return { confirmed, unconfirmed };
208
+ }
209
+ async listUnspent(address) {
210
+ const d = await this.dashboard(address);
211
+ 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 }));
212
+ }
213
+ async getTransaction(txid) {
214
+ const { data } = await this.request(`raw/transaction/${txid}`, {}, void 0, (v) => isRecord(v) && Object.values(v).every((t) => isRecord(t) && typeof t.raw_transaction === "string"));
215
+ const hex = (data[txid] ?? Object.values(data)[0])?.raw_transaction;
216
+ if (!hex) throw new NetworkError2(`Transaction ${txid} has no raw data`, { provider: this.base });
217
+ return hex;
218
+ }
219
+ /** Inputs / outputs with addresses, values and scripts — what the activity history and prevout lookups read. */
220
+ async getTransactionDashboard(txid) {
221
+ try {
222
+ const { data, state } = await this.request(`dashboards/transaction/${txid}`, {}, void 0, (v) => isRecord(v) && Object.values(v).every((t2) => t2 === null || isDashboard(t2)));
223
+ const t = data[txid] ?? Object.values(data)[0];
224
+ if (!t) return void 0;
225
+ return { ...t, transaction: { ...t.transaction, ...state !== void 0 ? { confirmations: t.transaction.block_id > 0 ? state - t.transaction.block_id + 1 : 0 } : {} } };
226
+ } catch (e) {
227
+ if (e instanceof NotFound) return void 0;
228
+ throw e;
229
+ }
230
+ }
231
+ /** Several transactions in one call (Blockchair takes up to 10 comma-separated hashes). */
232
+ async getTransactionDashboards(txids) {
233
+ const out = /* @__PURE__ */ new Map();
234
+ for (let i = 0; i < txids.length; i += 10) {
235
+ const slice = txids.slice(i, i + 10);
236
+ const { data, state } = await this.request(`dashboards/transactions/${slice.join(",")}`, {}, void 0, (v) => isRecord(v) && Object.values(v).every((t) => t === null || isDashboard(t)));
237
+ for (const [hash, t] of Object.entries(data)) {
238
+ if (!t) continue;
239
+ const confirmations = state !== void 0 && t.transaction.block_id > 0 ? state - t.transaction.block_id + 1 : 0;
240
+ out.set(hash, { ...t, transaction: { ...t.transaction, confirmations } });
241
+ }
242
+ }
243
+ return out;
244
+ }
245
+ async getOutput(txid, vout) {
246
+ const d = await this.getTransactionDashboard(txid);
247
+ const o = d?.outputs.find((x) => x.index === vout);
248
+ return o ? { value: BigInt(o.value), script: hexToBytes(o.script_hex) } : void 0;
249
+ }
250
+ async getTransactionInfo(txid) {
251
+ const d = await this.getTransactionDashboard(txid);
252
+ if (!d) return void 0;
253
+ const t = d.transaction;
254
+ const info = { txid: t.hash, blockHeight: t.block_id > 0 ? t.block_id : -1, confirmations: t.confirmations ?? 0 };
255
+ if (typeof t.fee === "number") info.fee = BigInt(t.fee);
256
+ const time = blockchairTime(t.time);
257
+ if (time !== void 0) info.blockTime = time;
258
+ return info;
259
+ }
260
+ async broadcast(rawTx) {
261
+ const body = `data=${encodeURIComponent(rawTx)}`;
262
+ const url = this.url("push/transaction");
263
+ const res = await fetchWithTimeout(this.fetchFn, url, { method: "POST", headers: { "content-type": "application/x-www-form-urlencoded" }, body }, this.timeoutMs, this.base);
264
+ let env = {};
265
+ try {
266
+ env = await res.json();
267
+ } catch {
268
+ }
269
+ const hash = env.data?.transaction_hash;
270
+ if (hash) return hash;
271
+ const reason = env.context?.error ?? `${res.status} ${res.statusText}`;
272
+ throw new Error(`Broadcast rejected: ${reason}`);
273
+ }
274
+ async getBlockHeight() {
275
+ const { data } = await this.request("stats", {}, void 0, (v) => isRecord(v) && isInt(v.best_block_height));
276
+ if (data.best_block_height <= 0) throw new NetworkError2("Blockchair reported no block height", { provider: this.base });
277
+ return data.best_block_height;
278
+ }
279
+ };
280
+ var NotFound = class extends Error {
281
+ constructor() {
282
+ super("not found");
283
+ this.name = "NotFound";
284
+ }
285
+ };
286
+
287
+ // src/types.ts
288
+ var CAIP2 = { mainnet: "zcash:mainnet", testnet: "zcash:testnet" };
289
+
290
+ // src/history.ts
291
+ var HistoryUnavailableError = class extends Error {
292
+ chain;
293
+ reason;
294
+ constructor(chain, reason) {
295
+ super(`History unavailable for ${chain}: ${reason}`);
296
+ this.name = "HistoryUnavailableError";
297
+ this.chain = chain;
298
+ this.reason = reason;
299
+ }
300
+ };
301
+ var DEFAULT_LIMIT = 25;
302
+ var MAX_PAGE_SIZE = 100;
303
+ function encodeCursor(c) {
304
+ return `${c.v}:${c.o}:${c.s}`;
305
+ }
306
+ function decodeCursor(s) {
307
+ const m = /^1:(\d+):(\d+)$/.exec(s);
308
+ if (!m) throw new Error("@anywalletkit/wallet-zcash: malformed history cursor");
309
+ const o = Number(m[1]), size = Number(m[2]);
310
+ if (size < 1) throw new Error("@anywalletkit/wallet-zcash: malformed history cursor");
311
+ return { v: 1, o, s: size };
312
+ }
313
+ function mapDashboardTx(chain, address, d) {
314
+ let ownIn = 0n, ownOut = 0n, sentToOthers = 0n;
315
+ for (const i of d.inputs) if (i.recipient === address) ownIn += BigInt(i.value);
316
+ for (const o of d.outputs) {
317
+ if (o.recipient === address) ownOut += BigInt(o.value);
318
+ else sentToOthers += BigInt(o.value);
319
+ }
320
+ const firstInput = d.inputs.find((i) => i.recipient)?.recipient;
321
+ const firstOther = d.outputs.find((o) => o.recipient && o.recipient !== address)?.recipient;
322
+ const transfers = [];
323
+ let from, to, nativeValue;
324
+ if (ownIn > 0n) {
325
+ from = address;
326
+ to = firstOther ?? address;
327
+ nativeValue = firstOther ? sentToOthers : ownOut;
328
+ if (nativeValue > 0n) transfers.push({ token: null, from: address, to, amount: nativeValue });
329
+ } else {
330
+ from = firstInput ?? (d.inputs.length === 0 ? "shielded" : "coinbase");
331
+ to = address;
332
+ nativeValue = ownOut;
333
+ if (nativeValue > 0n) transfers.push({ token: null, from, to: address, amount: nativeValue });
334
+ }
335
+ const t = d.transaction;
336
+ const confirmed = t.block_id > 0;
337
+ const out = {
338
+ chain,
339
+ hash: t.hash,
340
+ time: blockchairTime(t.time) ?? 0,
341
+ status: confirmed ? "confirmed" : "pending",
342
+ address,
343
+ from,
344
+ to,
345
+ nativeValue,
346
+ transfers,
347
+ raw: { tx: d, ownIn, ownOut }
348
+ };
349
+ if (typeof t.fee === "number") out.fee = BigInt(t.fee);
350
+ if (confirmed) out.block = BigInt(t.block_id);
351
+ return out;
352
+ }
353
+ function zcashExplorerTxUrl(hash) {
354
+ return `https://blockchair.com/zcash/transaction/${hash}`;
355
+ }
356
+ function createZcashHistory(options = {}) {
357
+ const chain = CAIP2.mainnet;
358
+ const fetchFn = options.fetch ?? globalThis.fetch;
359
+ if (typeof fetchFn !== "function") throw new Error("@anywalletkit/wallet-zcash: no global fetch; pass `fetch` in the options");
360
+ const client = new BlockchairClient({ ...options.blockchairUrl ? { url: options.blockchairUrl } : {}, ...options.key ? { key: options.key } : {} }, fetchFn, options.timeoutMs ?? DEFAULT_TIMEOUT_MS);
361
+ const wrap = async (run) => {
362
+ try {
363
+ return await run();
364
+ } catch (e) {
365
+ throw new HistoryUnavailableError(chain, e instanceof Error ? e.message : String(e));
366
+ }
367
+ };
368
+ return {
369
+ chain,
370
+ async listActivity(address, query = {}) {
371
+ const cursor = query.cursor ? decodeCursor(query.cursor) : void 0;
372
+ const pageSize = cursor?.s ?? Math.min(MAX_PAGE_SIZE, Math.max(1, Math.floor(options.pageSize ?? query.limit ?? DEFAULT_LIMIT)));
373
+ const offset = cursor?.o ?? 0;
374
+ const { hashes, total } = await wrap(() => client.listTransactions(address, pageSize, offset));
375
+ const dashboards = hashes.length ? await wrap(() => client.getTransactionDashboards(hashes)) : /* @__PURE__ */ new Map();
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);
378
+ let more = total !== void 0 ? offset + hashes.length < total : hashes.length === pageSize;
379
+ if (query.since !== void 0) {
380
+ const since = query.since;
381
+ if (items.some((t) => t.status === "confirmed" && t.time < since)) more = false;
382
+ items = items.filter((t) => t.status !== "confirmed" || t.time >= since);
383
+ }
384
+ const page = { items, offset, ...total !== void 0 ? { total } : {} };
385
+ if (more) page.cursor = encodeCursor({ v: 1, o: offset + hashes.length, s: pageSize });
386
+ return page;
387
+ },
388
+ async getTransaction(hash, address) {
389
+ const d = await wrap(() => client.getTransactionDashboard(hash));
390
+ return d ? mapDashboardTx(chain, address, d) : void 0;
391
+ },
392
+ explorerTxUrl: zcashExplorerTxUrl
393
+ };
394
+ }
395
+
396
+ export {
397
+ CAIP2,
398
+ compactSize,
399
+ u32le,
400
+ Writer,
401
+ Reader,
402
+ reverseBytes,
403
+ bytesToHex,
404
+ hexToBytes,
405
+ utf8ToBytes,
406
+ DEFAULT_TIMEOUT_MS,
407
+ fetchWithTimeout,
408
+ isRecord,
409
+ isIntString,
410
+ isInt,
411
+ BLOCKCHAIR_URL,
412
+ blockchairTime,
413
+ BlockchairClient,
414
+ HistoryUnavailableError,
415
+ encodeCursor,
416
+ decodeCursor,
417
+ mapDashboardTx,
418
+ zcashExplorerTxUrl,
419
+ createZcashHistory
420
+ };
421
+ //# sourceMappingURL=chunk-GJBPCXQK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/blockchair.ts","../src/encoding.ts","../src/http.ts","../src/types.ts","../src/history.ts"],"sourcesContent":["/**\n * Blockchair REST transport (`https://api.blockchair.com/zcash`): public, CORS\n * open, no key needed at wallet volumes (one request every couple of seconds;\n * a `key` lifts the quota). Mainnet only — Blockchair indexes no Zcash\n * testnet. Address dashboards carry the UTXO set (mempool included, block_id\n * -1), `raw/transaction` the hex, `push/transaction` broadcasts.\n */\nimport { NetworkError } from '@anywalletkit/core'\nimport { hexToBytes } from './encoding.js'\nimport { DEFAULT_TIMEOUT_MS, fetchWithTimeout, isInt, isRecord } 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"]}