crypto-aio 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +151 -1
- package/README.md +32 -12
- package/dist/adapters/evm/builder.js +64 -4
- package/dist/adapters/evm/builder.js.map +1 -1
- package/dist/adapters/evm/decode.js +6 -1
- package/dist/adapters/evm/decode.js.map +1 -1
- package/dist/adapters/evm/ethers-client.js +4 -0
- package/dist/adapters/evm/ethers-client.js.map +1 -1
- package/dist/adapters/evm/fees.d.ts +24 -0
- package/dist/adapters/evm/fees.js +47 -4
- package/dist/adapters/evm/fees.js.map +1 -1
- package/dist/adapters/evm/index.d.ts +1 -1
- package/dist/adapters/evm/index.js +2 -1
- package/dist/adapters/evm/index.js.map +1 -1
- package/dist/adapters/evm/network.d.ts +5 -0
- package/dist/adapters/evm/network.js +21 -2
- package/dist/adapters/evm/network.js.map +1 -1
- package/dist/adapters/evm/plugin.d.ts +5 -6
- package/dist/adapters/evm/plugin.js +50 -2
- package/dist/adapters/evm/plugin.js.map +1 -1
- package/dist/adapters/evm/proofs.js +17 -5
- package/dist/adapters/evm/proofs.js.map +1 -1
- package/dist/adapters/evm/reader.d.ts +18 -0
- package/dist/adapters/evm/reader.js +34 -0
- package/dist/adapters/evm/reader.js.map +1 -1
- package/dist/adapters/evm/tokens.d.ts +3 -0
- package/dist/adapters/evm/tokens.js.map +1 -1
- package/dist/adapters/evm/types.d.ts +10 -0
- package/dist/adapters/evm/types.js.map +1 -1
- package/dist/adapters/evm/web3-client.d.ts +6 -3
- package/dist/adapters/evm/web3-client.js +19 -2
- package/dist/adapters/evm/web3-client.js.map +1 -1
- package/dist/adapters/solana/builder.js +29 -18
- package/dist/adapters/solana/builder.js.map +1 -1
- package/dist/adapters/solana/fees.d.ts +12 -3
- package/dist/adapters/solana/fees.js +13 -4
- package/dist/adapters/solana/fees.js.map +1 -1
- package/dist/adapters/solana/message.d.ts +15 -0
- package/dist/adapters/solana/message.js +120 -0
- package/dist/adapters/solana/message.js.map +1 -0
- package/dist/adapters/solana/plugin.js +4 -1
- package/dist/adapters/solana/plugin.js.map +1 -1
- package/dist/adapters/solana/types.d.ts +8 -5
- package/dist/adapters/solana/types.js.map +1 -1
- package/dist/adapters/solana/web3.js +10 -32
- package/dist/adapters/solana/web3.js.map +1 -1
- package/dist/adapters/ton/proofs.js +18 -76
- package/dist/adapters/ton/proofs.js.map +1 -1
- package/dist/adapters/ton/reader.d.ts +45 -4
- package/dist/adapters/ton/reader.js +200 -5
- package/dist/adapters/ton/reader.js.map +1 -1
- package/dist/adapters/ton/trace.d.ts +26 -0
- package/dist/adapters/ton/trace.js +35 -9
- package/dist/adapters/ton/trace.js.map +1 -1
- package/dist/adapters/tron/abi.d.ts +2 -0
- package/dist/adapters/tron/abi.js +2 -0
- package/dist/adapters/tron/abi.js.map +1 -1
- package/dist/adapters/tron/builder.js +20 -4
- package/dist/adapters/tron/builder.js.map +1 -1
- package/dist/adapters/tron/decode.d.ts +2 -0
- package/dist/adapters/tron/decode.js +1 -1
- package/dist/adapters/tron/decode.js.map +1 -1
- package/dist/adapters/tron/proofs.js +1 -0
- package/dist/adapters/tron/proofs.js.map +1 -1
- package/dist/adapters/tron/reader.d.ts +10 -0
- package/dist/adapters/tron/reader.js +17 -0
- package/dist/adapters/tron/reader.js.map +1 -1
- package/dist/adapters/tron/tokens.d.ts +2 -0
- package/dist/adapters/tron/tokens.js.map +1 -1
- package/dist/adapters/utxo/builder.js +1 -1
- package/dist/adapters/utxo/builder.js.map +1 -1
- package/dist/adapters/utxo/chains.js +2 -1
- package/dist/adapters/utxo/chains.js.map +1 -1
- package/dist/adapters/utxo/context.d.ts +6 -0
- package/dist/adapters/utxo/context.js +8 -1
- package/dist/adapters/utxo/context.js.map +1 -1
- package/dist/adapters/utxo/decode.d.ts +8 -0
- package/dist/adapters/utxo/decode.js +36 -0
- package/dist/adapters/utxo/decode.js.map +1 -1
- package/dist/adapters/utxo/driver.js +5 -0
- package/dist/adapters/utxo/driver.js.map +1 -1
- package/dist/adapters/utxo/esplora.d.ts +23 -2
- package/dist/adapters/utxo/esplora.js +49 -2
- package/dist/adapters/utxo/esplora.js.map +1 -1
- package/dist/adapters/utxo/proofs.d.ts +15 -6
- package/dist/adapters/utxo/proofs.js +185 -47
- package/dist/adapters/utxo/proofs.js.map +1 -1
- package/dist/adapters/utxo/rawblock.d.ts +46 -0
- package/dist/adapters/utxo/rawblock.js +159 -0
- package/dist/adapters/utxo/rawblock.js.map +1 -0
- package/dist/adapters/utxo/rawtx.d.ts +14 -0
- package/dist/adapters/utxo/rawtx.js +44 -14
- package/dist/adapters/utxo/rawtx.js.map +1 -1
- package/dist/core/blockchain/handle.d.ts +6 -27
- package/dist/core/blockchain/handle.js +112 -112
- package/dist/core/blockchain/handle.js.map +1 -1
- package/dist/core/config/types.d.ts +15 -0
- package/dist/core/config/types.js.map +1 -1
- package/dist/core/container/container.d.ts +1 -8
- package/dist/core/container/container.js +42 -8
- package/dist/core/container/container.js.map +1 -1
- package/dist/core/driver/types.d.ts +34 -1
- package/dist/core/driver/types.js.map +1 -1
- package/dist/core/errors/codes.d.ts +10 -0
- package/dist/core/errors/codes.js +4 -0
- package/dist/core/errors/codes.js.map +1 -1
- package/dist/core/lifecycle/engine-rules.d.ts +3 -4
- package/dist/core/lifecycle/engine-rules.js +16 -6
- package/dist/core/lifecycle/engine-rules.js.map +1 -1
- package/dist/core/lifecycle/engine.d.ts +2 -0
- package/dist/core/lifecycle/engine.js +19 -1
- package/dist/core/lifecycle/engine.js.map +1 -1
- package/dist/core/lifecycle/evaluate.js +9 -4
- package/dist/core/lifecycle/evaluate.js.map +1 -1
- package/dist/core/lifecycle/monitor.js +16 -6
- package/dist/core/lifecycle/monitor.js.map +1 -1
- package/dist/core/lifecycle/reconcile.d.ts +1 -1
- package/dist/core/lifecycle/reconcile.js +1 -1
- package/dist/core/lifecycle/reconcile.js.map +1 -1
- package/dist/core/lifecycle/workers.d.ts +9 -3
- package/dist/core/lifecycle/workers.js +32 -14
- package/dist/core/lifecycle/workers.js.map +1 -1
- package/dist/core/model/ids.d.ts +1 -0
- package/dist/core/model/ids.js +1 -0
- package/dist/core/model/ids.js.map +1 -1
- package/dist/core/model/ordering.d.ts +8 -0
- package/dist/core/model/ordering.js.map +1 -1
- package/dist/core/model/transaction.d.ts +7 -0
- package/dist/core/model/transaction.js.map +1 -1
- package/dist/core/observe/scanner.js +3 -0
- package/dist/core/observe/scanner.js.map +1 -1
- package/dist/core/signing/wallet.js +8 -0
- package/dist/core/signing/wallet.js.map +1 -1
- package/dist/core/store/format.d.ts +20 -0
- package/dist/core/store/format.js +86 -0
- package/dist/core/store/format.js.map +1 -0
- package/dist/core/store/memory.js +2 -2
- package/dist/core/store/memory.js.map +1 -1
- package/dist/core/store/types.d.ts +15 -3
- package/dist/core/store/types.js +2 -0
- package/dist/core/store/types.js.map +1 -1
- package/dist/core/transport/http-transport.js +21 -13
- package/dist/core/transport/http-transport.js.map +1 -1
- package/dist/core/transport/types.d.ts +16 -1
- package/dist/core/transport/types.js.map +1 -1
- package/dist/core/util/json.d.ts +7 -1
- package/dist/core/util/json.js +13 -4
- package/dist/core/util/json.js.map +1 -1
- package/dist/core/util/names.d.ts +6 -0
- package/dist/core/util/names.js +10 -0
- package/dist/core/util/names.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/testing/contracts/operations.js +20 -1
- package/dist/testing/contracts/operations.js.map +1 -1
- package/dist/testing/env.d.ts +5 -0
- package/dist/testing/env.js +1 -1
- package/dist/testing/env.js.map +1 -1
- package/dist/testing/faulty-store.d.ts +2 -0
- package/dist/testing/faulty-store.js +5 -0
- package/dist/testing/faulty-store.js.map +1 -1
- package/package.json +17 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workers.js","sourceRoot":"","sources":["../../../src/core/lifecycle/workers.ts"],"names":[],"mappings":"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","sourcesContent":["import { ConfigError, isCryptoAioError } from '../errors/error';\nimport {\n NON_TERMINAL_STATES,\n isTerminal,\n type Fence,\n type OperationClaim,\n type OperationPatch,\n type OperationRecord,\n} from '../store/types';\nimport { randomId } from '../util/bytes';\nimport type { ReadTarget } from './engine';\nimport { PRE_SIGNING_STATES, errorCode } from './engine-rules';\nimport type { MonitorDeps, ReadResolver, TargetResolver } from './monitor';\n\n/*\n * The monitor's background worker loop and startup recovery (`Monitor` delegates to\n * `Workers`). They check Operations through the monitor\n * (`MonitorChecks`) and write only through the engine.\n */\n\n/**\n * What `recover()` did. The counts are per Operation, except `reconciled`, and they\n * overlap: an Operation whose resend was attempted and whose check then failed counts in\n * both `rebroadcast` and `failed`.\n */\nexport interface RecoveryReport {\n /**\n * `signed` or ambiguously `submitted` Operations whose stored bytes were sent again:\n * attempted resends, including ones the node refused or whose outcome is unknown.\n */\n readonly rebroadcast: number;\n /** Operations checked on chain after any resend. */\n readonly checked: number;\n /** Operations that need a caller (see `recovery.skipped`); never resent or checked. */\n readonly skipped: number;\n /** Operations whose target could not be rebuilt, or whose resend or check threw. */\n readonly failed: number;\n /** Leaked nonce values that reconciliation returned for reuse (across all wallets). */\n readonly reconciled: number;\n}\n\nexport interface WorkerOptions {\n /** Default: a random id per `start` call. */\n readonly workerId?: string;\n readonly signal?: AbortSignal;\n /** How many due Operations one pass claims. Default: 50. */\n readonly batch?: number;\n}\n\nconst DEFAULT_BATCH = 50;\n/** How many Operations' reported gaps a monitor remembers (`nonce.gap` is at-least-once). */\nconst GAP_MEMORY = 10_000;\n\n/** What the worker loop and recovery use of the monitor's own checks. */\nexport interface MonitorChecks {\n checkPass(\n target: ReadTarget,\n op: OperationRecord,\n fence?: Fence,\n signal?: AbortSignal,\n ): Promise<{ readonly record: OperationRecord; readonly stale: boolean }>;\n check(\n target: ReadTarget,\n op: OperationRecord,\n fence?: Fence,\n signal?: AbortSignal,\n ): Promise<OperationRecord>;\n find(ref: string): Promise<OperationRecord | null>;\n}\n\n/** Worker passes and startup recovery for one monitor (see `Monitor`). */\nexport class Workers {\n /**\n * Per Operation, the expected nonces a `nonce.gap` was already emitted for; least\n * recently reported first, capped at `GAP_MEMORY` Operations.\n */\n readonly #gaps = new Map<string, Set<string>>();\n\n constructor(\n private readonly deps: MonitorDeps,\n private readonly monitor: MonitorChecks,\n ) {}\n\n /**\n * One worker pass: claims up to `batch` due Operations, checks each under its claim fence\n * (a stale worker's writes fail), then releases the claim. Every claimed Operation\n * that stays live leaves the pass scheduled a poll interval ahead, including when its\n * check threw, its view was stale or its all-rejected verdict could not run, so no worker\n * claims it again before then. A stale view also skips gap handling and reconciliation.\n * `signal` bounds each check and its lease wait; once it aborts, the Operations not yet\n * checked are only released, still due, for another worker. Returns how many Operations\n * it claimed.\n */\n async runOnce(options: {\n readonly workerId: string;\n readonly batch?: number;\n readonly signal?: AbortSignal;\n }): Promise<number> {\n const { signal } = options;\n if (signal?.aborted) return 0;\n const claimed = await this.deps.stores.operations.claimDue(\n this.deps.namespace,\n options.workerId,\n this.deps.clock.now(),\n this.deps.lifecycle().claimLeaseMs,\n options.batch ?? DEFAULT_BATCH,\n );\n const reads = this.#passResolver(this.deps.resolveRead);\n const writes = this.#passResolver(this.deps.resolveTarget);\n for (const op of claimed) {\n const fence: Fence = { claimToken: (op.claim as OperationClaim).token };\n if (!signal?.aborted) await this.#process(reads, writes, op, fence, signal);\n await this.deps.stores.operations\n .releaseClaim(this.deps.namespace, op.id, fence)\n .catch((error: unknown) =>\n this.deps.log.debug('claim already lost', {\n operationId: op.id,\n code: errorCode(error),\n }),\n );\n }\n return claimed.length;\n }\n\n /** One claimed Operation of a worker pass (see `runOnce`). */\n async #process(\n reads: ReadResolver,\n writes: TargetResolver,\n op: OperationRecord,\n fence: Fence,\n signal: AbortSignal | undefined,\n ): Promise<void> {\n const started = this.deps.clock.now();\n let current: OperationRecord | undefined;\n try {\n const target = await this.#resolved(reads, op);\n const pass = await this.monitor.checkPass(target, op, fence, signal);\n current = pass.record;\n if (!pass.stale) await this.#detectNonceGap(target, current, writes);\n } catch (error) {\n // An abort mid-check is an expected shutdown, not a failure.\n this.deps.log[signal?.aborted ? 'debug' : 'warn'](\n signal?.aborted ? 'monitor check stopped' : 'monitor check failed',\n { operationId: op.id, code: errorCode(error) },\n );\n }\n const scheduled =\n current !== undefined &&\n (isTerminal(current.state) ||\n (current.nextCheckAt !== undefined && current.nextCheckAt > started));\n if (!scheduled) await this.#reschedule(op.id, fence, started);\n }\n\n /**\n * Runs worker passes until `signal` aborts. Any number of workers, in any number of\n * processes, may run: claims keep them apart. A full batch is followed by the next pass at\n * once, anything less by a poll-interval sleep. A failed pass (e.g. a store outage) is\n * logged by code and retried after the sleep.\n */\n async start(options: WorkerOptions = {}): Promise<void> {\n const workerId = options.workerId ?? randomId('worker');\n const batch = options.batch ?? DEFAULT_BATCH;\n const { signal } = options;\n while (!signal?.aborted) {\n let processed = 0;\n try {\n processed = await this.runOnce({\n workerId,\n batch,\n ...(signal ? { signal } : {}),\n });\n } catch (error) {\n this.deps.log.warn('monitor worker pass failed', {\n workerId,\n code: errorCode(error),\n });\n }\n if (processed > 0 && processed >= batch) continue;\n try {\n await this.deps.clock.sleep(this.deps.lifecycle().pollIntervalMs, signal);\n } catch {\n return;\n }\n }\n }\n\n /**\n * Startup recovery for this namespace; it never signs. `signed` and ambiguously\n * `submitted` Operations resend their stored raw bytes; every other signed-or-later live\n * Operation is checked. `created`, `prepared`, `awaiting-signature` and `stalled` ones need\n * a caller and are reported through `recovery.skipped` (codes and states only). Then each\n * wallet with a live Operation has its nonces reconciled under its address lease. A\n * failure is logged by code and counted, and the rest go on. `signal` stops recovery\n * between Operations and bounds each check and lease wait. Known gap: a `signed` or\n * ambiguous Operation whose wallet-bound target cannot be resolved is counted `failed`\n * without its check, although the check needs no wallet.\n */\n async recover(\n options: { readonly signal?: AbortSignal } = {},\n ): Promise<RecoveryReport> {\n const { signal } = options;\n const { namespace } = this.deps;\n const live = await this.deps.stores.operations.list({\n namespace,\n states: NON_TERMINAL_STATES,\n });\n const reads = this.#passResolver(this.deps.resolveRead);\n const writes = this.#passResolver(this.deps.resolveTarget);\n let rebroadcast = 0;\n let checked = 0;\n let skipped = 0;\n let failed = 0;\n let reconciled = 0;\n const skip = (op: OperationRecord, reason: string) => {\n skipped += 1;\n this.deps.events.emit('recovery.skipped', {\n namespace,\n operationId: op.id,\n state: op.state,\n reason,\n });\n };\n for (const op of live) {\n if (signal?.aborted) break;\n if (PRE_SIGNING_STATES.has(op.state)) {\n skip(op, 'CALLER_ACTION_REQUIRED');\n continue;\n }\n if (op.state === 'stalled') {\n skip(op, 'STALLED');\n continue;\n }\n try {\n const target = await this.#resolved(reads, op);\n let current = op;\n if (\n op.state === 'signed' ||\n (op.state === 'submitted' && op.ambiguous === true)\n ) {\n const writer = await this.#resolved(writes, op);\n try {\n current = await this.deps.engine.rebroadcast(writer, op.id, signal);\n } catch (error) {\n // A refusal or an unknown outcome is recorded on the Operation: check it next.\n if (\n !isCryptoAioError(error) ||\n (error.category !== 'chain' && error.ambiguous !== true)\n )\n throw error;\n current = (await this.monitor.find(op.id)) ?? op;\n }\n rebroadcast += 1;\n }\n await this.monitor.check(target, current, undefined, signal);\n checked += 1;\n } catch (error) {\n failed += 1;\n this.deps.log.warn('recovery of an operation failed', {\n operationId: op.id,\n code: errorCode(error),\n });\n }\n }\n const wallets = new Map<string, OperationRecord>();\n for (const op of live) {\n const key = [op.context.chain, op.context.network, op.intent.from].join('\\n');\n if (!wallets.has(key)) wallets.set(key, op);\n }\n for (const op of wallets.values()) {\n if (signal?.aborted) break;\n try {\n const writer = await this.#resolved(writes, op);\n reconciled += (await this.deps.engine.reconcileNonces(writer, op, { signal }))\n .length;\n } catch (error) {\n this.deps.log.warn('nonce reconciliation failed', {\n operationId: op.id,\n code: errorCode(error),\n });\n }\n }\n return { rebroadcast, checked, skipped, failed, reconciled };\n }\n\n /**\n * `resolve` for one pass: each execution context's target is rebuilt at most once, and\n * only when first asked for (a wallet-bound one only by a write that needs it).\n */\n #passResolver<T>(\n resolve: (op: OperationRecord) => Promise<T | undefined>,\n ): (op: OperationRecord) => Promise<T | undefined> {\n const targets = new Map<string, Promise<T | undefined>>();\n return (op) => {\n let target = targets.get(op.context.configHash);\n if (!target) {\n target = resolve(op);\n targets.set(op.context.configHash, target);\n }\n return target;\n };\n }\n\n async #resolved<T>(\n resolve: (op: OperationRecord) => Promise<T | undefined>,\n op: OperationRecord,\n ): Promise<T> {\n const target = await resolve(op);\n if (!target) {\n throw new ConfigError(\n 'CONFIG_INVALID',\n `the target of operation '${op.id}' cannot be rebuilt from its context`,\n );\n }\n return target;\n }\n\n /**\n * Leaves a claimed, live Operation scheduled a poll interval ahead, unless it ended,\n * another worker took it over or a writer scheduled it meanwhile. A pre-signing Operation\n * is never scheduled (callers drive it), so it is unscheduled instead. Best effort.\n */\n async #reschedule(id: string, fence: Fence, started: number): Promise<void> {\n try {\n for (let tries = 0; tries < 3; tries++) {\n const fresh = await this.deps.stores.operations.get(this.deps.namespace, id);\n if (\n !fresh ||\n isTerminal(fresh.state) ||\n fresh.claim?.token !== fence.claimToken ||\n (fresh.nextCheckAt !== undefined && fresh.nextCheckAt > started)\n )\n return;\n const patch: OperationPatch = PRE_SIGNING_STATES.has(fresh.state)\n ? { clear: ['nextCheckAt'] }\n : { nextCheckAt: this.deps.clock.now() + this.deps.lifecycle().pollIntervalMs };\n try {\n await this.deps.engine.update(fresh, patch, fence);\n return;\n } catch (error) {\n if (!isCryptoAioError(error, 'VERSION_CONFLICT')) throw error;\n }\n }\n } catch (error) {\n this.deps.log.debug('could not reschedule a claimed operation', {\n operationId: id,\n code: errorCode(error),\n });\n }\n }\n\n /**\n * `nonce.gap`, once per (Operation, expected nonce): a `submitted` Operation has waited\n * longer than `droppedGracePeriodMs` since its active Attempt was first seen or sent, and\n * the chain's pending nonce is still below its own (a lower nonce is missing\n * even from the mempool, so congestion alone is no gap). It names the live Operation\n * holding the expected nonce, when one exists. Every such pass then reconciles the wallet's nonces, trying the lease\n * once (never a filler transaction): a leaked value goes back for the next transfer.\n * Only that write resolves the wallet-bound target (`writes`).\n */\n async #detectNonceGap(\n target: ReadTarget,\n op: OperationRecord,\n writes: TargetResolver,\n ): Promise<void> {\n const { sequence } = target.pooled.driver;\n if (op.state !== 'submitted' || op.reservation?.kind !== 'nonce' || !sequence) {\n this.#gaps.delete(op.id);\n return;\n }\n const attempt = op.attempts.find((a) => a.id === op.activeAttemptId);\n const observation = attempt\n ? await this.deps.stores.operations.getObservation(attempt.id)\n : null;\n // Not `lastBroadcastAt`, which every resend of a dropped Attempt refreshes.\n const since = observation?.firstSeenAt ?? attempt?.createdAt ?? op.createdAt;\n if (this.deps.clock.now() - since < this.deps.lifecycle().droppedGracePeriodMs)\n return;\n const expected = await sequence.pending(op.intent.from);\n if (expected >= op.reservation.nonce) return;\n const reported = this.#gaps.get(op.id) ?? new Set<string>();\n this.#gaps.delete(op.id);\n this.#gaps.set(op.id, reported);\n if (this.#gaps.size > GAP_MEMORY) {\n const oldest = this.#gaps.keys().next().value;\n if (oldest !== undefined) this.#gaps.delete(oldest);\n }\n if (!reported.has(expected.toString())) {\n reported.add(expected.toString());\n const blocking = (\n await this.deps.stores.operations.list({\n namespace: this.deps.namespace,\n chain: op.context.chain,\n network: op.context.network,\n from: op.intent.from,\n states: NON_TERMINAL_STATES,\n })\n ).find((o) => o.reservation?.kind === 'nonce' && o.reservation.nonce === expected);\n this.deps.events.emit('nonce.gap', {\n namespace: this.deps.namespace,\n chain: op.context.chain,\n network: op.context.network,\n operationId: op.id,\n expected: expected.toString(),\n ...(blocking ? { blockingOperationId: blocking.id } : {}),\n });\n }\n try {\n const writer = await this.#resolved(writes, op);\n await this.deps.engine.reconcileNonces(writer, op, { acquireTimeoutMs: 0 });\n } catch (error) {\n const busy = isCryptoAioError(error, 'SEQUENCE_BUSY');\n this.deps.log[busy ? 'debug' : 'warn']('nonce reconciliation did not run', {\n operationId: op.id,\n code: errorCode(error),\n });\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"workers.js","sourceRoot":"","sources":["../../../src/core/lifecycle/workers.ts"],"names":[],"mappings":"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","sourcesContent":["import { ConfigError, isCryptoAioError } from '../errors/error';\nimport {\n NON_TERMINAL_STATES,\n isTerminal,\n type Fence,\n type OperationClaim,\n type OperationPatch,\n type OperationRecord,\n} from '../store/types';\nimport { randomId } from '../util/bytes';\nimport type { ReadTarget } from './engine';\nimport { PRE_SIGNING_STATES, errorCode } from './engine-rules';\nimport type { MonitorDeps, ReadResolver, TargetResolver } from './monitor';\n\n/*\n * The monitor's background worker loop and startup recovery (`Monitor` delegates to\n * `Workers`). They check Operations through the monitor\n * (`MonitorChecks`) and write only through the engine.\n */\n\n/**\n * What `recover()` did. The counts are per Operation, except `reconciled`, and they\n * overlap: an Operation whose resend was attempted and whose check then failed counts in\n * both `rebroadcast` and `failed`.\n */\nexport interface RecoveryReport {\n /**\n * `signed` or ambiguously `submitted` Operations whose stored bytes were sent again:\n * attempted resends, including ones the node refused or whose outcome is unknown.\n */\n readonly rebroadcast: number;\n /** Operations checked on chain after any resend. */\n readonly checked: number;\n /** Operations that need a caller (see `recovery.skipped`); never resent or checked. */\n readonly skipped: number;\n /**\n * `signed` or ambiguously `submitted` Operations whose wallet no longer resolves (its\n * configuration or signer was removed): checked on chain, but their stored bytes were not\n * sent again. Restore the wallet and recover again to resend them.\n */\n readonly unresent: number;\n /** Operations whose target could not be rebuilt, or whose resend or check threw. */\n readonly failed: number;\n /** Leaked nonce values that reconciliation returned for reuse (across all wallets). */\n readonly reconciled: number;\n}\n\nexport interface WorkerOptions {\n /** Default: a random id per `start` call. */\n readonly workerId?: string;\n readonly signal?: AbortSignal;\n /** How many due Operations one pass claims. Default: 50. */\n readonly batch?: number;\n}\n\nconst DEFAULT_BATCH = 50;\n/** How many Operations' reported gaps a monitor remembers (`nonce.gap` is at-least-once). */\nconst GAP_MEMORY = 10_000;\n\n/** What the worker loop and recovery use of the monitor's own checks. */\nexport interface MonitorChecks {\n checkPass(\n target: ReadTarget,\n op: OperationRecord,\n fence?: Fence,\n signal?: AbortSignal,\n ): Promise<{ readonly record: OperationRecord; readonly stale: boolean }>;\n check(\n target: ReadTarget,\n op: OperationRecord,\n fence?: Fence,\n signal?: AbortSignal,\n ): Promise<OperationRecord>;\n find(ref: string): Promise<OperationRecord | null>;\n}\n\n/** Worker passes and startup recovery for one monitor (see `Monitor`). */\nexport class Workers {\n /**\n * Per Operation, the expected nonces a `nonce.gap` was already emitted for; least\n * recently reported first, capped at `GAP_MEMORY` Operations.\n */\n readonly #gaps = new Map<string, Set<string>>();\n\n constructor(\n private readonly deps: MonitorDeps,\n private readonly monitor: MonitorChecks,\n ) {}\n\n /**\n * One worker pass: claims up to `batch` due Operations, checks each under its claim fence\n * (a stale worker's writes fail), then releases the claim. Every claimed Operation\n * that stays live leaves the pass scheduled a poll interval ahead, including when its\n * check threw, its view was stale or its all-rejected verdict could not run, so no worker\n * claims it again before then. A stale view also skips gap handling and reconciliation.\n * `signal` bounds each check and its lease wait; once it aborts, the Operations not yet\n * checked are only released, still due, for another worker. Returns how many Operations\n * it claimed.\n */\n async runOnce(options: {\n readonly workerId: string;\n readonly batch?: number;\n readonly signal?: AbortSignal;\n }): Promise<number> {\n const { signal } = options;\n if (signal?.aborted) return 0;\n const claimed = await this.deps.stores.operations.claimDue(\n this.deps.namespace,\n options.workerId,\n this.deps.clock.now(),\n this.deps.lifecycle().claimLeaseMs,\n options.batch ?? DEFAULT_BATCH,\n );\n const reads = this.#passResolver(this.deps.resolveRead);\n const writes = this.#passResolver(this.deps.resolveTarget);\n for (const op of claimed) {\n const fence: Fence = { claimToken: (op.claim as OperationClaim).token };\n if (!signal?.aborted) await this.#process(reads, writes, op, fence, signal);\n await this.deps.stores.operations\n .releaseClaim(this.deps.namespace, op.id, fence)\n .catch((error: unknown) =>\n this.deps.log.debug('claim already lost', {\n operationId: op.id,\n code: errorCode(error),\n }),\n );\n }\n return claimed.length;\n }\n\n /** One claimed Operation of a worker pass (see `runOnce`). */\n async #process(\n reads: ReadResolver,\n writes: TargetResolver,\n op: OperationRecord,\n fence: Fence,\n signal: AbortSignal | undefined,\n ): Promise<void> {\n const started = this.deps.clock.now();\n let current: OperationRecord | undefined;\n try {\n const target = await this.#resolved(reads, op);\n const pass = await this.monitor.checkPass(target, op, fence, signal);\n current = pass.record;\n if (!pass.stale) await this.#detectNonceGap(target, current, writes);\n } catch (error) {\n // An abort mid-check is an expected shutdown, not a failure.\n this.deps.log[signal?.aborted ? 'debug' : 'warn'](\n signal?.aborted ? 'monitor check stopped' : 'monitor check failed',\n { operationId: op.id, code: errorCode(error) },\n );\n }\n const scheduled =\n current !== undefined &&\n (isTerminal(current.state) ||\n (current.nextCheckAt !== undefined && current.nextCheckAt > started));\n if (!scheduled) await this.#reschedule(op.id, fence, started);\n }\n\n /**\n * Runs worker passes until `signal` aborts. Any number of workers, in any number of\n * processes, may run: claims keep them apart. A full batch is followed by the next pass at\n * once, anything less by a poll-interval sleep. A failed pass (e.g. a store outage) is\n * logged by code and retried after the sleep.\n */\n async start(options: WorkerOptions = {}): Promise<void> {\n const workerId = options.workerId ?? randomId('worker');\n const batch = options.batch ?? DEFAULT_BATCH;\n const { signal } = options;\n while (!signal?.aborted) {\n let processed = 0;\n try {\n processed = await this.runOnce({\n workerId,\n batch,\n ...(signal ? { signal } : {}),\n });\n } catch (error) {\n this.deps.log.warn('monitor worker pass failed', {\n workerId,\n code: errorCode(error),\n });\n }\n if (processed > 0 && processed >= batch) continue;\n try {\n await this.deps.clock.sleep(this.deps.lifecycle().pollIntervalMs, signal);\n } catch {\n return;\n }\n }\n }\n\n /**\n * Startup recovery for this namespace; it never signs. `signed` and ambiguously\n * `submitted` Operations resend their stored raw bytes; every other signed-or-later live\n * Operation is checked. `created`, `prepared`, `awaiting-signature` and `stalled` ones need\n * a caller and are reported through `recovery.skipped` (codes and states only). Then each\n * wallet with a live Operation has its nonces reconciled under its address lease. A\n * failure is logged by code and counted, and the rest go on. `signal` stops recovery\n * between Operations and bounds each check and lease wait. A `signed` or ambiguous\n * Operation whose wallet no longer resolves is still checked, since the check needs no\n * wallet, and counted `unresent`: only its resend needs the wallet.\n */\n async recover(\n options: { readonly signal?: AbortSignal } = {},\n ): Promise<RecoveryReport> {\n const { signal } = options;\n const { namespace } = this.deps;\n const live = await this.deps.stores.operations.list({\n namespace,\n states: NON_TERMINAL_STATES,\n });\n const reads = this.#passResolver(this.deps.resolveRead);\n const writes = this.#passResolver(this.deps.resolveTarget);\n let rebroadcast = 0;\n let checked = 0;\n let skipped = 0;\n let unresent = 0;\n let failed = 0;\n let reconciled = 0;\n const skip = (op: OperationRecord, reason: string) => {\n skipped += 1;\n this.deps.events.emit('recovery.skipped', {\n namespace,\n operationId: op.id,\n state: op.state,\n reason,\n });\n };\n for (const op of live) {\n if (signal?.aborted) break;\n if (PRE_SIGNING_STATES.has(op.state)) {\n skip(op, 'CALLER_ACTION_REQUIRED');\n continue;\n }\n if (op.state === 'stalled') {\n skip(op, 'STALLED');\n continue;\n }\n try {\n const target = await this.#resolved(reads, op);\n let current = op;\n if (\n op.state === 'signed' ||\n (op.state === 'submitted' && op.ambiguous === true)\n ) {\n const writer = await this.#resolved(writes, op).catch((error: unknown) => {\n // A wallet whose configuration or signer is gone rules out the resend only.\n if (!walletUnresolved(error)) throw error;\n unresent += 1;\n this.deps.log.warn('recovery checks an operation it cannot resend', {\n operationId: op.id,\n code: errorCode(error),\n });\n return undefined;\n });\n if (writer) {\n try {\n current = await this.deps.engine.rebroadcast(writer, op.id, signal);\n } catch (error) {\n // A refusal or an unknown outcome is recorded on the Operation: check it next.\n if (\n !isCryptoAioError(error) ||\n (error.category !== 'chain' && error.ambiguous !== true)\n )\n throw error;\n current = (await this.monitor.find(op.id)) ?? op;\n }\n rebroadcast += 1;\n }\n }\n await this.monitor.check(target, current, undefined, signal);\n checked += 1;\n } catch (error) {\n failed += 1;\n this.deps.log.warn('recovery of an operation failed', {\n operationId: op.id,\n code: errorCode(error),\n });\n }\n }\n const wallets = new Map<string, OperationRecord>();\n for (const op of live) {\n const key = [op.context.chain, op.context.network, op.intent.from].join('\\n');\n if (!wallets.has(key)) wallets.set(key, op);\n }\n for (const op of wallets.values()) {\n if (signal?.aborted) break;\n try {\n const writer = await this.#resolved(writes, op);\n reconciled += (await this.deps.engine.reconcileNonces(writer, op, { signal }))\n .length;\n } catch (error) {\n this.deps.log.warn('nonce reconciliation failed', {\n operationId: op.id,\n code: errorCode(error),\n });\n }\n }\n return { rebroadcast, checked, skipped, unresent, failed, reconciled };\n }\n\n /**\n * `resolve` for one pass: each execution context's target is rebuilt at most once, and\n * only when first asked for (a wallet-bound one only by a write that needs it).\n */\n #passResolver<T>(\n resolve: (op: OperationRecord) => Promise<T | undefined>,\n ): (op: OperationRecord) => Promise<T | undefined> {\n const targets = new Map<string, Promise<T | undefined>>();\n return (op) => {\n let target = targets.get(op.context.configHash);\n if (!target) {\n target = resolve(op);\n targets.set(op.context.configHash, target);\n }\n return target;\n };\n }\n\n async #resolved<T>(\n resolve: (op: OperationRecord) => Promise<T | undefined>,\n op: OperationRecord,\n ): Promise<T> {\n const target = await resolve(op);\n if (!target) {\n throw new ConfigError(\n 'CONFIG_INVALID',\n `the target of operation '${op.id}' cannot be rebuilt from its context`,\n );\n }\n return target;\n }\n\n /**\n * Leaves a claimed, live Operation scheduled a poll interval ahead, unless it ended,\n * another worker took it over or a writer scheduled it meanwhile. A pre-signing Operation\n * is never scheduled (callers drive it), so it is unscheduled instead. Best effort.\n */\n async #reschedule(id: string, fence: Fence, started: number): Promise<void> {\n try {\n for (let tries = 0; tries < 3; tries++) {\n const fresh = await this.deps.stores.operations.get(this.deps.namespace, id);\n if (\n !fresh ||\n isTerminal(fresh.state) ||\n fresh.claim?.token !== fence.claimToken ||\n (fresh.nextCheckAt !== undefined && fresh.nextCheckAt > started)\n )\n return;\n const patch: OperationPatch = PRE_SIGNING_STATES.has(fresh.state)\n ? { clear: ['nextCheckAt'] }\n : { nextCheckAt: this.deps.clock.now() + this.deps.lifecycle().pollIntervalMs };\n try {\n await this.deps.engine.update(fresh, patch, fence);\n return;\n } catch (error) {\n if (!isCryptoAioError(error, 'VERSION_CONFLICT')) throw error;\n }\n }\n } catch (error) {\n this.deps.log.debug('could not reschedule a claimed operation', {\n operationId: id,\n code: errorCode(error),\n });\n }\n }\n\n /**\n * `nonce.gap`, once per (Operation, expected nonce): a `submitted` Operation has waited\n * longer than `droppedGracePeriodMs` since its active Attempt was first seen or sent, and\n * the chain's pending nonce is still below its own (a lower nonce is missing\n * even from the mempool, so congestion alone is no gap). It names the live Operation\n * holding the expected nonce, when one exists. Every such pass then reconciles the wallet's nonces, trying the lease\n * once (never a filler transaction): a leaked value goes back for the next transfer.\n * Only that write resolves the wallet-bound target (`writes`).\n */\n async #detectNonceGap(\n target: ReadTarget,\n op: OperationRecord,\n writes: TargetResolver,\n ): Promise<void> {\n const { sequence } = target.pooled.driver;\n if (op.state !== 'submitted' || op.reservation?.kind !== 'nonce' || !sequence) {\n this.#gaps.delete(op.id);\n return;\n }\n const attempt = op.attempts.find((a) => a.id === op.activeAttemptId);\n const observation = attempt\n ? await this.deps.stores.operations.getObservation(attempt.id)\n : null;\n // Not `lastBroadcastAt`, which every resend of a dropped Attempt refreshes.\n const since = observation?.firstSeenAt ?? attempt?.createdAt ?? op.createdAt;\n if (this.deps.clock.now() - since < this.deps.lifecycle().droppedGracePeriodMs)\n return;\n const expected = await sequence.pending(op.intent.from);\n if (expected >= op.reservation.nonce) return;\n const reported = this.#gaps.get(op.id) ?? new Set<string>();\n this.#gaps.delete(op.id);\n this.#gaps.set(op.id, reported);\n if (this.#gaps.size > GAP_MEMORY) {\n const oldest = this.#gaps.keys().next().value;\n if (oldest !== undefined) this.#gaps.delete(oldest);\n }\n if (!reported.has(expected.toString())) {\n reported.add(expected.toString());\n const blocking = (\n await this.deps.stores.operations.list({\n namespace: this.deps.namespace,\n chain: op.context.chain,\n network: op.context.network,\n from: op.intent.from,\n states: NON_TERMINAL_STATES,\n })\n ).find((o) => o.reservation?.kind === 'nonce' && o.reservation.nonce === expected);\n this.deps.events.emit('nonce.gap', {\n namespace: this.deps.namespace,\n chain: op.context.chain,\n network: op.context.network,\n operationId: op.id,\n expected: expected.toString(),\n ...(blocking ? { blockingOperationId: blocking.id } : {}),\n });\n }\n try {\n const writer = await this.#resolved(writes, op);\n await this.deps.engine.reconcileNonces(writer, op, { acquireTimeoutMs: 0 });\n } catch (error) {\n const busy = isCryptoAioError(error, 'SEQUENCE_BUSY');\n this.deps.log[busy ? 'debug' : 'warn']('nonce reconciliation did not run', {\n operationId: op.id,\n code: errorCode(error),\n });\n }\n }\n}\n\n/** A wallet that cannot be resolved for writes: its configuration or its signer is gone. */\nfunction walletUnresolved(error: unknown): boolean {\n return (\n isCryptoAioError(error) &&\n (error.category === 'config' || error.category === 'signing')\n );\n}\n"]}
|
package/dist/core/model/ids.d.ts
CHANGED
|
@@ -26,6 +26,7 @@ export type ExtOf<C extends ChainId> = FamilyOf<C> extends keyof FamilyRegistry
|
|
|
26
26
|
} ? E : unknown : unknown;
|
|
27
27
|
export declare const Library: Readonly<{
|
|
28
28
|
readonly ETHERS: "ethers";
|
|
29
|
+
/** @deprecated web3.js is no longer maintained: use `ETHERS`. Removed in crypto-aio 2.0. */
|
|
29
30
|
readonly WEB3: "web3";
|
|
30
31
|
readonly TRONWEB: "tronweb";
|
|
31
32
|
readonly BITCOINJS_LIB: "bitcoinjs-lib";
|
package/dist/core/model/ids.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.Library = void 0;
|
|
4
4
|
exports.Library = Object.freeze({
|
|
5
5
|
ETHERS: 'ethers',
|
|
6
|
+
/** @deprecated web3.js is no longer maintained: use `ETHERS`. Removed in crypto-aio 2.0. */
|
|
6
7
|
WEB3: 'web3',
|
|
7
8
|
TRONWEB: 'tronweb',
|
|
8
9
|
BITCOINJS_LIB: 'bitcoinjs-lib',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ids.js","sourceRoot":"","sources":["../../../src/core/model/ids.ts"],"names":[],"mappings":";;;AAmCa,QAAA,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC;IACnC,MAAM,EAAE,QAAQ;IAChB,IAAI,EAAE,MAAM;IACZ,OAAO,EAAE,SAAS;IAClB,aAAa,EAAE,eAAe;IAC9B,cAAc,EAAE,iBAAiB;IACjC,GAAG,EAAE,UAAU;IACf,WAAW,EAAE,sBAAsB;CAC3B,CAAC,CAAC","sourcesContent":["/**\n * Type-level registries. Users and plugins augment them through the package entry, e.g.\n * `declare module 'crypto-aio' { interface ChainRegistry { ethereum: {...} } }`, and plugins\n * inside this package augment the entry module (`declare module '../index'`). Never augment\n * this file directly: an augmentation here and one through the entry are then merged in file\n * order, and a user's chains can be lost.\n */\nexport interface ChainRegistry {}\nexport interface FamilyRegistry {}\nexport interface NativeClientMap {}\n\nexport type ChainId = Extract<keyof ChainRegistry, string>;\n\ntype ChainEntry<C extends ChainId> = ChainRegistry[C] extends {\n family: string;\n network: string;\n}\n ? ChainRegistry[C]\n : never;\n\nexport type NetworkOf<C extends ChainId> = ChainEntry<C>['network'];\nexport type FamilyOf<C extends ChainId> = ChainEntry<C>['family'];\nexport type LibraryOf<C extends ChainId> =\n FamilyOf<C> extends keyof FamilyRegistry\n ? FamilyRegistry[FamilyOf<C>] extends { library: infer L }\n ? L\n : string\n : string;\nexport type ExtOf<C extends ChainId> =\n FamilyOf<C> extends keyof FamilyRegistry\n ? FamilyRegistry[FamilyOf<C>] extends { ext: infer E }\n ? E\n : unknown\n : unknown;\n\nexport const Library = Object.freeze({\n ETHERS: 'ethers',\n WEB3: 'web3',\n TRONWEB: 'tronweb',\n BITCOINJS_LIB: 'bitcoinjs-lib',\n SOLANA_WEB3_JS: '@solana/web3.js',\n TON: '@ton/ton',\n AVALANCHEJS: '@avalabs/avalanchejs',\n} as const);\n\nexport type KnownLibrary = (typeof Library)[keyof typeof Library];\n"]}
|
|
1
|
+
{"version":3,"file":"ids.js","sourceRoot":"","sources":["../../../src/core/model/ids.ts"],"names":[],"mappings":";;;AAmCa,QAAA,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC;IACnC,MAAM,EAAE,QAAQ;IAChB,4FAA4F;IAC5F,IAAI,EAAE,MAAM;IACZ,OAAO,EAAE,SAAS;IAClB,aAAa,EAAE,eAAe;IAC9B,cAAc,EAAE,iBAAiB;IACjC,GAAG,EAAE,UAAU;IACf,WAAW,EAAE,sBAAsB;CAC3B,CAAC,CAAC","sourcesContent":["/**\n * Type-level registries. Users and plugins augment them through the package entry, e.g.\n * `declare module 'crypto-aio' { interface ChainRegistry { ethereum: {...} } }`, and plugins\n * inside this package augment the entry module (`declare module '../index'`). Never augment\n * this file directly: an augmentation here and one through the entry are then merged in file\n * order, and a user's chains can be lost.\n */\nexport interface ChainRegistry {}\nexport interface FamilyRegistry {}\nexport interface NativeClientMap {}\n\nexport type ChainId = Extract<keyof ChainRegistry, string>;\n\ntype ChainEntry<C extends ChainId> = ChainRegistry[C] extends {\n family: string;\n network: string;\n}\n ? ChainRegistry[C]\n : never;\n\nexport type NetworkOf<C extends ChainId> = ChainEntry<C>['network'];\nexport type FamilyOf<C extends ChainId> = ChainEntry<C>['family'];\nexport type LibraryOf<C extends ChainId> =\n FamilyOf<C> extends keyof FamilyRegistry\n ? FamilyRegistry[FamilyOf<C>] extends { library: infer L }\n ? L\n : string\n : string;\nexport type ExtOf<C extends ChainId> =\n FamilyOf<C> extends keyof FamilyRegistry\n ? FamilyRegistry[FamilyOf<C>] extends { ext: infer E }\n ? E\n : unknown\n : unknown;\n\nexport const Library = Object.freeze({\n ETHERS: 'ethers',\n /** @deprecated web3.js is no longer maintained: use `ETHERS`. Removed in crypto-aio 2.0. */\n WEB3: 'web3',\n TRONWEB: 'tronweb',\n BITCOINJS_LIB: 'bitcoinjs-lib',\n SOLANA_WEB3_JS: '@solana/web3.js',\n TON: '@ton/ton',\n AVALANCHEJS: '@avalabs/avalanchejs',\n} as const);\n\nexport type KnownLibrary = (typeof Library)[keyof typeof Library];\n"]}
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
export type OrderingKind = 'nonce' | 'seqno' | 'inputs' | 'expiry';
|
|
2
|
+
/**
|
|
3
|
+
* What reserves an Attempt's slot. A family's build may record more about a `seqno` or
|
|
4
|
+
* `expiry` slot in the same object (TON's `validFrom`, Tron's `refBlockHash`, Solana's
|
|
5
|
+
* `blockhash` and `blockhashSlot`, each in the family's own exported type), and its proofs
|
|
6
|
+
* read those fields back. A store keeps every ordering whole and unchanged, extra fields
|
|
7
|
+
* included: strings, finite numbers and bigints beyond 2^53. The `OperationStore` contract
|
|
8
|
+
* suite checks each built-in family's (`SAMPLE_ORDERINGS`).
|
|
9
|
+
*/
|
|
2
10
|
export type OrderingData = {
|
|
3
11
|
readonly kind: 'nonce';
|
|
4
12
|
readonly nonce: bigint;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ordering.js","sourceRoot":"","sources":["../../../src/core/model/ordering.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"ordering.js","sourceRoot":"","sources":["../../../src/core/model/ordering.ts"],"names":[],"mappings":";;AAqBA,8CAOC;AAGD,sCAWC;AAtBD,2FAA2F;AAC3F,SAAgB,iBAAiB,CAAC,CAAe,EAAE,CAAe;IAChE,IAAI,CAAC,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,CAAC,IAAI,KAAK,OAAO;QAAE,OAAO,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,KAAK,CAAC;IACzE,IAAI,CAAC,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,CAAC,IAAI,KAAK,OAAO;QAAE,OAAO,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,KAAK,CAAC;IACzE,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC/C,OAAO,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;IAC5D,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,8EAA8E;AAC9E,SAAgB,aAAa,CAAC,QAAsB;IAClD,QAAQ,QAAQ,CAAC,IAAI,EAAE,CAAC;QACtB,KAAK,OAAO;YACV,OAAO,SAAS,QAAQ,CAAC,KAAK,EAAE,CAAC;QACnC,KAAK,OAAO;YACV,OAAO,SAAS,QAAQ,CAAC,KAAK,EAAE,CAAC;QACnC,KAAK,QAAQ;YACX,OAAO,UAAU,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QAC5C,KAAK,QAAQ;YACX,OAAO,QAAQ,CAAC;IACpB,CAAC;AACH,CAAC","sourcesContent":["export type OrderingKind = 'nonce' | 'seqno' | 'inputs' | 'expiry';\n\n/**\n * What reserves an Attempt's slot. A family's build may record more about a `seqno` or\n * `expiry` slot in the same object (TON's `validFrom`, Tron's `refBlockHash`, Solana's\n * `blockhash` and `blockhashSlot`, each in the family's own exported type), and its proofs\n * read those fields back. A store keeps every ordering whole and unchanged, extra fields\n * included: strings, finite numbers and bigints beyond 2^53. The `OperationStore` contract\n * suite checks each built-in family's (`SAMPLE_ORDERINGS`).\n */\nexport type OrderingData =\n | { readonly kind: 'nonce'; readonly nonce: bigint }\n | { readonly kind: 'seqno'; readonly seqno: bigint; readonly validUntil: number }\n | { readonly kind: 'inputs'; readonly inputs: readonly string[] }\n | {\n readonly kind: 'expiry';\n readonly lastValidHeight?: bigint;\n readonly expiresAtMs?: number;\n };\n\n/** True when at most one of two transactions with these orderings can ever be included. */\nexport function mutuallyExclusive(a: OrderingData, b: OrderingData): boolean {\n if (a.kind === 'nonce' && b.kind === 'nonce') return a.nonce === b.nonce;\n if (a.kind === 'seqno' && b.kind === 'seqno') return a.seqno === b.seqno;\n if (a.kind === 'inputs' && b.kind === 'inputs') {\n return a.inputs.some((input) => b.inputs.includes(input));\n }\n return false;\n}\n\n/** Short label safe for events and logs (never lists inputs or addresses). */\nexport function orderingLabel(ordering: OrderingData): string {\n switch (ordering.kind) {\n case 'nonce':\n return `nonce:${ordering.nonce}`;\n case 'seqno':\n return `seqno:${ordering.seqno}`;\n case 'inputs':\n return `inputs:${ordering.inputs.length}`;\n case 'expiry':\n return 'expiry';\n }\n}\n"]}
|
|
@@ -20,6 +20,13 @@ export interface AttemptRef {
|
|
|
20
20
|
}
|
|
21
21
|
export type TxState = 'unknown' | 'pending' | 'mempool' | 'included' | 'final' | 'failed' | 'dropped' | 'replaced' | 'expired' | 'refused' | 'rejected';
|
|
22
22
|
export type Evidence = 'observed' | 'proven';
|
|
23
|
+
/**
|
|
24
|
+
* What failed in an included transaction: `'reverted'` when its execution failed, so
|
|
25
|
+
* nothing moved but the fee, and `'unevidenced'` when it executed but the chain shows no
|
|
26
|
+
* transfer to the recipient (a token that logged none, a jetton sent to a wallet its master
|
|
27
|
+
* does not name): value may have moved, so check the chain before paying again.
|
|
28
|
+
*/
|
|
29
|
+
export type TxFailure = 'reverted' | 'unevidenced';
|
|
23
30
|
export type Finality = 'none' | 'probabilistic' | 'final';
|
|
24
31
|
export interface TxStatus {
|
|
25
32
|
readonly state: TxState;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transaction.js","sourceRoot":"","sources":["../../../src/core/model/transaction.ts"],"names":[],"mappings":"","sourcesContent":["import type { ErrorCode } from '../errors/codes';\nimport type { SigningRequest } from '../signing/types';\nimport type { Address } from './address';\nimport type { Amount } from './amount';\nimport type { AssetInfo, AssetRef } from './asset';\nimport type { FeeEstimateDraft } from './fee';\nimport type { IntentSummary } from './intent';\nimport type { OrderingData } from './ordering';\n\n/** Protocol data only (bytes or protocol JSON), never SDK objects. */\nexport interface RawTx {\n readonly encoding: 'hex' | 'base64' | 'json';\n readonly data: string;\n}\n\nexport type AttemptIdKind = 'tx-hash' | 'txid' | 'signature' | 'message-hash';\n\n/** Identity of a signed payload. `canonical: false` = not the final protocol tx hash (TON). */\nexport interface AttemptRef {\n readonly id: string;\n readonly idKind: AttemptIdKind;\n readonly canonical: boolean;\n}\n\nexport type TxState =\n | 'unknown'\n | 'pending'\n | 'mempool'\n | 'included'\n | 'final'\n | 'failed'\n | 'dropped'\n | 'replaced'\n | 'expired'\n | 'refused'\n | 'rejected';\n\nexport type Evidence = 'observed' | 'proven';\nexport type Finality = 'none' | 'probabilistic' | 'final';\n\nexport interface TxStatus {\n readonly state: TxState;\n readonly evidence: Evidence;\n readonly confirmations: number;\n readonly txHash?: string;\n readonly blockHash?: string;\n readonly blockHeight?: bigint;\n readonly finality: Finality;\n /**\n * Why the transaction did not go through. Present only with `failed`, `refused` or\n * `rejected`. It is either a broadcast's refusal or rejection text, or the chain\n * driver's text for an on-chain failure. It is a short, fixed text with no addresses,\n * amounts or node detail. It is `sensitive` data, so it never appears in events\n * or logs.\n */\n readonly reason?: string;\n readonly replacedBy?: string;\n}\n\nexport interface BlockRef {\n readonly height: bigint;\n readonly hash: string;\n readonly timestamp?: number;\n}\n\nexport interface Block {\n readonly height: bigint;\n readonly hash: string;\n readonly parentHash: string;\n readonly timestamp?: number;\n readonly transactionIds?: readonly string[];\n}\n\nexport type TransferSource = 'native' | 'token-event' | 'internal';\n\ninterface TransferBase {\n /** Deterministic: `${txId}:${locator}`. */\n readonly id: string;\n readonly from: readonly Address[];\n readonly to: Address;\n readonly source: TransferSource;\n readonly memo?: string;\n}\n\n/** A transfer whose asset resolved on this chain and network. */\nexport interface ResolvedTransfer extends TransferBase {\n readonly asset: AssetInfo;\n readonly amount: Amount;\n readonly unresolved?: undefined;\n}\n\n/**\n * A transfer whose asset could not be resolved, for example a token with unusable\n * metadata or a failing decimals call. It has no `asset` and no `amount`: without the\n * asset's decimals there is no `Amount`. `unresolved` keeps the chain's raw data instead,\n * and the transaction's `decoding` is `'partial'`. A read never fails on such a transfer;\n * only a retryable failure fails the read, so it can be retried.\n */\nexport interface UnresolvedTransfer extends TransferBase {\n readonly asset?: undefined;\n readonly amount?: undefined;\n readonly unresolved: {\n /** The asset as the chain names it. */\n readonly asset: AssetRef;\n /** The amount in base units, never scaled. */\n readonly amount: bigint;\n /** Why the asset did not resolve, e.g. `ASSET_RESOLUTION`. */\n readonly code: ErrorCode;\n };\n}\n\n/** Check `unresolved` (or `amount`) before using a transfer's `asset` and `amount`. */\nexport type Transfer = ResolvedTransfer | UnresolvedTransfer;\n\nexport type Decoding = 'complete' | 'partial' | 'none';\n\nexport interface Transaction {\n readonly id: string;\n readonly chain: string;\n readonly network: string;\n readonly status: TxStatus;\n readonly block?: BlockRef;\n readonly fee?: readonly Amount[];\n readonly transfers: readonly Transfer[];\n readonly decoding: Decoding;\n readonly raw?: RawTx;\n readonly details: Readonly<Record<string, unknown>>;\n}\n\nexport interface UnsignedTx {\n readonly payload: RawTx;\n /** Only when identity is fixed before signing (Tron; UTXO with witness-only inputs). */\n readonly expectedRef?: AttemptRef;\n readonly signingRequests: readonly SigningRequest[];\n readonly ordering: OrderingData;\n readonly fee: FeeEstimateDraft;\n readonly summary: IntentSummary;\n}\n\nexport interface SignedTx {\n readonly raw: RawTx;\n readonly ref: AttemptRef;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"transaction.js","sourceRoot":"","sources":["../../../src/core/model/transaction.ts"],"names":[],"mappings":"","sourcesContent":["import type { ErrorCode } from '../errors/codes';\nimport type { SigningRequest } from '../signing/types';\nimport type { Address } from './address';\nimport type { Amount } from './amount';\nimport type { AssetInfo, AssetRef } from './asset';\nimport type { FeeEstimateDraft } from './fee';\nimport type { IntentSummary } from './intent';\nimport type { OrderingData } from './ordering';\n\n/** Protocol data only (bytes or protocol JSON), never SDK objects. */\nexport interface RawTx {\n readonly encoding: 'hex' | 'base64' | 'json';\n readonly data: string;\n}\n\nexport type AttemptIdKind = 'tx-hash' | 'txid' | 'signature' | 'message-hash';\n\n/** Identity of a signed payload. `canonical: false` = not the final protocol tx hash (TON). */\nexport interface AttemptRef {\n readonly id: string;\n readonly idKind: AttemptIdKind;\n readonly canonical: boolean;\n}\n\nexport type TxState =\n | 'unknown'\n | 'pending'\n | 'mempool'\n | 'included'\n | 'final'\n | 'failed'\n | 'dropped'\n | 'replaced'\n | 'expired'\n | 'refused'\n | 'rejected';\n\nexport type Evidence = 'observed' | 'proven';\n\n/**\n * What failed in an included transaction: `'reverted'` when its execution failed, so\n * nothing moved but the fee, and `'unevidenced'` when it executed but the chain shows no\n * transfer to the recipient (a token that logged none, a jetton sent to a wallet its master\n * does not name): value may have moved, so check the chain before paying again.\n */\nexport type TxFailure = 'reverted' | 'unevidenced';\nexport type Finality = 'none' | 'probabilistic' | 'final';\n\nexport interface TxStatus {\n readonly state: TxState;\n readonly evidence: Evidence;\n readonly confirmations: number;\n readonly txHash?: string;\n readonly blockHash?: string;\n readonly blockHeight?: bigint;\n readonly finality: Finality;\n /**\n * Why the transaction did not go through. Present only with `failed`, `refused` or\n * `rejected`. It is either a broadcast's refusal or rejection text, or the chain\n * driver's text for an on-chain failure. It is a short, fixed text with no addresses,\n * amounts or node detail. It is `sensitive` data, so it never appears in events\n * or logs.\n */\n readonly reason?: string;\n readonly replacedBy?: string;\n}\n\nexport interface BlockRef {\n readonly height: bigint;\n readonly hash: string;\n readonly timestamp?: number;\n}\n\nexport interface Block {\n readonly height: bigint;\n readonly hash: string;\n readonly parentHash: string;\n readonly timestamp?: number;\n readonly transactionIds?: readonly string[];\n}\n\nexport type TransferSource = 'native' | 'token-event' | 'internal';\n\ninterface TransferBase {\n /** Deterministic: `${txId}:${locator}`. */\n readonly id: string;\n readonly from: readonly Address[];\n readonly to: Address;\n readonly source: TransferSource;\n readonly memo?: string;\n}\n\n/** A transfer whose asset resolved on this chain and network. */\nexport interface ResolvedTransfer extends TransferBase {\n readonly asset: AssetInfo;\n readonly amount: Amount;\n readonly unresolved?: undefined;\n}\n\n/**\n * A transfer whose asset could not be resolved, for example a token with unusable\n * metadata or a failing decimals call. It has no `asset` and no `amount`: without the\n * asset's decimals there is no `Amount`. `unresolved` keeps the chain's raw data instead,\n * and the transaction's `decoding` is `'partial'`. A read never fails on such a transfer;\n * only a retryable failure fails the read, so it can be retried.\n */\nexport interface UnresolvedTransfer extends TransferBase {\n readonly asset?: undefined;\n readonly amount?: undefined;\n readonly unresolved: {\n /** The asset as the chain names it. */\n readonly asset: AssetRef;\n /** The amount in base units, never scaled. */\n readonly amount: bigint;\n /** Why the asset did not resolve, e.g. `ASSET_RESOLUTION`. */\n readonly code: ErrorCode;\n };\n}\n\n/** Check `unresolved` (or `amount`) before using a transfer's `asset` and `amount`. */\nexport type Transfer = ResolvedTransfer | UnresolvedTransfer;\n\nexport type Decoding = 'complete' | 'partial' | 'none';\n\nexport interface Transaction {\n readonly id: string;\n readonly chain: string;\n readonly network: string;\n readonly status: TxStatus;\n readonly block?: BlockRef;\n readonly fee?: readonly Amount[];\n readonly transfers: readonly Transfer[];\n readonly decoding: Decoding;\n readonly raw?: RawTx;\n readonly details: Readonly<Record<string, unknown>>;\n}\n\nexport interface UnsignedTx {\n readonly payload: RawTx;\n /** Only when identity is fixed before signing (Tron; UTXO with witness-only inputs). */\n readonly expectedRef?: AttemptRef;\n readonly signingRequests: readonly SigningRequest[];\n readonly ordering: OrderingData;\n readonly fee: FeeEstimateDraft;\n readonly summary: IntentSummary;\n}\n\nexport interface SignedTx {\n readonly raw: RawTx;\n readonly ref: AttemptRef;\n}\n"]}
|
|
@@ -4,6 +4,7 @@ exports.Scanner = void 0;
|
|
|
4
4
|
const mapping_1 = require("../blockchain/mapping");
|
|
5
5
|
const error_1 = require("../errors/error");
|
|
6
6
|
const stale_view_1 = require("../transport/stale-view");
|
|
7
|
+
const names_1 = require("../util/names");
|
|
7
8
|
const isAssetInput = (value) => typeof value === 'string'
|
|
8
9
|
? value.length > 0
|
|
9
10
|
: typeof value === 'object' &&
|
|
@@ -28,6 +29,8 @@ function assertOptions(options) {
|
|
|
28
29
|
assertFilter(options.filter, invalid);
|
|
29
30
|
if (typeof cursorKey !== 'string' || cursorKey.length === 0)
|
|
30
31
|
throw invalid('cursorKey must be a non-empty string');
|
|
32
|
+
if (!(0, names_1.storableText)(cursorKey))
|
|
33
|
+
throw invalid('cursorKey must be well-formed text without U+0000');
|
|
31
34
|
if (from !== undefined && from !== 'latest' && (typeof from !== 'bigint' || from < 0n))
|
|
32
35
|
throw invalid("from must be 'latest' or a non-negative bigint height");
|
|
33
36
|
if (mode !== undefined && mode !== 'final' && mode !== 'head')
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scanner.js","sourceRoot":"","sources":["../../../src/core/observe/scanner.ts"],"names":[],"mappings":"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","sourcesContent":["import { toBlock, toTransaction, type MappingContext } from '../blockchain/mapping';\nimport type { BlockSource, ScanFilter } from '../driver/types';\nimport { ConfigError, StateError, isCryptoAioError } from '../errors/error';\nimport type { EventBus } from '../events/bus';\nimport type { AssetRef } from '../model/asset';\nimport type { Block, Transaction } from '../model/transaction';\nimport type { CursorStore, ScanCursor } from '../store/types';\nimport { isStaleView, type StaleViewSource } from '../transport/stale-view';\nimport type { Clock } from '../util/clock';\n\nexport interface ScannerOptions {\n /** Durable name of this consumer's position (namespaced per container, chain and network). */\n readonly cursorKey: string;\n /**\n * Where a NEW cursor starts; ignored when a stored cursor exists. Default `'latest'`. The\n * new cursor also retains the `reorgWindow` blocks below the start, so a rollback within\n * the first window can name blocks that were never delivered, and the replay that follows\n * can start below `from`.\n */\n readonly from?: 'latest' | bigint;\n /**\n * `'final'` emits finalized blocks only; a rollback can then still come from a provider\n * inconsistency. `'head'` follows the tip and may roll back within the window.\n * Default `'head'`. The mode is not stored with the cursor: resuming a head-mode cursor in\n * final mode keeps the unfinalized blocks it already delivered.\n */\n readonly mode?: 'final' | 'head';\n /** Passed to the driver's block source; each entry is resolved on this chain and network. */\n readonly filter?: {\n readonly addresses?: readonly string[];\n readonly assets?: readonly (AssetRef | string)[];\n };\n /** Blocks retained for rollback detection (default: the network's reorgWindow). */\n readonly reorgWindow?: number;\n readonly pollIntervalMs?: number;\n /**\n * Stops the scan, also while it waits for new blocks. `iterator.return()` only takes effect\n * once a pending `next()` settles, so an idle scanner is stopped with this signal.\n */\n readonly signal?: AbortSignal;\n}\n\nexport interface Checkpoint {\n readonly height: bigint;\n readonly hash: string;\n}\n\n/** A scan event without its `ack()`: a delivered block, or a rollback to a checkpoint. */\nexport type ScanEventBody =\n | {\n readonly type: 'block';\n readonly block: Block;\n readonly transactions: readonly Transaction[];\n }\n | {\n readonly type: 'rollback';\n readonly to: Checkpoint;\n readonly removed: readonly Checkpoint[];\n };\n\nexport type ScanEvent = ScanEventBody & { ack(): Promise<void> };\n\nexport interface ScannerDeps {\n readonly load: () => Promise<{\n readonly mapping: MappingContext;\n readonly blocks: BlockSource;\n /** The verified height watermark and lag tolerance behind the stale-view guard. */\n readonly transport: StaleViewSource;\n }>;\n readonly cursors: CursorStore;\n readonly events: EventBus;\n readonly clock: Clock;\n readonly namespace: string;\n readonly defaults: { readonly reorgWindow: number; readonly pollIntervalMs: number };\n}\n\ninterface Step {\n readonly event: ScanEventBody;\n readonly next: ScanCursor;\n}\n\n/** What one iteration of a scan reads through. */\ninterface Source {\n readonly mapping: MappingContext;\n readonly blocks: BlockSource;\n readonly transport: StaleViewSource;\n readonly window: number;\n readonly filter: ScanFilter | undefined;\n}\n\nconst isAssetInput = (value: unknown): boolean =>\n typeof value === 'string'\n ? value.length > 0\n : typeof value === 'object' &&\n value !== null &&\n typeof (value as { standard?: unknown }).standard === 'string' &&\n typeof (value as { contract?: unknown }).contract === 'string';\n\nfunction assertFilter(filter: ScannerOptions['filter'], invalid: (m: string) => Error) {\n if (filter === undefined) return;\n if (typeof filter !== 'object' || filter === null)\n throw invalid('filter must be an object');\n const { addresses, assets } = filter;\n if (\n addresses !== undefined &&\n (!Array.isArray(addresses) || !addresses.every((a) => typeof a === 'string'))\n )\n throw invalid('filter.addresses must be an array of address strings');\n if (assets !== undefined && (!Array.isArray(assets) || !assets.every(isAssetInput)))\n throw invalid('filter.assets must be an array of asset refs or asset ids');\n}\n\nfunction assertOptions(options: ScannerOptions): void {\n const invalid = (message: string) =>\n new ConfigError('CONFIG_INVALID', `scanner ${message}`);\n const { cursorKey, from, mode, reorgWindow, pollIntervalMs } = options;\n assertFilter(options.filter, invalid);\n if (typeof cursorKey !== 'string' || cursorKey.length === 0)\n throw invalid('cursorKey must be a non-empty string');\n if (from !== undefined && from !== 'latest' && (typeof from !== 'bigint' || from < 0n))\n throw invalid(\"from must be 'latest' or a non-negative bigint height\");\n if (mode !== undefined && mode !== 'final' && mode !== 'head')\n throw invalid(\"mode must be 'final' or 'head'\");\n if (\n reorgWindow !== undefined &&\n (!Number.isSafeInteger(reorgWindow) || reorgWindow < 1)\n )\n throw invalid('reorgWindow must be a positive integer');\n if (\n pollIntervalMs !== undefined &&\n (typeof pollIntervalMs !== 'number' ||\n !Number.isFinite(pollIntervalMs) ||\n pollIntervalMs <= 0)\n )\n throw invalid('pollIntervalMs must be a finite number greater than 0');\n}\n\n/** The cursor's window; a reset checkpoint stored without one is its own window. */\nfunction windowOf(cursor: ScanCursor): readonly Checkpoint[] {\n if (cursor.recent.length > 0 || cursor.height < 0n) return cursor.recent;\n return [{ height: cursor.height, hash: cursor.hash }];\n}\n\nfunction sameCursor(a: ScanCursor, b: ScanCursor): boolean {\n return (\n a.height === b.height &&\n a.hash === b.hash &&\n a.recent.length === b.recent.length &&\n a.recent.every(\n (r, i) => r.height === b.recent[i]?.height && r.hash === b.recent[i]?.hash,\n )\n );\n}\n\n/**\n * Reorg-aware, at-least-once block scanner. Each event's `ack()` commits the\n * cursor (compare-and-set on its version, so two scanners sharing a `cursorKey` never both\n * commit the same advance); asking for the next event first throws `INVALID_TRANSITION`.\n * A view that cannot decide (stale, or missing a block) never causes a rollback: the\n * scanner waits a poll interval and looks again, as it does after a retryable provider error.\n *\n * A cursor stopped by `SCANNER_REORG_TOO_DEEP` is reset explicitly: scan under a new\n * `cursorKey`, or `put` a checkpoint `{ height, hash, recent }` for its key through the\n * `CursorStore`. A checkpoint without `recent` is validated on its own block, and its\n * window is then refilled from the chain below that block.\n */\nexport class Scanner implements AsyncIterable<ScanEvent> {\n constructor(\n private readonly deps: ScannerDeps,\n private readonly options: ScannerOptions,\n ) {\n assertOptions(options);\n }\n\n [Symbol.asyncIterator](): AsyncIterator<ScanEvent> {\n return this.run();\n }\n\n private async *run(): AsyncGenerator<ScanEvent> {\n const { signal } = this.options;\n const { mapping, blocks, transport } = await this.deps.load();\n const reader = mapping.driver.reader;\n const { chain, network } = mapping.selection;\n const key = `${this.deps.namespace}:${chain.id}:${network.id}:${this.options.cursorKey}`;\n const window = this.options.reorgWindow ?? this.deps.defaults.reorgWindow;\n // Resolved inside the loop, so a transient failure resolving filter.assets is retried.\n let source: Source | undefined;\n const poll = this.options.pollIntervalMs ?? this.deps.defaults.pollIntervalMs;\n const tip = () =>\n this.options.mode === 'final'\n ? reader.getFinalizedHeight()\n : reader.getBlockHeight();\n const stored = await this.deps.cursors.get(key);\n let version = stored?.version ?? null;\n let cursor = stored?.cursor;\n // A stored cursor is re-validated against the canonical chain before anything is emitted.\n let validated = stored === null;\n while (!signal?.aborted) {\n let step: Step | undefined;\n try {\n source ??= {\n mapping,\n blocks,\n transport,\n window,\n filter: await this.scanFilter(mapping),\n };\n cursor ??= await this.initialCursor(source, await tip());\n if (cursor) {\n let verdict = validated ? 'canonical' : await this.findRollback(source, cursor);\n if (!validated && verdict === 'canonical') {\n // A short window (a reset checkpoint) is refilled from the chain below the\n // validated block, so a reorg within the window still rolls back.\n const recent = await this.refill(source, windowOf(cursor));\n if (recent) cursor = { ...cursor, recent };\n else verdict = undefined;\n }\n validated = verdict !== undefined;\n step =\n verdict === 'canonical'\n ? await this.nextBlock(source, cursor, await tip())\n : verdict;\n }\n } catch (error) {\n // Like `watch`: a transient provider failure is retried on the next poll.\n if (signal?.aborted) return;\n if (!isCryptoAioError(error) || !error.retryable) throw error;\n }\n if (signal?.aborted) return;\n if (!step) {\n try {\n await this.deps.clock.sleep(poll, signal);\n } catch {\n return;\n }\n continue;\n }\n const { event, next } = step;\n let acked = false;\n let commit: Promise<void> | undefined;\n // Set once one of our puts for this event ended without a known outcome.\n let uncertain = false;\n const commitCursor = async (): Promise<void> => {\n try {\n version = await this.deps.cursors.put(key, next, version);\n } catch (error) {\n const conflict = isCryptoAioError(error, 'VERSION_CONFLICT');\n // A conflict may be our own put having landed only after one ended unseen (or when\n // the store says so); a first-try conflict is another scanner on this key.\n const recheck = conflict && (uncertain || error.ambiguous);\n const stored = recheck ? await this.deps.cursors.get(key) : null;\n if (!stored || !sameCursor(stored.cursor, next)) {\n if (!conflict) uncertain = true;\n throw error;\n }\n version = stored.version;\n }\n cursor = next;\n acked = true;\n this.emit(event);\n };\n yield {\n ...event,\n // Concurrent calls share one commit; a failed commit can be retried.\n ack: () =>\n (commit ??= commitCursor().catch((error: unknown) => {\n commit = undefined;\n throw error;\n })),\n };\n if (!acked) {\n throw new StateError(\n 'INVALID_TRANSITION',\n 'ack() the previous scan event before requesting the next one',\n );\n }\n }\n }\n\n /** Normalizes the filter on this chain and network (the driver's codec and asset service). */\n private async scanFilter(mapping: MappingContext): Promise<ScanFilter | undefined> {\n const { addresses, assets } = this.options.filter ?? {};\n if (addresses === undefined && assets === undefined) return undefined;\n const { selection, driver } = mapping;\n return {\n ...(addresses\n ? { addresses: addresses.map((a) => driver.address.normalize(a).canonical) }\n : {}),\n ...(assets\n ? {\n assets: await Promise.all(\n assets.map(\n async (a) => (await mapping.assets.resolve(selection, driver, a)).ref,\n ),\n ),\n }\n : {}),\n };\n }\n\n /**\n * A new cursor sits just below the start height and retains the `window` blocks beneath\n * it, so a reorg early in the scan is still resolvable. `undefined` (wait) while the\n * chain's tip for this mode is below the start's parent, or its blocks are not visible\n * as one consistent chain yet.\n */\n private async initialCursor(\n source: Source,\n tip: bigint,\n ): Promise<ScanCursor | undefined> {\n const from = this.options.from ?? 'latest';\n const start = from === 'latest' ? tip : from;\n if (start <= 0n) return { height: -1n, hash: '', recent: [] };\n if (start - 1n > tip) return undefined;\n const recent = await this.loadWindow(source, start - 1n, source.window);\n const top = recent?.[recent.length - 1];\n return recent && top && { height: top.height, hash: top.hash, recent };\n }\n\n /**\n * Up to `count` checkpoints ending at `height`, oldest first, read down the parent links;\n * with `hash`, the block at `height` must have it. `undefined` (wait) when a block is not\n * visible or the links do not hold.\n */\n private async loadWindow(\n source: Source,\n height: bigint,\n count: number,\n hash?: string,\n ): Promise<Checkpoint[] | undefined> {\n const loaded: Checkpoint[] = [];\n let expected = hash;\n for (let h = height; h >= 0n && loaded.length < count; h--) {\n const header = await source.blocks.header(h);\n if (!header || (expected !== undefined && header.hash !== expected))\n return undefined;\n loaded.unshift({ height: header.height, hash: header.hash });\n expected = header.parentHash;\n }\n return loaded;\n }\n\n /**\n * Extends a window that a rollback trimmed back down to `window` entries from the chain,\n * which is canonical at and below the common ancestor. `undefined` (wait) on a gap.\n */\n private async refill(\n source: Source,\n kept: readonly Checkpoint[],\n ): Promise<readonly Checkpoint[] | undefined> {\n const oldest = kept[0];\n if (!oldest || kept.length >= source.window || oldest.height === 0n) return kept;\n const missing = source.window - kept.length;\n const below = await this.loadWindow(source, oldest.height, missing + 1, oldest.hash);\n return below && [...below.slice(0, -1), ...kept];\n }\n\n private async nextBlock(\n source: Source,\n cursor: ScanCursor,\n tip: bigint,\n ): Promise<Step | undefined> {\n const height = cursor.height + 1n;\n if (height > tip) return undefined;\n const header = await source.blocks.header(height);\n if (!header) return undefined;\n if (cursor.height >= 0n && header.parentHash !== cursor.hash) {\n const verdict = await this.findRollback(source, cursor);\n // The cursor's block is still canonical, so the two reads disagreed: look again later.\n return verdict === 'canonical' ? undefined : verdict;\n }\n const transactions = await source.blocks.transactions(header, source.filter);\n const reader = source.mapping.driver.reader;\n const [head, finalized] = await Promise.all([\n reader.getBlockHeight(),\n reader.getFinalizedHeight(),\n ]);\n const mapped = await Promise.all(\n transactions.map((tx) => toTransaction(source.mapping, tx, head, finalized)),\n );\n const checkpoint = { height: header.height, hash: header.hash };\n return {\n event: { type: 'block', block: toBlock(header), transactions: mapped },\n next: {\n ...checkpoint,\n recent: [...windowOf(cursor), checkpoint].slice(-source.window),\n },\n };\n }\n\n /**\n * Walks the retained window newest-first to the common ancestor with the canonical chain.\n * Returns `'canonical'` when the cursor's own block still is, a rollback step when an older\n * block is, and `undefined` when this view cannot decide: it is stale, or it does not show\n * a block yet (absence is never divergence). Throws `SCANNER_REORG_TOO_DEEP` only when\n * every retained block is visible and none is canonical. The rolled-back cursor's window\n * is refilled from the chain below the ancestor. A rollback or TOO_DEEP verdict of this\n * header walk stands only once the proof quorum confirms it, so one endpoint serving a\n * fork never rolls a cursor back. Only verdicts are confirmed: a block's transactions\n * are still read from the one endpoint that serves them.\n */\n private async findRollback(\n source: Source,\n cursor: ScanCursor,\n ): Promise<Step | 'canonical' | undefined> {\n if (cursor.height < 0n) return 'canonical';\n if (await this.staleView(source)) return undefined;\n const window = windowOf(cursor);\n const newestFirst = [...window].reverse();\n for (const [i, entry] of newestFirst.entries()) {\n const canonical = await source.blocks.header(entry.height);\n if (!canonical) return undefined;\n if (canonical.hash !== entry.hash) continue;\n if (i === 0) return 'canonical';\n if (!(await this.confirmed(source, newestFirst.slice(0, i), entry)))\n return undefined;\n const recent = await this.refill(\n source,\n window.filter((r) => r.height <= entry.height),\n );\n if (!recent) return undefined;\n return {\n event: { type: 'rollback', to: entry, removed: newestFirst.slice(0, i) },\n next: { height: entry.height, hash: entry.hash, recent },\n };\n }\n if (!(await this.confirmed(source, newestFirst))) return undefined;\n throw new StateError(\n 'SCANNER_REORG_TOO_DEEP',\n `the chain diverged deeper than the ${source.window}-block window of cursor '${this.options.cursorKey}'; reset the cursor explicitly`,\n );\n }\n\n /**\n * Whether the quorum-served hashes confirm a verdict: every `removed` block has been\n * replaced at its height, and `ancestor` (when given) is still canonical. No block at a\n * height decides nothing (`false`); a quorum that disagrees throws a retryable error,\n * which the scan loop also treats as \"look again later\".\n */\n private async confirmed(\n source: Source,\n removed: readonly Checkpoint[],\n ancestor?: Checkpoint,\n ): Promise<boolean> {\n const { proofs } = source.mapping.driver;\n for (const entry of removed) {\n const hash = await proofs.blockHash(entry.height, 'latest');\n if (hash === null || hash === entry.hash) return false;\n }\n if (ancestor === undefined) return true;\n return (await proofs.blockHash(ancestor.height, 'latest')) === ancestor.hash;\n }\n\n /** The monitor's stale-view guard (`isStaleView`): a stale view decides nothing. */\n private async staleView(source: Source): Promise<boolean> {\n return isStaleView(\n source.transport,\n await source.mapping.driver.reader.getBlockHeight(),\n );\n }\n\n /** Operational data only: never addresses, amounts or hashes. */\n private emit(event: ScanEventBody): void {\n if (event.type === 'block') {\n this.deps.events.emit('scanner.block', {\n namespace: this.deps.namespace,\n cursorKey: this.options.cursorKey,\n height: event.block.height.toString(),\n });\n } else {\n this.deps.events.emit('scanner.rollback', {\n namespace: this.deps.namespace,\n cursorKey: this.options.cursorKey,\n toHeight: event.to.height.toString(),\n removed: event.removed.length,\n });\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"scanner.js","sourceRoot":"","sources":["../../../src/core/observe/scanner.ts"],"names":[],"mappings":"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","sourcesContent":["import { toBlock, toTransaction, type MappingContext } from '../blockchain/mapping';\nimport type { BlockSource, ScanFilter } from '../driver/types';\nimport { ConfigError, StateError, isCryptoAioError } from '../errors/error';\nimport type { EventBus } from '../events/bus';\nimport type { AssetRef } from '../model/asset';\nimport type { Block, Transaction } from '../model/transaction';\nimport type { CursorStore, ScanCursor } from '../store/types';\nimport { isStaleView, type StaleViewSource } from '../transport/stale-view';\nimport type { Clock } from '../util/clock';\nimport { storableText } from '../util/names';\n\nexport interface ScannerOptions {\n /** Durable name of this consumer's position (namespaced per container, chain and network). */\n readonly cursorKey: string;\n /**\n * Where a NEW cursor starts; ignored when a stored cursor exists. Default `'latest'`. The\n * new cursor also retains the `reorgWindow` blocks below the start, so a rollback within\n * the first window can name blocks that were never delivered, and the replay that follows\n * can start below `from`.\n */\n readonly from?: 'latest' | bigint;\n /**\n * `'final'` emits finalized blocks only; a rollback can then still come from a provider\n * inconsistency. `'head'` follows the tip and may roll back within the window.\n * Default `'head'`. The mode is not stored with the cursor: resuming a head-mode cursor in\n * final mode keeps the unfinalized blocks it already delivered.\n */\n readonly mode?: 'final' | 'head';\n /** Passed to the driver's block source; each entry is resolved on this chain and network. */\n readonly filter?: {\n readonly addresses?: readonly string[];\n readonly assets?: readonly (AssetRef | string)[];\n };\n /** Blocks retained for rollback detection (default: the network's reorgWindow). */\n readonly reorgWindow?: number;\n readonly pollIntervalMs?: number;\n /**\n * Stops the scan, also while it waits for new blocks. `iterator.return()` only takes effect\n * once a pending `next()` settles, so an idle scanner is stopped with this signal.\n */\n readonly signal?: AbortSignal;\n}\n\nexport interface Checkpoint {\n readonly height: bigint;\n readonly hash: string;\n}\n\n/** A scan event without its `ack()`: a delivered block, or a rollback to a checkpoint. */\nexport type ScanEventBody =\n | {\n readonly type: 'block';\n readonly block: Block;\n readonly transactions: readonly Transaction[];\n }\n | {\n readonly type: 'rollback';\n readonly to: Checkpoint;\n readonly removed: readonly Checkpoint[];\n };\n\nexport type ScanEvent = ScanEventBody & { ack(): Promise<void> };\n\nexport interface ScannerDeps {\n readonly load: () => Promise<{\n readonly mapping: MappingContext;\n readonly blocks: BlockSource;\n /** The verified height watermark and lag tolerance behind the stale-view guard. */\n readonly transport: StaleViewSource;\n }>;\n readonly cursors: CursorStore;\n readonly events: EventBus;\n readonly clock: Clock;\n readonly namespace: string;\n readonly defaults: { readonly reorgWindow: number; readonly pollIntervalMs: number };\n}\n\ninterface Step {\n readonly event: ScanEventBody;\n readonly next: ScanCursor;\n}\n\n/** What one iteration of a scan reads through. */\ninterface Source {\n readonly mapping: MappingContext;\n readonly blocks: BlockSource;\n readonly transport: StaleViewSource;\n readonly window: number;\n readonly filter: ScanFilter | undefined;\n}\n\nconst isAssetInput = (value: unknown): boolean =>\n typeof value === 'string'\n ? value.length > 0\n : typeof value === 'object' &&\n value !== null &&\n typeof (value as { standard?: unknown }).standard === 'string' &&\n typeof (value as { contract?: unknown }).contract === 'string';\n\nfunction assertFilter(filter: ScannerOptions['filter'], invalid: (m: string) => Error) {\n if (filter === undefined) return;\n if (typeof filter !== 'object' || filter === null)\n throw invalid('filter must be an object');\n const { addresses, assets } = filter;\n if (\n addresses !== undefined &&\n (!Array.isArray(addresses) || !addresses.every((a) => typeof a === 'string'))\n )\n throw invalid('filter.addresses must be an array of address strings');\n if (assets !== undefined && (!Array.isArray(assets) || !assets.every(isAssetInput)))\n throw invalid('filter.assets must be an array of asset refs or asset ids');\n}\n\nfunction assertOptions(options: ScannerOptions): void {\n const invalid = (message: string) =>\n new ConfigError('CONFIG_INVALID', `scanner ${message}`);\n const { cursorKey, from, mode, reorgWindow, pollIntervalMs } = options;\n assertFilter(options.filter, invalid);\n if (typeof cursorKey !== 'string' || cursorKey.length === 0)\n throw invalid('cursorKey must be a non-empty string');\n if (!storableText(cursorKey))\n throw invalid('cursorKey must be well-formed text without U+0000');\n if (from !== undefined && from !== 'latest' && (typeof from !== 'bigint' || from < 0n))\n throw invalid(\"from must be 'latest' or a non-negative bigint height\");\n if (mode !== undefined && mode !== 'final' && mode !== 'head')\n throw invalid(\"mode must be 'final' or 'head'\");\n if (\n reorgWindow !== undefined &&\n (!Number.isSafeInteger(reorgWindow) || reorgWindow < 1)\n )\n throw invalid('reorgWindow must be a positive integer');\n if (\n pollIntervalMs !== undefined &&\n (typeof pollIntervalMs !== 'number' ||\n !Number.isFinite(pollIntervalMs) ||\n pollIntervalMs <= 0)\n )\n throw invalid('pollIntervalMs must be a finite number greater than 0');\n}\n\n/** The cursor's window; a reset checkpoint stored without one is its own window. */\nfunction windowOf(cursor: ScanCursor): readonly Checkpoint[] {\n if (cursor.recent.length > 0 || cursor.height < 0n) return cursor.recent;\n return [{ height: cursor.height, hash: cursor.hash }];\n}\n\nfunction sameCursor(a: ScanCursor, b: ScanCursor): boolean {\n return (\n a.height === b.height &&\n a.hash === b.hash &&\n a.recent.length === b.recent.length &&\n a.recent.every(\n (r, i) => r.height === b.recent[i]?.height && r.hash === b.recent[i]?.hash,\n )\n );\n}\n\n/**\n * Reorg-aware, at-least-once block scanner. Each event's `ack()` commits the\n * cursor (compare-and-set on its version, so two scanners sharing a `cursorKey` never both\n * commit the same advance); asking for the next event first throws `INVALID_TRANSITION`.\n * A view that cannot decide (stale, or missing a block) never causes a rollback: the\n * scanner waits a poll interval and looks again, as it does after a retryable provider error.\n *\n * A cursor stopped by `SCANNER_REORG_TOO_DEEP` is reset explicitly: scan under a new\n * `cursorKey`, or `put` a checkpoint `{ height, hash, recent }` for its key through the\n * `CursorStore`. A checkpoint without `recent` is validated on its own block, and its\n * window is then refilled from the chain below that block.\n */\nexport class Scanner implements AsyncIterable<ScanEvent> {\n constructor(\n private readonly deps: ScannerDeps,\n private readonly options: ScannerOptions,\n ) {\n assertOptions(options);\n }\n\n [Symbol.asyncIterator](): AsyncIterator<ScanEvent> {\n return this.run();\n }\n\n private async *run(): AsyncGenerator<ScanEvent> {\n const { signal } = this.options;\n const { mapping, blocks, transport } = await this.deps.load();\n const reader = mapping.driver.reader;\n const { chain, network } = mapping.selection;\n const key = `${this.deps.namespace}:${chain.id}:${network.id}:${this.options.cursorKey}`;\n const window = this.options.reorgWindow ?? this.deps.defaults.reorgWindow;\n // Resolved inside the loop, so a transient failure resolving filter.assets is retried.\n let source: Source | undefined;\n const poll = this.options.pollIntervalMs ?? this.deps.defaults.pollIntervalMs;\n const tip = () =>\n this.options.mode === 'final'\n ? reader.getFinalizedHeight()\n : reader.getBlockHeight();\n const stored = await this.deps.cursors.get(key);\n let version = stored?.version ?? null;\n let cursor = stored?.cursor;\n // A stored cursor is re-validated against the canonical chain before anything is emitted.\n let validated = stored === null;\n while (!signal?.aborted) {\n let step: Step | undefined;\n try {\n source ??= {\n mapping,\n blocks,\n transport,\n window,\n filter: await this.scanFilter(mapping),\n };\n cursor ??= await this.initialCursor(source, await tip());\n if (cursor) {\n let verdict = validated ? 'canonical' : await this.findRollback(source, cursor);\n if (!validated && verdict === 'canonical') {\n // A short window (a reset checkpoint) is refilled from the chain below the\n // validated block, so a reorg within the window still rolls back.\n const recent = await this.refill(source, windowOf(cursor));\n if (recent) cursor = { ...cursor, recent };\n else verdict = undefined;\n }\n validated = verdict !== undefined;\n step =\n verdict === 'canonical'\n ? await this.nextBlock(source, cursor, await tip())\n : verdict;\n }\n } catch (error) {\n // Like `watch`: a transient provider failure is retried on the next poll.\n if (signal?.aborted) return;\n if (!isCryptoAioError(error) || !error.retryable) throw error;\n }\n if (signal?.aborted) return;\n if (!step) {\n try {\n await this.deps.clock.sleep(poll, signal);\n } catch {\n return;\n }\n continue;\n }\n const { event, next } = step;\n let acked = false;\n let commit: Promise<void> | undefined;\n // Set once one of our puts for this event ended without a known outcome.\n let uncertain = false;\n const commitCursor = async (): Promise<void> => {\n try {\n version = await this.deps.cursors.put(key, next, version);\n } catch (error) {\n const conflict = isCryptoAioError(error, 'VERSION_CONFLICT');\n // A conflict may be our own put having landed only after one ended unseen (or when\n // the store says so); a first-try conflict is another scanner on this key.\n const recheck = conflict && (uncertain || error.ambiguous);\n const stored = recheck ? await this.deps.cursors.get(key) : null;\n if (!stored || !sameCursor(stored.cursor, next)) {\n if (!conflict) uncertain = true;\n throw error;\n }\n version = stored.version;\n }\n cursor = next;\n acked = true;\n this.emit(event);\n };\n yield {\n ...event,\n // Concurrent calls share one commit; a failed commit can be retried.\n ack: () =>\n (commit ??= commitCursor().catch((error: unknown) => {\n commit = undefined;\n throw error;\n })),\n };\n if (!acked) {\n throw new StateError(\n 'INVALID_TRANSITION',\n 'ack() the previous scan event before requesting the next one',\n );\n }\n }\n }\n\n /** Normalizes the filter on this chain and network (the driver's codec and asset service). */\n private async scanFilter(mapping: MappingContext): Promise<ScanFilter | undefined> {\n const { addresses, assets } = this.options.filter ?? {};\n if (addresses === undefined && assets === undefined) return undefined;\n const { selection, driver } = mapping;\n return {\n ...(addresses\n ? { addresses: addresses.map((a) => driver.address.normalize(a).canonical) }\n : {}),\n ...(assets\n ? {\n assets: await Promise.all(\n assets.map(\n async (a) => (await mapping.assets.resolve(selection, driver, a)).ref,\n ),\n ),\n }\n : {}),\n };\n }\n\n /**\n * A new cursor sits just below the start height and retains the `window` blocks beneath\n * it, so a reorg early in the scan is still resolvable. `undefined` (wait) while the\n * chain's tip for this mode is below the start's parent, or its blocks are not visible\n * as one consistent chain yet.\n */\n private async initialCursor(\n source: Source,\n tip: bigint,\n ): Promise<ScanCursor | undefined> {\n const from = this.options.from ?? 'latest';\n const start = from === 'latest' ? tip : from;\n if (start <= 0n) return { height: -1n, hash: '', recent: [] };\n if (start - 1n > tip) return undefined;\n const recent = await this.loadWindow(source, start - 1n, source.window);\n const top = recent?.[recent.length - 1];\n return recent && top && { height: top.height, hash: top.hash, recent };\n }\n\n /**\n * Up to `count` checkpoints ending at `height`, oldest first, read down the parent links;\n * with `hash`, the block at `height` must have it. `undefined` (wait) when a block is not\n * visible or the links do not hold.\n */\n private async loadWindow(\n source: Source,\n height: bigint,\n count: number,\n hash?: string,\n ): Promise<Checkpoint[] | undefined> {\n const loaded: Checkpoint[] = [];\n let expected = hash;\n for (let h = height; h >= 0n && loaded.length < count; h--) {\n const header = await source.blocks.header(h);\n if (!header || (expected !== undefined && header.hash !== expected))\n return undefined;\n loaded.unshift({ height: header.height, hash: header.hash });\n expected = header.parentHash;\n }\n return loaded;\n }\n\n /**\n * Extends a window that a rollback trimmed back down to `window` entries from the chain,\n * which is canonical at and below the common ancestor. `undefined` (wait) on a gap.\n */\n private async refill(\n source: Source,\n kept: readonly Checkpoint[],\n ): Promise<readonly Checkpoint[] | undefined> {\n const oldest = kept[0];\n if (!oldest || kept.length >= source.window || oldest.height === 0n) return kept;\n const missing = source.window - kept.length;\n const below = await this.loadWindow(source, oldest.height, missing + 1, oldest.hash);\n return below && [...below.slice(0, -1), ...kept];\n }\n\n private async nextBlock(\n source: Source,\n cursor: ScanCursor,\n tip: bigint,\n ): Promise<Step | undefined> {\n const height = cursor.height + 1n;\n if (height > tip) return undefined;\n const header = await source.blocks.header(height);\n if (!header) return undefined;\n if (cursor.height >= 0n && header.parentHash !== cursor.hash) {\n const verdict = await this.findRollback(source, cursor);\n // The cursor's block is still canonical, so the two reads disagreed: look again later.\n return verdict === 'canonical' ? undefined : verdict;\n }\n const transactions = await source.blocks.transactions(header, source.filter);\n const reader = source.mapping.driver.reader;\n const [head, finalized] = await Promise.all([\n reader.getBlockHeight(),\n reader.getFinalizedHeight(),\n ]);\n const mapped = await Promise.all(\n transactions.map((tx) => toTransaction(source.mapping, tx, head, finalized)),\n );\n const checkpoint = { height: header.height, hash: header.hash };\n return {\n event: { type: 'block', block: toBlock(header), transactions: mapped },\n next: {\n ...checkpoint,\n recent: [...windowOf(cursor), checkpoint].slice(-source.window),\n },\n };\n }\n\n /**\n * Walks the retained window newest-first to the common ancestor with the canonical chain.\n * Returns `'canonical'` when the cursor's own block still is, a rollback step when an older\n * block is, and `undefined` when this view cannot decide: it is stale, or it does not show\n * a block yet (absence is never divergence). Throws `SCANNER_REORG_TOO_DEEP` only when\n * every retained block is visible and none is canonical. The rolled-back cursor's window\n * is refilled from the chain below the ancestor. A rollback or TOO_DEEP verdict of this\n * header walk stands only once the proof quorum confirms it, so one endpoint serving a\n * fork never rolls a cursor back. Only verdicts are confirmed: a block's transactions\n * are still read from the one endpoint that serves them.\n */\n private async findRollback(\n source: Source,\n cursor: ScanCursor,\n ): Promise<Step | 'canonical' | undefined> {\n if (cursor.height < 0n) return 'canonical';\n if (await this.staleView(source)) return undefined;\n const window = windowOf(cursor);\n const newestFirst = [...window].reverse();\n for (const [i, entry] of newestFirst.entries()) {\n const canonical = await source.blocks.header(entry.height);\n if (!canonical) return undefined;\n if (canonical.hash !== entry.hash) continue;\n if (i === 0) return 'canonical';\n if (!(await this.confirmed(source, newestFirst.slice(0, i), entry)))\n return undefined;\n const recent = await this.refill(\n source,\n window.filter((r) => r.height <= entry.height),\n );\n if (!recent) return undefined;\n return {\n event: { type: 'rollback', to: entry, removed: newestFirst.slice(0, i) },\n next: { height: entry.height, hash: entry.hash, recent },\n };\n }\n if (!(await this.confirmed(source, newestFirst))) return undefined;\n throw new StateError(\n 'SCANNER_REORG_TOO_DEEP',\n `the chain diverged deeper than the ${source.window}-block window of cursor '${this.options.cursorKey}'; reset the cursor explicitly`,\n );\n }\n\n /**\n * Whether the quorum-served hashes confirm a verdict: every `removed` block has been\n * replaced at its height, and `ancestor` (when given) is still canonical. No block at a\n * height decides nothing (`false`); a quorum that disagrees throws a retryable error,\n * which the scan loop also treats as \"look again later\".\n */\n private async confirmed(\n source: Source,\n removed: readonly Checkpoint[],\n ancestor?: Checkpoint,\n ): Promise<boolean> {\n const { proofs } = source.mapping.driver;\n for (const entry of removed) {\n const hash = await proofs.blockHash(entry.height, 'latest');\n if (hash === null || hash === entry.hash) return false;\n }\n if (ancestor === undefined) return true;\n return (await proofs.blockHash(ancestor.height, 'latest')) === ancestor.hash;\n }\n\n /** The monitor's stale-view guard (`isStaleView`): a stale view decides nothing. */\n private async staleView(source: Source): Promise<boolean> {\n return isStaleView(\n source.transport,\n await source.mapping.driver.reader.getBlockHeight(),\n );\n }\n\n /** Operational data only: never addresses, amounts or hashes. */\n private emit(event: ScanEventBody): void {\n if (event.type === 'block') {\n this.deps.events.emit('scanner.block', {\n namespace: this.deps.namespace,\n cursorKey: this.options.cursorKey,\n height: event.block.height.toString(),\n });\n } else {\n this.deps.events.emit('scanner.rollback', {\n namespace: this.deps.namespace,\n cursorKey: this.options.cursorKey,\n toHeight: event.to.height.toString(),\n removed: event.removed.length,\n });\n }\n }\n}\n"]}
|
|
@@ -89,6 +89,14 @@ deadline) {
|
|
|
89
89
|
// The signer is user-supplied code; its scheme list and keys are guarded.
|
|
90
90
|
const { id, instance } = selection.signer;
|
|
91
91
|
const supported = (0, guard_1.signerSchemes)(id, instance);
|
|
92
|
+
// Selection checked that the signer has one of the chain's schemes; a wallet whose
|
|
93
|
+
// options narrow them (a `p2tr` wallet signs with Schnorr only) needs each scheme it
|
|
94
|
+
// signs with. Refused here, before any key is read, so a transfer is never built or
|
|
95
|
+
// reserved only to fail at signing.
|
|
96
|
+
const missing = (driver.signingSchemes?.(options) ?? []).filter((scheme) => !supported.includes(scheme));
|
|
97
|
+
if (missing.length > 0) {
|
|
98
|
+
throw new error_1.ConfigError('CONFIG_INVALID', `signer '${id}' supports ${supported.join(', ')} but wallet '${wallet.name}' needs ${missing.join(', ')}`);
|
|
99
|
+
}
|
|
92
100
|
for (const scheme of selection.chain.schemes) {
|
|
93
101
|
if (!supported.includes(scheme))
|
|
94
102
|
continue;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wallet.js","sourceRoot":"","sources":["../../../src/core/signing/wallet.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ResolvedSelection, WalletConfig } from '../config/types';\nimport type { ChainDriver, WalletKey, WalletOptions } from '../driver/types';\nimport { ConfigError } from '../errors/error';\nimport { Address } from '../model/address';\nimport type { SchemeCatalog } from '../registry/schemes';\nimport { fromHex } from '../util/bytes';\nimport { signerPublicKey, signerSchemes, type SignerDeadline } from './guard';\nimport { parseExtendedPublicKey, type ExtendedKeyVersions } from './hd';\nimport type { KeyRef, Signer } from './types';\n\nexport interface ResolvedWallet {\n readonly name: string;\n readonly config: WalletConfig;\n readonly address: Address;\n /** One key per chain scheme the signer supports; `keys[0]` defines the address. */\n readonly keys: readonly WalletKey[];\n readonly options: WalletOptions;\n readonly watchOnly: boolean;\n readonly tier?: string;\n signerFor(\n keyRef?: KeyRef,\n ): { readonly id: string; readonly signer: Signer } | undefined;\n /** The signer with this id (own keys only), e.g. to cancel a ticket through its issuer. */\n signerById(id: string): { readonly id: string; readonly signer: Signer } | undefined;\n}\n\n/**\n * The wallet's extended public key as drivers receive it, `WalletOptions.hd`: plain,\n * frozen data, present only when the wallet configures a non-empty `xpub` (an empty\n * one counts as none, as in `deriveAddress`), which must be a readable PUBLIC extended key\n * (`CONFIG_INVALID` otherwise, naming no key).\n */\nexport interface WalletHdOptions {\n readonly xpub: string;\n /** Child path template relative to the xpub; `{index}` is replaced. Default `0/{index}`. */\n readonly xpubPath?: string;\n readonly xpubVersions?: ExtendedKeyVersions;\n}\n\nexport function walletOptionsOf(config: WalletConfig): WalletOptions {\n // `hd` is the core's own key: the wallet's xpub or nothing, never a user option, since\n // a driver trusts it to validate change addresses.\n const { hd: _ignored, ...options } = config.options ?? {};\n return {\n ...options,\n ...(config.utxo ? { utxo: config.utxo } : {}),\n ...(config.ton ? { ton: config.ton } : {}),\n // A falsy `xpub` ('', null) is no xpub, as `deriveAddress` reads it.\n ...(config.xpub ? { hd: hdOptionsOf(config) } : {}),\n };\n}\n\n/**\n * The wallet's `xpubPath`, `undefined` when absent (`undefined` or `null`, as\n * `deriveAddress` reads it). One that is present but not a string is `CONFIG_INVALID` with a\n * fixed text. Wallet resolution and `deriveAddress` share this check.\n */\nexport function xpubPathOf(config: WalletConfig): string | undefined {\n const path: unknown = config.xpubPath;\n if (path === undefined || path === null) return undefined;\n if (typeof path !== 'string') {\n throw new ConfigError('CONFIG_INVALID', 'xpubPath must be a string');\n }\n return path;\n}\n\nfunction hdOptionsOf(config: WalletConfig): WalletHdOptions {\n const xpubPath = xpubPathOf(config);\n const versions = config.xpubVersions;\n // The frozen copy comes first, reading each field once, and the key is read against\n // it, so it is checked against exactly the versions a driver receives.\n const hd: WalletHdOptions = Object.freeze({\n xpub: config.xpub as string,\n ...(xpubPath !== undefined ? { xpubPath } : {}),\n // The version pair only, never other keys of the caller's object.\n ...(versions\n ? {\n xpubVersions: Object.freeze({\n private: versions.private,\n public: versions.public,\n }),\n }\n : {}),\n });\n // Only a readable, PUBLIC extended key ever reaches a driver.\n parseExtendedPublicKey(hd.xpub, hd.xpubVersions);\n return hd;\n}\n\n/**\n * A watch-only wallet's `publicKey` is checked as a signer's key is: hex of\n * exactly the length its scheme defines. Any other key fails here, never later: an\n * uncompressed secp256k1 key derives an address but never verifies a signature.\n */\nfunction watchOnlyKey(\n name: string,\n hex: unknown,\n scheme: string,\n length: number,\n): Uint8Array {\n let key: Uint8Array | undefined;\n try {\n key = typeof hex === 'string' ? fromHex(hex) : undefined;\n } catch {\n key = undefined;\n }\n if (key === undefined || key.length !== length) {\n throw new ConfigError(\n 'CONFIG_INVALID',\n `wallet '${name}': publicKey must be ${length} bytes of hex for ${scheme}`,\n );\n }\n return key;\n}\n\nexport async function resolveWallet(\n selection: ResolvedSelection,\n driver: ChainDriver,\n signers: Readonly<Record<string, Signer>>,\n schemes: SchemeCatalog,\n /** Bounds each public-key read (`lifecycle.signTimeoutMs`). */\n deadline?: SignerDeadline,\n): Promise<ResolvedWallet> {\n const wallet = selection.wallet;\n if (!wallet) {\n throw new ConfigError(\n 'CONFIG_INVALID',\n `no wallet selected for ${selection.chain.id}; pass { wallet } or set chains.${selection.chain.id}.wallet`,\n );\n }\n const { config } = wallet;\n const options = walletOptionsOf(config);\n const keyRef = config.keyRef;\n const keys: WalletKey[] = [];\n if (selection.signer) {\n // The signer is user-supplied code; its scheme list and keys are guarded.\n const { id, instance } = selection.signer;\n const supported = signerSchemes(id, instance);\n for (const scheme of selection.chain.schemes) {\n if (!supported.includes(scheme)) continue;\n const { publicKeyLength } = schemes.get(scheme);\n const publicKey = await signerPublicKey(\n id,\n instance,\n scheme,\n keyRef,\n publicKeyLength,\n deadline,\n );\n keys.push({ scheme, publicKey, ...(keyRef ? { keyRef } : {}) });\n }\n } else if (config.publicKey) {\n const scheme = selection.chain.schemes[0] as string;\n keys.push({\n scheme,\n publicKey: watchOnlyKey(\n wallet.name,\n config.publicKey,\n scheme,\n schemes.get(scheme).publicKeyLength,\n ),\n ...(keyRef ? { keyRef } : {}),\n });\n }\n const first = keys[0];\n const derived = first\n ? driver.address.fromPublicKey(first.publicKey, options)\n : undefined;\n const configured =\n config.address !== undefined ? driver.address.normalize(config.address) : undefined;\n if (derived && configured && derived.canonical !== configured.canonical) {\n throw new ConfigError(\n 'CONFIG_INVALID',\n `wallet '${wallet.name}': configured address does not match its public key`,\n );\n }\n const normalized = configured ?? derived;\n if (!normalized) {\n throw new ConfigError(\n 'CONFIG_INVALID',\n `wallet '${wallet.name}' needs a signer, a publicKey or an address`,\n );\n }\n const primary = selection.signer;\n return {\n name: wallet.name,\n config,\n address: new Address(selection.chain.id, normalized, driver.address.format),\n keys,\n options,\n watchOnly: !primary,\n ...(config.tier !== undefined ? { tier: config.tier } : {}),\n signerFor: (ref) => {\n // Own keys only: a key ref named `toString` routes nowhere.\n const routes = config.signers ?? {};\n const routed =\n ref?.id !== undefined && Object.hasOwn(routes, ref.id)\n ? routes[ref.id]\n : undefined;\n const id = routed ?? primary?.id;\n if (id === undefined) return undefined;\n const signer =\n id === primary?.id\n ? primary.instance\n : Object.hasOwn(signers, id)\n ? signers[id]\n : undefined;\n return signer ? { id, signer } : undefined;\n },\n signerById: (id) => {\n if (id === primary?.id) return { id, signer: primary.instance };\n const signer = Object.hasOwn(signers, id) ? signers[id] : undefined;\n return signer ? { id, signer } : undefined;\n },\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"wallet.js","sourceRoot":"","sources":["../../../src/core/signing/wallet.ts"],"names":[],"mappings":";;AAuCA,0CAWC;AAOD,gCAOC;AAmDD,sCAiHC;AAlOD,2CAA8C;AAC9C,8CAA2C;AAE3C,yCAAwC;AACxC,mCAA8E;AAC9E,6BAAwE;AAgCxE,SAAgB,eAAe,CAAC,MAAoB;IAClD,uFAAuF;IACvF,mDAAmD;IACnD,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,GAAG,OAAO,EAAE,GAAG,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC;IAC1D,OAAO;QACL,GAAG,OAAO;QACV,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7C,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1C,qEAAqE;QACrE,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACpD,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAgB,UAAU,CAAC,MAAoB;IAC7C,MAAM,IAAI,GAAY,MAAM,CAAC,QAAQ,CAAC;IACtC,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,SAAS,CAAC;IAC1D,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,MAAM,IAAI,mBAAW,CAAC,gBAAgB,EAAE,2BAA2B,CAAC,CAAC;IACvE,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,WAAW,CAAC,MAAoB;IACvC,MAAM,QAAQ,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;IACpC,MAAM,QAAQ,GAAG,MAAM,CAAC,YAAY,CAAC;IACrC,oFAAoF;IACpF,uEAAuE;IACvE,MAAM,EAAE,GAAoB,MAAM,CAAC,MAAM,CAAC;QACxC,IAAI,EAAE,MAAM,CAAC,IAAc;QAC3B,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/C,kEAAkE;QAClE,GAAG,CAAC,QAAQ;YACV,CAAC,CAAC;gBACE,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC;oBAC1B,OAAO,EAAE,QAAQ,CAAC,OAAO;oBACzB,MAAM,EAAE,QAAQ,CAAC,MAAM;iBACxB,CAAC;aACH;YACH,CAAC,CAAC,EAAE,CAAC;KACR,CAAC,CAAC;IACH,8DAA8D;IAC9D,IAAA,2BAAsB,EAAC,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC;IACjD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;;;;GAIG;AACH,SAAS,YAAY,CACnB,IAAY,EACZ,GAAY,EACZ,MAAc,EACd,MAAc;IAEd,IAAI,GAA2B,CAAC;IAChC,IAAI,CAAC;QACH,GAAG,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAA,eAAO,EAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC3D,CAAC;IAAC,MAAM,CAAC;QACP,GAAG,GAAG,SAAS,CAAC;IAClB,CAAC;IACD,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QAC/C,MAAM,IAAI,mBAAW,CACnB,gBAAgB,EAChB,WAAW,IAAI,wBAAwB,MAAM,qBAAqB,MAAM,EAAE,CAC3E,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAEM,KAAK,UAAU,aAAa,CACjC,SAA4B,EAC5B,MAAmB,EACnB,OAAyC,EACzC,OAAsB;AACtB,+DAA+D;AAC/D,QAAyB;IAEzB,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC;IAChC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,mBAAW,CACnB,gBAAgB,EAChB,0BAA0B,SAAS,CAAC,KAAK,CAAC,EAAE,mCAAmC,SAAS,CAAC,KAAK,CAAC,EAAE,SAAS,CAC3G,CAAC;IACJ,CAAC;IACD,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IAC1B,MAAM,OAAO,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAC7B,MAAM,IAAI,GAAgB,EAAE,CAAC;IAC7B,IAAI,SAAS,CAAC,MAAM,EAAE,CAAC;QACrB,0EAA0E;QAC1E,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,GAAG,SAAS,CAAC,MAAM,CAAC;QAC1C,MAAM,SAAS,GAAG,IAAA,qBAAa,EAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;QAC9C,mFAAmF;QACnF,qFAAqF;QACrF,oFAAoF;QACpF,oCAAoC;QACpC,MAAM,OAAO,GAAG,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAC7D,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CACxC,CAAC;QACF,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,mBAAW,CACnB,gBAAgB,EAChB,WAAW,EAAE,cAAc,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,MAAM,CAAC,IAAI,WAAW,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC1G,CAAC;QACJ,CAAC;QACD,KAAK,MAAM,MAAM,IAAI,SAAS,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;YAC7C,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC;gBAAE,SAAS;YAC1C,MAAM,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAChD,MAAM,SAAS,GAAG,MAAM,IAAA,uBAAe,EACrC,EAAE,EACF,QAAQ,EACR,MAAM,EACN,MAAM,EACN,eAAe,EACf,QAAQ,CACT,CAAC;YACF,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QAClE,CAAC;IACH,CAAC;SAAM,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAW,CAAC;QACpD,IAAI,CAAC,IAAI,CAAC;YACR,MAAM;YACN,SAAS,EAAE,YAAY,CACrB,MAAM,CAAC,IAAI,EACX,MAAM,CAAC,SAAS,EAChB,MAAM,EACN,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,eAAe,CACpC;YACD,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC9B,CAAC,CAAC;IACL,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACtB,MAAM,OAAO,GAAG,KAAK;QACnB,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC;QACxD,CAAC,CAAC,SAAS,CAAC;IACd,MAAM,UAAU,GACd,MAAM,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACtF,IAAI,OAAO,IAAI,UAAU,IAAI,OAAO,CAAC,SAAS,KAAK,UAAU,CAAC,SAAS,EAAE,CAAC;QACxE,MAAM,IAAI,mBAAW,CACnB,gBAAgB,EAChB,WAAW,MAAM,CAAC,IAAI,qDAAqD,CAC5E,CAAC;IACJ,CAAC;IACD,MAAM,UAAU,GAAG,UAAU,IAAI,OAAO,CAAC;IACzC,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,mBAAW,CACnB,gBAAgB,EAChB,WAAW,MAAM,CAAC,IAAI,6CAA6C,CACpE,CAAC;IACJ,CAAC;IACD,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC;IACjC,OAAO;QACL,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,MAAM;QACN,OAAO,EAAE,IAAI,iBAAO,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,EAAE,UAAU,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;QAC3E,IAAI;QACJ,OAAO;QACP,SAAS,EAAE,CAAC,OAAO;QACnB,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3D,SAAS,EAAE,CAAC,GAAG,EAAE,EAAE;YACjB,4DAA4D;YAC5D,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC;YACpC,MAAM,MAAM,GACV,GAAG,EAAE,EAAE,KAAK,SAAS,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC;gBACpD,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;gBAChB,CAAC,CAAC,SAAS,CAAC;YAChB,MAAM,EAAE,GAAG,MAAM,IAAI,OAAO,EAAE,EAAE,CAAC;YACjC,IAAI,EAAE,KAAK,SAAS;gBAAE,OAAO,SAAS,CAAC;YACvC,MAAM,MAAM,GACV,EAAE,KAAK,OAAO,EAAE,EAAE;gBAChB,CAAC,CAAC,OAAO,CAAC,QAAQ;gBAClB,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC;oBAC1B,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;oBACb,CAAC,CAAC,SAAS,CAAC;YAClB,OAAO,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QAC7C,CAAC;QACD,UAAU,EAAE,CAAC,EAAE,EAAE,EAAE;YACjB,IAAI,EAAE,KAAK,OAAO,EAAE,EAAE;gBAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC;YAChE,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YACpE,OAAO,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QAC7C,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import type { ResolvedSelection, WalletConfig } from '../config/types';\nimport type { ChainDriver, WalletKey, WalletOptions } from '../driver/types';\nimport { ConfigError } from '../errors/error';\nimport { Address } from '../model/address';\nimport type { SchemeCatalog } from '../registry/schemes';\nimport { fromHex } from '../util/bytes';\nimport { signerPublicKey, signerSchemes, type SignerDeadline } from './guard';\nimport { parseExtendedPublicKey, type ExtendedKeyVersions } from './hd';\nimport type { KeyRef, Signer } from './types';\n\nexport interface ResolvedWallet {\n readonly name: string;\n readonly config: WalletConfig;\n readonly address: Address;\n /** One key per chain scheme the signer supports; `keys[0]` defines the address. */\n readonly keys: readonly WalletKey[];\n readonly options: WalletOptions;\n readonly watchOnly: boolean;\n readonly tier?: string;\n signerFor(\n keyRef?: KeyRef,\n ): { readonly id: string; readonly signer: Signer } | undefined;\n /** The signer with this id (own keys only), e.g. to cancel a ticket through its issuer. */\n signerById(id: string): { readonly id: string; readonly signer: Signer } | undefined;\n}\n\n/**\n * The wallet's extended public key as drivers receive it, `WalletOptions.hd`: plain,\n * frozen data, present only when the wallet configures a non-empty `xpub` (an empty\n * one counts as none, as in `deriveAddress`), which must be a readable PUBLIC extended key\n * (`CONFIG_INVALID` otherwise, naming no key).\n */\nexport interface WalletHdOptions {\n readonly xpub: string;\n /** Child path template relative to the xpub; `{index}` is replaced. Default `0/{index}`. */\n readonly xpubPath?: string;\n readonly xpubVersions?: ExtendedKeyVersions;\n}\n\nexport function walletOptionsOf(config: WalletConfig): WalletOptions {\n // `hd` is the core's own key: the wallet's xpub or nothing, never a user option, since\n // a driver trusts it to validate change addresses.\n const { hd: _ignored, ...options } = config.options ?? {};\n return {\n ...options,\n ...(config.utxo ? { utxo: config.utxo } : {}),\n ...(config.ton ? { ton: config.ton } : {}),\n // A falsy `xpub` ('', null) is no xpub, as `deriveAddress` reads it.\n ...(config.xpub ? { hd: hdOptionsOf(config) } : {}),\n };\n}\n\n/**\n * The wallet's `xpubPath`, `undefined` when absent (`undefined` or `null`, as\n * `deriveAddress` reads it). One that is present but not a string is `CONFIG_INVALID` with a\n * fixed text. Wallet resolution and `deriveAddress` share this check.\n */\nexport function xpubPathOf(config: WalletConfig): string | undefined {\n const path: unknown = config.xpubPath;\n if (path === undefined || path === null) return undefined;\n if (typeof path !== 'string') {\n throw new ConfigError('CONFIG_INVALID', 'xpubPath must be a string');\n }\n return path;\n}\n\nfunction hdOptionsOf(config: WalletConfig): WalletHdOptions {\n const xpubPath = xpubPathOf(config);\n const versions = config.xpubVersions;\n // The frozen copy comes first, reading each field once, and the key is read against\n // it, so it is checked against exactly the versions a driver receives.\n const hd: WalletHdOptions = Object.freeze({\n xpub: config.xpub as string,\n ...(xpubPath !== undefined ? { xpubPath } : {}),\n // The version pair only, never other keys of the caller's object.\n ...(versions\n ? {\n xpubVersions: Object.freeze({\n private: versions.private,\n public: versions.public,\n }),\n }\n : {}),\n });\n // Only a readable, PUBLIC extended key ever reaches a driver.\n parseExtendedPublicKey(hd.xpub, hd.xpubVersions);\n return hd;\n}\n\n/**\n * A watch-only wallet's `publicKey` is checked as a signer's key is: hex of\n * exactly the length its scheme defines. Any other key fails here, never later: an\n * uncompressed secp256k1 key derives an address but never verifies a signature.\n */\nfunction watchOnlyKey(\n name: string,\n hex: unknown,\n scheme: string,\n length: number,\n): Uint8Array {\n let key: Uint8Array | undefined;\n try {\n key = typeof hex === 'string' ? fromHex(hex) : undefined;\n } catch {\n key = undefined;\n }\n if (key === undefined || key.length !== length) {\n throw new ConfigError(\n 'CONFIG_INVALID',\n `wallet '${name}': publicKey must be ${length} bytes of hex for ${scheme}`,\n );\n }\n return key;\n}\n\nexport async function resolveWallet(\n selection: ResolvedSelection,\n driver: ChainDriver,\n signers: Readonly<Record<string, Signer>>,\n schemes: SchemeCatalog,\n /** Bounds each public-key read (`lifecycle.signTimeoutMs`). */\n deadline?: SignerDeadline,\n): Promise<ResolvedWallet> {\n const wallet = selection.wallet;\n if (!wallet) {\n throw new ConfigError(\n 'CONFIG_INVALID',\n `no wallet selected for ${selection.chain.id}; pass { wallet } or set chains.${selection.chain.id}.wallet`,\n );\n }\n const { config } = wallet;\n const options = walletOptionsOf(config);\n const keyRef = config.keyRef;\n const keys: WalletKey[] = [];\n if (selection.signer) {\n // The signer is user-supplied code; its scheme list and keys are guarded.\n const { id, instance } = selection.signer;\n const supported = signerSchemes(id, instance);\n // Selection checked that the signer has one of the chain's schemes; a wallet whose\n // options narrow them (a `p2tr` wallet signs with Schnorr only) needs each scheme it\n // signs with. Refused here, before any key is read, so a transfer is never built or\n // reserved only to fail at signing.\n const missing = (driver.signingSchemes?.(options) ?? []).filter(\n (scheme) => !supported.includes(scheme),\n );\n if (missing.length > 0) {\n throw new ConfigError(\n 'CONFIG_INVALID',\n `signer '${id}' supports ${supported.join(', ')} but wallet '${wallet.name}' needs ${missing.join(', ')}`,\n );\n }\n for (const scheme of selection.chain.schemes) {\n if (!supported.includes(scheme)) continue;\n const { publicKeyLength } = schemes.get(scheme);\n const publicKey = await signerPublicKey(\n id,\n instance,\n scheme,\n keyRef,\n publicKeyLength,\n deadline,\n );\n keys.push({ scheme, publicKey, ...(keyRef ? { keyRef } : {}) });\n }\n } else if (config.publicKey) {\n const scheme = selection.chain.schemes[0] as string;\n keys.push({\n scheme,\n publicKey: watchOnlyKey(\n wallet.name,\n config.publicKey,\n scheme,\n schemes.get(scheme).publicKeyLength,\n ),\n ...(keyRef ? { keyRef } : {}),\n });\n }\n const first = keys[0];\n const derived = first\n ? driver.address.fromPublicKey(first.publicKey, options)\n : undefined;\n const configured =\n config.address !== undefined ? driver.address.normalize(config.address) : undefined;\n if (derived && configured && derived.canonical !== configured.canonical) {\n throw new ConfigError(\n 'CONFIG_INVALID',\n `wallet '${wallet.name}': configured address does not match its public key`,\n );\n }\n const normalized = configured ?? derived;\n if (!normalized) {\n throw new ConfigError(\n 'CONFIG_INVALID',\n `wallet '${wallet.name}' needs a signer, a publicKey or an address`,\n );\n }\n const primary = selection.signer;\n return {\n name: wallet.name,\n config,\n address: new Address(selection.chain.id, normalized, driver.address.format),\n keys,\n options,\n watchOnly: !primary,\n ...(config.tier !== undefined ? { tier: config.tier } : {}),\n signerFor: (ref) => {\n // Own keys only: a key ref named `toString` routes nowhere.\n const routes = config.signers ?? {};\n const routed =\n ref?.id !== undefined && Object.hasOwn(routes, ref.id)\n ? routes[ref.id]\n : undefined;\n const id = routed ?? primary?.id;\n if (id === undefined) return undefined;\n const signer =\n id === primary?.id\n ? primary.instance\n : Object.hasOwn(signers, id)\n ? signers[id]\n : undefined;\n return signer ? { id, signer } : undefined;\n },\n signerById: (id) => {\n if (id === primary?.id) return { id, signer: primary.instance };\n const signer = Object.hasOwn(signers, id) ? signers[id] : undefined;\n return signer ? { id, signer } : undefined;\n },\n };\n}\n"]}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Logger } from '../events/logger';
|
|
2
|
+
import type { OperationRecord, OperationStore } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* The format of the Operation records this version writes. A record holds the stored
|
|
5
|
+
* intent, the family's unsigned transaction and ordering data, and its Attempts; a release
|
|
6
|
+
* that changes how any of them is stored or read raises this number, and keeps reading
|
|
7
|
+
* every earlier format. Records written before formats existed (0.1.0) carry none and are
|
|
8
|
+
* format 1.
|
|
9
|
+
*/
|
|
10
|
+
export declare const OPERATION_FORMAT = 1;
|
|
11
|
+
/** The format of `record`: a record without one (0.1.0) is format 1. */
|
|
12
|
+
export declare function formatOf(record: OperationRecord): number;
|
|
13
|
+
/**
|
|
14
|
+
* The Operation store as the engine, the workers and `aio.operations` read it: every
|
|
15
|
+
* record it returns is in a format this version reads. A record a newer version wrote, as
|
|
16
|
+
* in a rolling upgrade, is never read as an older format: a read of it throws
|
|
17
|
+
* `RECORD_FORMAT_UNSUPPORTED`, and a worker pass releases its claim and leaves it to a
|
|
18
|
+
* process that reads it.
|
|
19
|
+
*/
|
|
20
|
+
export declare function formatGuard(store: OperationStore, log: Logger): OperationStore;
|