crypto-aio 0.2.0 → 1.0.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. package/CHANGELOG.md +70 -2
  2. package/README.md +16 -10
  3. package/dist/adapters/avalanche/driver.d.ts +4 -0
  4. package/dist/adapters/avalanche/driver.js.map +1 -1
  5. package/dist/adapters/avalanche/sdk.d.ts +15 -0
  6. package/dist/adapters/avalanche/sdk.js.map +1 -1
  7. package/dist/adapters/evm/plugin.d.ts +1 -0
  8. package/dist/adapters/evm/plugin.js.map +1 -1
  9. package/dist/adapters/ton/network.d.ts +1 -0
  10. package/dist/adapters/ton/network.js +1 -0
  11. package/dist/adapters/ton/network.js.map +1 -1
  12. package/dist/adapters/ton/types.d.ts +1 -0
  13. package/dist/adapters/ton/types.js.map +1 -1
  14. package/dist/adapters/tron/decode.js +3 -2
  15. package/dist/adapters/tron/decode.js.map +1 -1
  16. package/dist/adapters/tron/http.d.ts +6 -0
  17. package/dist/adapters/tron/http.js +9 -0
  18. package/dist/adapters/tron/http.js.map +1 -1
  19. package/dist/adapters/tron/network.d.ts +4 -0
  20. package/dist/adapters/tron/network.js +4 -0
  21. package/dist/adapters/tron/network.js.map +1 -1
  22. package/dist/adapters/tron/proofs.js +6 -2
  23. package/dist/adapters/tron/proofs.js.map +1 -1
  24. package/dist/adapters/tron/reader.js +1 -1
  25. package/dist/adapters/tron/reader.js.map +1 -1
  26. package/dist/adapters/utxo/driver.d.ts +4 -0
  27. package/dist/adapters/utxo/driver.js.map +1 -1
  28. package/dist/adapters/utxo/esplora.d.ts +6 -0
  29. package/dist/adapters/utxo/esplora.js +20 -3
  30. package/dist/adapters/utxo/esplora.js.map +1 -1
  31. package/dist/adapters/utxo/types.d.ts +1 -0
  32. package/dist/adapters/utxo/types.js.map +1 -1
  33. package/dist/core/blockchain/handle.d.ts +6 -1
  34. package/dist/core/blockchain/handle.js +1 -1
  35. package/dist/core/blockchain/handle.js.map +1 -1
  36. package/dist/core/config/types.d.ts +64 -0
  37. package/dist/core/config/types.js.map +1 -1
  38. package/dist/core/container/container.d.ts +3 -0
  39. package/dist/core/container/container.js.map +1 -1
  40. package/dist/core/container/pool.js +12 -0
  41. package/dist/core/container/pool.js.map +1 -1
  42. package/dist/core/driver/types.d.ts +124 -7
  43. package/dist/core/driver/types.js.map +1 -1
  44. package/dist/core/errors/codes.d.ts +3 -0
  45. package/dist/core/errors/codes.js.map +1 -1
  46. package/dist/core/errors/error.d.ts +26 -0
  47. package/dist/core/errors/error.js +20 -0
  48. package/dist/core/errors/error.js.map +1 -1
  49. package/dist/core/events/logger.d.ts +17 -1
  50. package/dist/core/events/logger.js +5 -1
  51. package/dist/core/events/logger.js.map +1 -1
  52. package/dist/core/events/types.d.ts +26 -1
  53. package/dist/core/events/types.js.map +1 -1
  54. package/dist/core/lifecycle/engine.d.ts +5 -0
  55. package/dist/core/lifecycle/engine.js.map +1 -1
  56. package/dist/core/lifecycle/monitor.d.ts +6 -0
  57. package/dist/core/lifecycle/monitor.js.map +1 -1
  58. package/dist/core/lifecycle/views.d.ts +5 -0
  59. package/dist/core/lifecycle/views.js.map +1 -1
  60. package/dist/core/lifecycle/workers.d.ts +1 -0
  61. package/dist/core/lifecycle/workers.js.map +1 -1
  62. package/dist/core/model/address.d.ts +4 -0
  63. package/dist/core/model/address.js.map +1 -1
  64. package/dist/core/model/amount.d.ts +5 -0
  65. package/dist/core/model/amount.js.map +1 -1
  66. package/dist/core/model/asset.d.ts +11 -0
  67. package/dist/core/model/asset.js +2 -0
  68. package/dist/core/model/asset.js.map +1 -1
  69. package/dist/core/model/capability.d.ts +6 -0
  70. package/dist/core/model/capability.js +4 -0
  71. package/dist/core/model/capability.js.map +1 -1
  72. package/dist/core/model/chain.d.ts +19 -0
  73. package/dist/core/model/chain.js +1 -0
  74. package/dist/core/model/chain.js.map +1 -1
  75. package/dist/core/model/fee.d.ts +24 -1
  76. package/dist/core/model/fee.js.map +1 -1
  77. package/dist/core/model/ids.d.ts +10 -7
  78. package/dist/core/model/ids.js +1 -0
  79. package/dist/core/model/ids.js.map +1 -1
  80. package/dist/core/model/intent.d.ts +13 -0
  81. package/dist/core/model/intent.js.map +1 -1
  82. package/dist/core/model/ordering.d.ts +5 -0
  83. package/dist/core/model/ordering.js.map +1 -1
  84. package/dist/core/model/transaction.d.ts +39 -0
  85. package/dist/core/model/transaction.js.map +1 -1
  86. package/dist/core/observe/scanner.d.ts +10 -1
  87. package/dist/core/observe/scanner.js +6 -0
  88. package/dist/core/observe/scanner.js.map +1 -1
  89. package/dist/core/registry/assets.d.ts +5 -0
  90. package/dist/core/registry/assets.js.map +1 -1
  91. package/dist/core/registry/plugin.d.ts +6 -1
  92. package/dist/core/registry/plugin.js.map +1 -1
  93. package/dist/core/registry/providers.d.ts +5 -0
  94. package/dist/core/registry/providers.js.map +1 -1
  95. package/dist/core/registry/schemes.d.ts +7 -0
  96. package/dist/core/registry/schemes.js.map +1 -1
  97. package/dist/core/secret/redact.d.ts +9 -0
  98. package/dist/core/secret/redact.js +9 -0
  99. package/dist/core/secret/redact.js.map +1 -1
  100. package/dist/core/secret/secret.d.ts +4 -0
  101. package/dist/core/secret/secret.js +4 -0
  102. package/dist/core/secret/secret.js.map +1 -1
  103. package/dist/core/signing/callback.d.ts +5 -0
  104. package/dist/core/signing/callback.js.map +1 -1
  105. package/dist/core/signing/hd.d.ts +4 -0
  106. package/dist/core/signing/hd.js.map +1 -1
  107. package/dist/core/signing/local.d.ts +17 -0
  108. package/dist/core/signing/local.js +5 -0
  109. package/dist/core/signing/local.js.map +1 -1
  110. package/dist/core/signing/types.d.ts +35 -1
  111. package/dist/core/signing/types.js.map +1 -1
  112. package/dist/core/store/format.d.ts +3 -3
  113. package/dist/core/store/format.js +18 -8
  114. package/dist/core/store/format.js.map +1 -1
  115. package/dist/core/store/memory.d.ts +11 -0
  116. package/dist/core/store/memory.js +11 -0
  117. package/dist/core/store/memory.js.map +1 -1
  118. package/dist/core/store/types.d.ts +164 -3
  119. package/dist/core/store/types.js +4 -0
  120. package/dist/core/store/types.js.map +1 -1
  121. package/dist/core/transport/http-transport.js +33 -13
  122. package/dist/core/transport/http-transport.js.map +1 -1
  123. package/dist/core/transport/types.d.ts +70 -0
  124. package/dist/core/transport/types.js.map +1 -1
  125. package/dist/core/util/clock.d.ts +6 -0
  126. package/dist/core/util/clock.js.map +1 -1
  127. package/dist/core/util/json.d.ts +6 -0
  128. package/dist/core/util/json.js +21 -8
  129. package/dist/core/util/json.js.map +1 -1
  130. package/dist/testing/contracts/api.d.ts +1 -0
  131. package/dist/testing/contracts/api.js +1 -0
  132. package/dist/testing/contracts/api.js.map +1 -1
  133. package/dist/testing/contracts/cursors.d.ts +5 -0
  134. package/dist/testing/contracts/cursors.js +4 -0
  135. package/dist/testing/contracts/cursors.js.map +1 -1
  136. package/dist/testing/contracts/locks.d.ts +6 -0
  137. package/dist/testing/contracts/locks.js +5 -0
  138. package/dist/testing/contracts/locks.js.map +1 -1
  139. package/dist/testing/contracts/operations.d.ts +11 -0
  140. package/dist/testing/contracts/operations.js +10 -0
  141. package/dist/testing/contracts/operations.js.map +1 -1
  142. package/dist/testing/contracts/sequences.d.ts +5 -0
  143. package/dist/testing/contracts/sequences.js +4 -0
  144. package/dist/testing/contracts/sequences.js.map +1 -1
  145. package/dist/testing/env.d.ts +11 -0
  146. package/dist/testing/env.js +1 -0
  147. package/dist/testing/env.js.map +1 -1
  148. package/dist/testing/fake-chain.d.ts +32 -0
  149. package/dist/testing/fake-chain.js +11 -0
  150. package/dist/testing/fake-chain.js.map +1 -1
  151. package/dist/testing/fake-driver.d.ts +2 -0
  152. package/dist/testing/fake-driver.js.map +1 -1
  153. package/dist/testing/fake-fetch.d.ts +6 -0
  154. package/dist/testing/fake-fetch.js +2 -0
  155. package/dist/testing/fake-fetch.js.map +1 -1
  156. package/dist/testing/fake-plugin.d.ts +2 -0
  157. package/dist/testing/fake-plugin.js +2 -0
  158. package/dist/testing/fake-plugin.js.map +1 -1
  159. package/dist/testing/faulty-store.d.ts +2 -0
  160. package/dist/testing/faulty-store.js +1 -0
  161. package/dist/testing/faulty-store.js.map +1 -1
  162. package/package.json +5 -5
@@ -1 +1 @@
1
- {"version":3,"file":"proofs.js","sourceRoot":"","sources":["../../../src/adapters/tron/proofs.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Proofs, the block source and TronGrid history.\n *\n * Proofs: every read is a `proof` quorum\n * read, and each fact is attested at its own height, so no endpoint proposes a height:\n * - \"my solidified block's timestamp is at or past the expiration\" is a monotone predicate\n * quorum key on the latest solidified block; honest endpoints disagree only in the moment\n * it becomes true on one of them, which decides nothing;\n * - a block at a fixed height is read from the solidity node, which serves it only once it\n * is solidified there, keyed on its consensus facts;\n * - `finalizedHead` is the one unanchored read: one endpoint's view, trailed by\n * `PEER_SKEW` blocks, then attested at that height.\n * A stale or lagging answer is a retryable `PROVIDER_INCONSISTENT` or `PROVIDER_UNAVAILABLE`\n * and decides nothing.\n *\n * Which blocks can hold a transaction (java-tron GreatVoyage-v4.8.2.2 `d5c3d1d1`:\n * `Manager.processBlock` runs `processTransaction`, so `validateTapos` and `validateCommon`,\n * for each transaction, and only then records the block in the recent-block store and as\n * the head):\n * - expiry: a transaction is invalid in a block whose parent's timestamp is at or past\n * its expiration, and block timestamps strictly increase, so no block after the first one\n * at or past the expiration can hold it;\n * - TaPoS: only a block above the reference block, and at most `TAPOS_WINDOW` above it, can\n * hold it.\n *\n * \"Not included\": the solidity index (and TronGrid behind a load balancer) can lag, so an\n * empty index answer is never taken as absence: an expired verdict for a transfer the\n * index missed would let `rebuild` pay twice.\n * `includedFinal` answers `included: false` only once expiry is attested and a scan of every\n * block that could hold the transaction shows it absent, from the attested first block at or\n * past the SIGNED expiration (`expiresAtMs`, which `assemble` binds to the signed bytes) down\n * to just above the reference block. The floor is never a time derived from the expiration:\n * the build-time head and the local clock are claims, so the expiration can sit any distance\n * after the reference.\n * - The ordering (`TronExpiryOrdering`) carries the reference height the build-time head\n * claimed (`lastValidHeight − TAPOS_WINDOW`) and the signed `ref_block_hash`. Only the\n * height's low 16 bits are signed (`ref_block_bytes`), so the height is trusted only when\n * the attested solidified block there carries the signed hash: then the scan runs from the\n * top down to it.\n * - Otherwise (another block there, or a height at or above the top) the proof searches the\n * heights TaPoS can match: every block up to the top checks the reference against the latest\n * block at or below its parent with the signed low 16 bits, and its parent is at most 24 h\n * before the expiration (`MAXIMUM_TIME_UNTIL_EXPIRATION`). So the attested blocks at those\n * heights, from one TaPoS window below that 24 h mark up to the top, are the only possible\n * references. None carries the signed hash: no block can hold the transaction. One does:\n * the blocks in its TaPoS window (and not before the 24 h mark) are scanned.\n * - Either way, a block whose parent is more than 24 h before the expiration cannot hold the\n * transaction, so no scan goes below the first block at or past that mark.\n * - A missing or malformed stored hash decides nothing.\n * Each scanned block is read by hash under the quorum, its parent hash names the next, and the\n * walk must end on the attested block below the window. A scanned block that holds the\n * transaction while the index says nothing decides nothing.\n *\n * Read cost, each read a quorum read: the reference check is one; a scan is one per block in\n * the window (about 20 for a 60 s expiration). A reference older than a day (a build head that\n * named an old block), or the search below, adds a gallop and binary search for the block 24 h\n * before the expiration (a few reads, logarithmic in missed slots). The search, only when the\n * stored height is not the reference, adds one read per candidate height (two or three). A\n * scan never covers more than the blocks from that 24 h mark to the first block at or past the\n * expiration: at most a day of blocks (28,800 at one per 3-second slot, fewer when slots are\n * missed), and never more than one TaPoS window (65,536).\n */\nimport type {\n AddressHistorySource,\n BlockSource,\n DriverTransaction,\n ProofSource,\n} from '../../core/driver/types';\nimport { ConfigError, ProviderError } from '../../core/errors/error';\nimport type { OrderingData } from '../../core/model/ordering';\nimport type { Transport } from '../../core/transport/types';\nimport { toBase58Address } from './address';\nimport { decodeTransaction, verdictOf } from './decode';\nimport {\n MONITOR,\n PROOF,\n READ,\n historyPage,\n notServable,\n type RpcBlock,\n type TronBlockHeader,\n} from './http';\nimport { TAPOS_WINDOW } from './network';\nimport type { TronContext } from './reader';\nimport type { TronExpiryOrdering } from './types';\n\nfunction undecided(): ProviderError {\n return new ProviderError(\n 'PROVIDER_UNAVAILABLE',\n 'finalized state cannot decide this yet',\n );\n}\n\n/** Attested answers that the chain's own rules make impossible together: decides nothing. */\nfunction contradiction(what: string): ProviderError {\n return new ProviderError('PROVIDER_INCONSISTENT', `${what}, which decides nothing`, {\n retryable: true,\n });\n}\n\nconst SLOT_MS = 3_000;\n/**\n * How far `finalizedHead` trails one endpoint's solidified head: up to 6 s behind, and no\n * verdict reads it.\n */\nconst PEER_SKEW = 2n;\n/** java-tron's block heights are `long`s. */\nconst INT64_MAX = 2n ** 63n - 1n;\nconst TX_ID = /^[0-9a-f]{64}$/;\n/** A signed `ref_block_hash`: 8 bytes, lower-case hex, as the builder stores it. */\nconst REF_HASH = /^[0-9a-f]{16}$/;\n/**\n * java-tron's `MAXIMUM_TIME_UNTIL_EXPIRATION` (`Constant.java`): `validateCommon` refuses an\n * expiration more than 24 h after the parent block's time.\n */\nconst MAX_LIFETIME_MS = 86_400_000;\n\n/** The timestamp of a solidified-block answer, or -1 when it is not one (never agrees). */\nfunction solidTimestamp(answer: unknown): number {\n const raw = (answer as { block_header?: { raw_data?: { timestamp?: unknown } } } | null)\n ?.block_header?.raw_data;\n return typeof raw?.timestamp === 'number' ? raw.timestamp : -1;\n}\n\ninterface Bounds {\n /** The signed expiration. */\n readonly expiration: number;\n /** The reference height the build-time head claimed: only its low 16 bits are signed. */\n readonly reference: bigint;\n /** The signed `ref_block_hash`. */\n readonly refBlockHash: string;\n}\n\n/**\n * Where an Attempt can be, from its `TronExpiryOrdering`; null when a field is missing or\n * out of range, which decides nothing.\n */\nfunction attemptBounds(ordering: OrderingData): Bounds | null {\n if (ordering.kind !== 'expiry') return null;\n const { expiresAtMs, lastValidHeight, refBlockHash } =\n ordering as Partial<TronExpiryOrdering>;\n if (\n !Number.isSafeInteger(expiresAtMs) ||\n typeof lastValidHeight !== 'bigint' ||\n lastValidHeight < TAPOS_WINDOW ||\n lastValidHeight > INT64_MAX ||\n typeof refBlockHash !== 'string' ||\n !REF_HASH.test(refBlockHash)\n ) {\n return null;\n }\n return {\n expiration: expiresAtMs as number,\n reference: lastValidHeight - TAPOS_WINDOW,\n refBlockHash,\n };\n}\n\n/** Bytes 8..16 of a block id: what a transaction's `ref_block_hash` names. */\nconst hashBytes = (block: TronBlockHeader): string => block.id.slice(16, 32);\n\n/** Scanned blocks kept per driver: immutable chain data, so a retry is cheap. */\nconst SCAN_CACHE_SIZE = 1_024;\n\nexport function createTronProofs(ctx: TronContext): ProofSource {\n const { api } = ctx;\n // Only quorum-agreed blocks below an attested solidified block, keyed by hash: final.\n const scanned = new Map<string, RpcBlock>();\n\n /** The block `hash`, expected at `height`; cached only once its height checks out. */\n async function finalBlockByHash(\n hash: string,\n height: bigint,\n ): Promise<RpcBlock | null> {\n const cached = scanned.get(hash);\n if (cached) return cached;\n const block = await api.rpcBlock(hash, PROOF);\n if (block && block.number === height) {\n if (scanned.size >= SCAN_CACHE_SIZE) {\n scanned.delete(scanned.keys().next().value as string);\n }\n scanned.set(hash, block);\n }\n return block;\n }\n\n /** A block at a fixed height, attested as solidified on every quorum endpoint. */\n async function solidHeader(height: bigint): Promise<TronBlockHeader> {\n const header = await api.block('solid', height, PROOF);\n if (!header) throw undecided();\n return header;\n }\n\n /**\n * The latest solidified block when every quorum endpoint's solidified block is at or past\n * `expiration` (a monotone predicate), else null.\n */\n async function passedExpiry(expiration: number): Promise<TronBlockHeader | null> {\n const head = (await api.block('solid', undefined, {\n ...PROOF,\n quorumKey: (answer) => solidTimestamp(answer) >= expiration,\n })) as TronBlockHeader;\n return head.timestamp >= expiration ? head : null;\n }\n\n /**\n * The first solidified block at or past `time`, at or below `hi` (an attested block at or\n * past it). Block timestamps strictly increase, so \"at or past `time`\" is monotone in the\n * height: a gallop down from the slot estimate, then a binary search. Every probe is\n * an attested fixed-height read at or below `hi`, which every quorum endpoint has\n * solidified, so none can stall; the slot spacing only picks the first probe.\n */\n async function firstAtOrAfter(\n time: number,\n hi: TronBlockHeader,\n ): Promise<TronBlockHeader> {\n let high = hi;\n let low: TronBlockHeader | undefined;\n let step = BigInt(Math.max(1, Math.floor((hi.timestamp - time) / SLOT_MS)));\n while (low === undefined) {\n if (high.number === 0n) return high;\n const probe = await solidHeader(high.number > step ? high.number - step : 0n);\n if (probe.timestamp < time) {\n low = probe;\n } else {\n high = probe;\n step *= 2n;\n }\n }\n while (high.number - low.number > 1n) {\n const mid = await solidHeader((low.number + high.number) / 2n);\n if (mid.timestamp < time) low = mid;\n else high = mid;\n }\n return high;\n }\n\n /**\n * The first solidified block at or past `expiration`, or null while the quorum has not\n * solidified past it. Only the predicate is attested: the latest block's height and time\n * are one endpoint's word, so a block trailed by the peer skew is attested at its own height\n * (a freshest endpoint then stalls nothing), and the search runs at or below it\n * or, within the skew, up to the first block at the expiration, which every endpoint has\n * solidified (bounded, whatever the endpoint claimed).\n */\n async function expiryBlock(expiration: number): Promise<TronBlockHeader | null> {\n const seen = await passedExpiry(expiration);\n if (!seen) return null;\n let top = await solidHeader(seen.number > PEER_SKEW ? seen.number - PEER_SKEW : 0n);\n if (top.timestamp >= expiration) return firstAtOrAfter(expiration, top);\n while (top.timestamp < expiration) {\n if (top.number >= seen.number) throw undecided();\n top = await solidHeader(top.number + 1n);\n }\n return top;\n }\n\n /**\n * No block above the attested `floor`, at or below `last` and `top`, holds `id`: walked by\n * parent hash from the upper end, which must arrive at `floor`. Throws when anything cannot\n * be decided. Every height read is below `top`, which every quorum endpoint has solidified.\n */\n async function absentAbove(\n id: string,\n floor: TronBlockHeader,\n top: TronBlockHeader,\n last: bigint,\n ): Promise<void> {\n const end = last < top.number ? last : top.number;\n if (end <= floor.number) return;\n const start = end === top.number ? top : await solidHeader(end);\n let hash = start.id;\n for (let height = start.number; height > floor.number; height -= 1n) {\n const block = await finalBlockByHash(hash, height);\n // Missing, or not the block the parent chain leads to: an endpoint is behind or lying.\n if (!block || block.number !== height) throw undecided();\n // In a solidified block, yet the index said nothing: it lags. Decide later.\n if (block.transactions.includes(id)) throw undecided();\n hash = block.parentHash;\n }\n // The walk is bound at both ends: it must arrive at the attested block below the window.\n if (hash !== floor.id) {\n throw contradiction('the scanned blocks do not lead to the reference block');\n }\n }\n\n /**\n * Absence proven by scan; throws when anything cannot be decided. `top`\n * is the attested first block at or past the expiration: no block above it can hold `id`.\n */\n async function absent(id: string, bounds: Bounds, top: TronBlockHeader): Promise<void> {\n const { reference, refBlockHash } = bounds;\n /** The 24 h mark: only a block whose parent is at or after it can hold `id`. */\n const dayMark = bounds.expiration - MAX_LIFETIME_MS;\n // The stored height is the build-time head's claim: it bounds the scan only when the\n // attested block there carries the signed hash bytes.\n if (reference < top.number) {\n const named = await solidHeader(reference);\n if (hashBytes(named) === refBlockHash) {\n // A reference older than a day (a build head that named an old block) is\n // scanned only from the 24 h mark, as the search below does, never its whole window.\n const floor =\n named.timestamp < dayMark ? await firstAtOrAfter(dayMark, top) : named;\n await absentAbove(id, floor, top, reference + TAPOS_WINDOW);\n return;\n }\n }\n // Otherwise, the heights TaPoS can match: the signed low 16 bits, below the top, from one\n // TaPoS window below the first block within 24 h of the expiration (a block's parent is at\n // or after it). Every block up to the top checks the reference against one of them.\n const earliest = await firstAtOrAfter(dayMark, top);\n const low16 = reference % TAPOS_WINDOW;\n const from =\n earliest.number + 1n > TAPOS_WINDOW ? earliest.number + 1n - TAPOS_WINDOW : 0n;\n let height = from + ((low16 - (from % TAPOS_WINDOW) + TAPOS_WINDOW) % TAPOS_WINDOW);\n for (; height < top.number; height += TAPOS_WINDOW) {\n const candidate = await solidHeader(height);\n if (hashBytes(candidate) !== refBlockHash) continue;\n // Its TaPoS window, less the blocks whose parent is more than 24 h before the expiration.\n const floor = candidate.number >= earliest.number ? candidate : earliest;\n await absentAbove(id, floor, top, candidate.number + TAPOS_WINDOW);\n }\n }\n\n return {\n async finalizedHead() {\n // The unanchored exception: one endpoint's view, trailed by the peer skew, attested.\n const seen = (await api.block('solid', undefined, MONITOR)) as TronBlockHeader;\n const head = await solidHeader(\n seen.number > PEER_SKEW ? seen.number - PEER_SKEW : 0n,\n );\n return { height: head.number, hash: head.id, timestamp: head.timestamp };\n },\n\n async includedFinal(ref, ordering) {\n // Bounded before any work; our own Attempt's ref is always a txID.\n if (typeof ref.id !== 'string' || ref.id.length !== 64) throw undecided();\n const id = ref.id.toLowerCase();\n if (!TX_ID.test(id)) throw undecided();\n const info = await api.transactionInfo('solid', id, PROOF);\n if (info) {\n const [header, tx] = await Promise.all([\n api.block('solid', info.blockNumber, PROOF),\n api.transaction('solid', id, PROOF),\n ]);\n if (!header || !tx) throw undecided();\n // java-tron writes the block's time into each receipt (`blockTimeStamp`): a receipt\n // dated otherwise is not from the solidified block at its height.\n if (info.blockTimestamp !== header.timestamp) {\n throw contradiction('a receipt does not match its solidified block');\n }\n // `verdictOf` pairs the receipt with the transaction by id, reads the verdict\n // fields strictly and wants evidence that value moved; a contradiction decides\n // nothing.\n const verdict = verdictOf(ctx.codec, tx, info);\n return {\n included: true,\n success: verdict.success,\n blockHeight: info.blockNumber,\n blockHash: header.id,\n txHash: id,\n ...(verdict.reason !== undefined ? { reason: verdict.reason } : {}),\n ...(verdict.failure !== undefined ? { failure: verdict.failure } : {}),\n };\n }\n const bounds = attemptBounds(ordering);\n if (!bounds) throw undecided();\n const top = await expiryBlock(bounds.expiration);\n if (!top) throw undecided();\n await absent(id, bounds, top);\n return { included: false };\n },\n\n async slotConsumed() {\n // Tron has no nonce or sequence: expiry is the only way an Attempt dies.\n return false;\n },\n\n async expired(ordering: OrderingData) {\n if (ordering.kind !== 'expiry' || !Number.isSafeInteger(ordering.expiresAtMs)) {\n return false;\n }\n return (await expiryBlock(ordering.expiresAtMs as number)) !== null;\n },\n\n async blockHash(height, level) {\n if (height < 0n || height > INT64_MAX) return null;\n const header = await api.block(\n level === 'finalized' ? 'solid' : 'full',\n height,\n PROOF,\n );\n return header?.id ?? null;\n },\n };\n}\n\nexport function createTronBlocks(ctx: TronContext): BlockSource {\n return {\n async header(height) {\n const header = await ctx.api.block('full', height, MONITOR);\n return header\n ? {\n height: header.number,\n hash: header.id,\n parentHash: header.parentId,\n timestamp: header.timestamp,\n }\n : null;\n },\n async transactions(block, filter) {\n // Genesis holds only the chain's initial allocations, which are not reported,\n // and java-tron answers `{}` for its receipts, which a scanner would retry for ever.\n if (block.height === 0n) return [];\n const read = await ctx.api.blockWithTransactions(block.height, MONITOR);\n if (!read || read.header.id !== block.hash) {\n throw new ProviderError(\n 'PROVIDER_INCONSISTENT',\n `block ${block.height} changed while scanning`,\n { retryable: true },\n );\n }\n // Receipts pair with transactions by id, never by position.\n const infos = new Map(read.infos.map((info) => [info.id, info]));\n const txs = read.transactions.map((tx) => {\n const info = infos.get(tx.id);\n if (!info) {\n throw new ProviderError(\n 'PROVIDER_UNAVAILABLE',\n 'a scanned block lacks a receipt',\n );\n }\n return decodeTransaction(ctx.codec, tx, info, block.hash);\n });\n if (!filter?.addresses?.length) return txs;\n const wanted = new Set(filter.addresses.map((a) => toBase58Address(a)));\n return txs.filter(\n (tx) =>\n wanted.has(String(tx.details.owner)) ||\n tx.transfers.some((t) => wanted.has(t.to) || t.from.some((f) => wanted.has(f))),\n );\n },\n };\n}\n\nconst CURSOR = /^([tx]):(.*)$/;\n/** The largest page TronGrid serves. */\nconst MAX_PAGE = 200;\n\n/**\n * TronGrid history, each entry re-read from the full node and decoded like any\n * transaction; confirmed (solidified) entries only (`historyPage`). Phase `t` is\n * `/transactions`: the account's own transactions, TRX sent to it and, for a contract\n * account, other accounts' calls to it. Phase `x` is `/transactions/trc20`: every TRC-20\n * transfer from or to it (a spender's `transferFrom` out of it included), less the account's\n * own calls, which phase `t` listed. A TRC-20 transfer a wallet only received is in phase `x`\n * alone (TronGrid, read-only on Nile, 2026-09-28), but a call to a contract account that moves\n * its own tokens comes in both phases, so callers dedupe on `transfer.id`.\n * Paging follows the raw page's fingerprint, never how many items survive the filter, and\n * an entry the node cannot serve yet decides nothing: dropping it would skip it for good.\n */\nexport function createTronHistory(\n ctx: TronContext,\n indexer: Transport,\n getTransaction: (id: string) => Promise<DriverTransaction | null>,\n): AddressHistorySource {\n return {\n async list(address, options) {\n const match = CURSOR.exec(options.cursor ?? 't:');\n if (!match) throw new ConfigError('CONFIG_INVALID', 'not a Tron history cursor');\n const phase = match[1] as 't' | 'x';\n const fingerprint = match[2] as string;\n const owner = toBase58Address(address);\n const page = await historyPage(\n indexer,\n owner,\n phase === 't' ? 'transactions' : 'trc20',\n {\n limit: Math.min(Math.max(Math.trunc(options.limit) || 1, 1), MAX_PAGE),\n ...(fingerprint ? { fingerprint } : {}),\n },\n READ,\n );\n const items: DriverTransaction[] = [];\n for (const id of page.ids) {\n const tx = await getTransaction(id);\n // The index lists it as confirmed: a node that serves nothing, or only its pool\n // copy, is behind; listing that copy would move the cursor past it for good.\n if (!tx || tx.observation.seen !== 'block') throw notServable();\n // Phase x skips the account's own calls: phase t listed them.\n if (!(phase === 'x' && tx.details.owner === owner)) items.push(tx);\n }\n const next = page.next ? `${phase}:${page.next}` : phase === 't' ? 'x:' : undefined;\n return { items, ...(next !== undefined ? { next } : {}) };\n },\n };\n}\n"]}
1
+ {"version":3,"file":"proofs.js","sourceRoot":"","sources":["../../../src/adapters/tron/proofs.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Proofs, the block source and TronGrid history.\n *\n * Proofs: every read is a `proof` quorum\n * read, and each fact is attested at its own height, so no endpoint proposes a height:\n * - \"my solidified block's timestamp is at or past the expiration\" is a monotone predicate\n * quorum key on the latest solidified block; honest endpoints disagree only in the moment\n * it becomes true on one of them, which decides nothing;\n * - a block at a fixed height is read from the solidity node, which serves it only once it\n * is solidified there, keyed on its consensus facts;\n * - `finalizedHead` is the one unanchored read: one endpoint's view, trailed by\n * `PEER_SKEW` blocks, then attested at that height.\n * A stale or lagging answer is a retryable `PROVIDER_INCONSISTENT` or `PROVIDER_UNAVAILABLE`\n * and decides nothing.\n *\n * Which blocks can hold a transaction (java-tron GreatVoyage-v4.8.2.2 `d5c3d1d1`:\n * `Manager.processBlock` runs `processTransaction`, so `validateTapos` and `validateCommon`,\n * for each transaction, and only then records the block in the recent-block store and as\n * the head):\n * - expiry: a transaction is invalid in a block whose parent's timestamp is at or past\n * its expiration, and block timestamps strictly increase, so no block after the first one\n * at or past the expiration can hold it;\n * - TaPoS: only a block above the reference block, and at most `TAPOS_WINDOW` above it, can\n * hold it.\n *\n * \"Not included\": the solidity index (and TronGrid behind a load balancer) can lag, so an\n * empty index answer is never taken as absence: an expired verdict for a transfer the\n * index missed would let `rebuild` pay twice.\n * `includedFinal` answers `included: false` only once expiry is attested and a scan of every\n * block that could hold the transaction shows it absent, from the attested first block at or\n * past the SIGNED expiration (`expiresAtMs`, which `assemble` binds to the signed bytes) down\n * to just above the reference block. The floor is never a time derived from the expiration:\n * the build-time head and the local clock are claims, so the expiration can sit any distance\n * after the reference.\n * - The ordering (`TronExpiryOrdering`) carries the reference height the build-time head\n * claimed (`lastValidHeight − TAPOS_WINDOW`) and the signed `ref_block_hash`. Only the\n * height's low 16 bits are signed (`ref_block_bytes`), so the height is trusted only when\n * the attested solidified block there carries the signed hash: then the scan runs from the\n * top down to it.\n * - Otherwise (another block there, or a height at or above the top) the proof searches the\n * heights TaPoS can match: every block up to the top checks the reference against the latest\n * block at or below its parent with the signed low 16 bits, and its parent is at most 24 h\n * before the expiration (`MAXIMUM_TIME_UNTIL_EXPIRATION`). So the attested blocks at those\n * heights, from one TaPoS window below that 24 h mark up to the top, are the only possible\n * references. None carries the signed hash: no block can hold the transaction. One does:\n * the blocks in its TaPoS window (and not before the 24 h mark) are scanned.\n * - Either way, a block whose parent is more than 24 h before the expiration cannot hold the\n * transaction, so no scan goes below the first block at or past that mark.\n * - A missing or malformed stored hash decides nothing.\n * Each scanned block is read by hash under the quorum, its parent hash names the next, and the\n * walk must end on the attested block below the window. A scanned block that holds the\n * transaction while the index says nothing decides nothing.\n *\n * Read cost, each read a quorum read: the reference check is one; a scan is one per block in\n * the window (about 20 for a 60 s expiration). A reference older than a day (a build head that\n * named an old block), or the search below, adds a gallop and binary search for the block 24 h\n * before the expiration (a few reads, logarithmic in missed slots). The search, only when the\n * stored height is not the reference, adds one read per candidate height (two or three). A\n * scan never covers more than the blocks from that 24 h mark to the first block at or past the\n * expiration: at most a day of blocks (28,800 at one per 3-second slot, fewer when slots are\n * missed), and never more than one TaPoS window (65,536).\n */\nimport type {\n AddressHistorySource,\n BlockSource,\n DriverTransaction,\n ProofSource,\n} from '../../core/driver/types';\nimport { ConfigError, ProviderError } from '../../core/errors/error';\nimport type { OrderingData } from '../../core/model/ordering';\nimport type { Transport } from '../../core/transport/types';\nimport { toBase58Address } from './address';\nimport { decodeTransaction, verdictOf } from './decode';\nimport {\n MONITOR,\n PROOF,\n READ,\n historyPage,\n notServable,\n unixSeconds,\n type RpcBlock,\n type TronBlockHeader,\n} from './http';\nimport { TAPOS_WINDOW } from './network';\nimport type { TronContext } from './reader';\nimport type { TronExpiryOrdering } from './types';\n\nfunction undecided(): ProviderError {\n return new ProviderError(\n 'PROVIDER_UNAVAILABLE',\n 'finalized state cannot decide this yet',\n );\n}\n\n/** Attested answers that the chain's own rules make impossible together: decides nothing. */\nfunction contradiction(what: string): ProviderError {\n return new ProviderError('PROVIDER_INCONSISTENT', `${what}, which decides nothing`, {\n retryable: true,\n });\n}\n\nconst SLOT_MS = 3_000;\n/**\n * How far `finalizedHead` trails one endpoint's solidified head: up to 6 s behind, and no\n * verdict reads it.\n */\nconst PEER_SKEW = 2n;\n/** java-tron's block heights are `long`s. */\nconst INT64_MAX = 2n ** 63n - 1n;\nconst TX_ID = /^[0-9a-f]{64}$/;\n/** A signed `ref_block_hash`: 8 bytes, lower-case hex, as the builder stores it. */\nconst REF_HASH = /^[0-9a-f]{16}$/;\n/**\n * java-tron's `MAXIMUM_TIME_UNTIL_EXPIRATION` (`Constant.java`): `validateCommon` refuses an\n * expiration more than 24 h after the parent block's time.\n */\nconst MAX_LIFETIME_MS = 86_400_000;\n\n/** The timestamp of a solidified-block answer, or -1 when it is not one (never agrees). */\nfunction solidTimestamp(answer: unknown): number {\n const raw = (answer as { block_header?: { raw_data?: { timestamp?: unknown } } } | null)\n ?.block_header?.raw_data;\n return typeof raw?.timestamp === 'number' ? raw.timestamp : -1;\n}\n\ninterface Bounds {\n /** The signed expiration. */\n readonly expiration: number;\n /** The reference height the build-time head claimed: only its low 16 bits are signed. */\n readonly reference: bigint;\n /** The signed `ref_block_hash`. */\n readonly refBlockHash: string;\n}\n\n/**\n * Where an Attempt can be, from its `TronExpiryOrdering`; null when a field is missing or\n * out of range, which decides nothing.\n */\nfunction attemptBounds(ordering: OrderingData): Bounds | null {\n if (ordering.kind !== 'expiry') return null;\n const { expiresAtMs, lastValidHeight, refBlockHash } =\n ordering as Partial<TronExpiryOrdering>;\n if (\n !Number.isSafeInteger(expiresAtMs) ||\n typeof lastValidHeight !== 'bigint' ||\n lastValidHeight < TAPOS_WINDOW ||\n lastValidHeight > INT64_MAX ||\n typeof refBlockHash !== 'string' ||\n !REF_HASH.test(refBlockHash)\n ) {\n return null;\n }\n return {\n expiration: expiresAtMs as number,\n reference: lastValidHeight - TAPOS_WINDOW,\n refBlockHash,\n };\n}\n\n/** Bytes 8..16 of a block id: what a transaction's `ref_block_hash` names. */\nconst hashBytes = (block: TronBlockHeader): string => block.id.slice(16, 32);\n\n/** Scanned blocks kept per driver: immutable chain data, so a retry is cheap. */\nconst SCAN_CACHE_SIZE = 1_024;\n\nexport function createTronProofs(ctx: TronContext): ProofSource {\n const { api } = ctx;\n // Only quorum-agreed blocks below an attested solidified block, keyed by hash: final.\n const scanned = new Map<string, RpcBlock>();\n\n /** The block `hash`, expected at `height`; cached only once its height checks out. */\n async function finalBlockByHash(\n hash: string,\n height: bigint,\n ): Promise<RpcBlock | null> {\n const cached = scanned.get(hash);\n if (cached) return cached;\n const block = await api.rpcBlock(hash, PROOF);\n if (block && block.number === height) {\n if (scanned.size >= SCAN_CACHE_SIZE) {\n scanned.delete(scanned.keys().next().value as string);\n }\n scanned.set(hash, block);\n }\n return block;\n }\n\n /** A block at a fixed height, attested as solidified on every quorum endpoint. */\n async function solidHeader(height: bigint): Promise<TronBlockHeader> {\n const header = await api.block('solid', height, PROOF);\n if (!header) throw undecided();\n return header;\n }\n\n /**\n * The latest solidified block when every quorum endpoint's solidified block is at or past\n * `expiration` (a monotone predicate), else null.\n */\n async function passedExpiry(expiration: number): Promise<TronBlockHeader | null> {\n const head = (await api.block('solid', undefined, {\n ...PROOF,\n quorumKey: (answer) => solidTimestamp(answer) >= expiration,\n })) as TronBlockHeader;\n return head.timestamp >= expiration ? head : null;\n }\n\n /**\n * The first solidified block at or past `time`, at or below `hi` (an attested block at or\n * past it). Block timestamps strictly increase, so \"at or past `time`\" is monotone in the\n * height: a gallop down from the slot estimate, then a binary search. Every probe is\n * an attested fixed-height read at or below `hi`, which every quorum endpoint has\n * solidified, so none can stall; the slot spacing only picks the first probe.\n */\n async function firstAtOrAfter(\n time: number,\n hi: TronBlockHeader,\n ): Promise<TronBlockHeader> {\n let high = hi;\n let low: TronBlockHeader | undefined;\n let step = BigInt(Math.max(1, Math.floor((hi.timestamp - time) / SLOT_MS)));\n while (low === undefined) {\n if (high.number === 0n) return high;\n const probe = await solidHeader(high.number > step ? high.number - step : 0n);\n if (probe.timestamp < time) {\n low = probe;\n } else {\n high = probe;\n step *= 2n;\n }\n }\n while (high.number - low.number > 1n) {\n const mid = await solidHeader((low.number + high.number) / 2n);\n if (mid.timestamp < time) low = mid;\n else high = mid;\n }\n return high;\n }\n\n /**\n * The first solidified block at or past `expiration`, or null while the quorum has not\n * solidified past it. Only the predicate is attested: the latest block's height and time\n * are one endpoint's word, so a block trailed by the peer skew is attested at its own height\n * (a freshest endpoint then stalls nothing), and the search runs at or below it\n * or, within the skew, up to the first block at the expiration, which every endpoint has\n * solidified (bounded, whatever the endpoint claimed).\n */\n async function expiryBlock(expiration: number): Promise<TronBlockHeader | null> {\n const seen = await passedExpiry(expiration);\n if (!seen) return null;\n let top = await solidHeader(seen.number > PEER_SKEW ? seen.number - PEER_SKEW : 0n);\n if (top.timestamp >= expiration) return firstAtOrAfter(expiration, top);\n while (top.timestamp < expiration) {\n if (top.number >= seen.number) throw undecided();\n top = await solidHeader(top.number + 1n);\n }\n return top;\n }\n\n /**\n * No block above the attested `floor`, at or below `last` and `top`, holds `id`: walked by\n * parent hash from the upper end, which must arrive at `floor`. Throws when anything cannot\n * be decided. Every height read is below `top`, which every quorum endpoint has solidified.\n */\n async function absentAbove(\n id: string,\n floor: TronBlockHeader,\n top: TronBlockHeader,\n last: bigint,\n ): Promise<void> {\n const end = last < top.number ? last : top.number;\n if (end <= floor.number) return;\n const start = end === top.number ? top : await solidHeader(end);\n let hash = start.id;\n for (let height = start.number; height > floor.number; height -= 1n) {\n const block = await finalBlockByHash(hash, height);\n // Missing, or not the block the parent chain leads to: an endpoint is behind or lying.\n if (!block || block.number !== height) throw undecided();\n // In a solidified block, yet the index said nothing: it lags. Decide later.\n if (block.transactions.includes(id)) throw undecided();\n hash = block.parentHash;\n }\n // The walk is bound at both ends: it must arrive at the attested block below the window.\n if (hash !== floor.id) {\n throw contradiction('the scanned blocks do not lead to the reference block');\n }\n }\n\n /**\n * Absence proven by scan; throws when anything cannot be decided. `top`\n * is the attested first block at or past the expiration: no block above it can hold `id`.\n */\n async function absent(id: string, bounds: Bounds, top: TronBlockHeader): Promise<void> {\n const { reference, refBlockHash } = bounds;\n /** The 24 h mark: only a block whose parent is at or after it can hold `id`. */\n const dayMark = bounds.expiration - MAX_LIFETIME_MS;\n // The stored height is the build-time head's claim: it bounds the scan only when the\n // attested block there carries the signed hash bytes.\n if (reference < top.number) {\n const named = await solidHeader(reference);\n if (hashBytes(named) === refBlockHash) {\n // A reference older than a day (a build head that named an old block) is\n // scanned only from the 24 h mark, as the search below does, never its whole window.\n const floor =\n named.timestamp < dayMark ? await firstAtOrAfter(dayMark, top) : named;\n await absentAbove(id, floor, top, reference + TAPOS_WINDOW);\n return;\n }\n }\n // Otherwise, the heights TaPoS can match: the signed low 16 bits, below the top, from one\n // TaPoS window below the first block within 24 h of the expiration (a block's parent is at\n // or after it). Every block up to the top checks the reference against one of them.\n const earliest = await firstAtOrAfter(dayMark, top);\n const low16 = reference % TAPOS_WINDOW;\n const from =\n earliest.number + 1n > TAPOS_WINDOW ? earliest.number + 1n - TAPOS_WINDOW : 0n;\n let height = from + ((low16 - (from % TAPOS_WINDOW) + TAPOS_WINDOW) % TAPOS_WINDOW);\n for (; height < top.number; height += TAPOS_WINDOW) {\n const candidate = await solidHeader(height);\n if (hashBytes(candidate) !== refBlockHash) continue;\n // Its TaPoS window, less the blocks whose parent is more than 24 h before the expiration.\n const floor = candidate.number >= earliest.number ? candidate : earliest;\n await absentAbove(id, floor, top, candidate.number + TAPOS_WINDOW);\n }\n }\n\n return {\n async finalizedHead() {\n // The unanchored exception: one endpoint's view, trailed by the peer skew, attested.\n const seen = (await api.block('solid', undefined, MONITOR)) as TronBlockHeader;\n const head = await solidHeader(\n seen.number > PEER_SKEW ? seen.number - PEER_SKEW : 0n,\n );\n return {\n height: head.number,\n hash: head.id,\n timestamp: unixSeconds(head.timestamp),\n };\n },\n\n async includedFinal(ref, ordering) {\n // Bounded before any work; our own Attempt's ref is always a txID.\n if (typeof ref.id !== 'string' || ref.id.length !== 64) throw undecided();\n const id = ref.id.toLowerCase();\n if (!TX_ID.test(id)) throw undecided();\n const info = await api.transactionInfo('solid', id, PROOF);\n if (info) {\n const [header, tx] = await Promise.all([\n api.block('solid', info.blockNumber, PROOF),\n api.transaction('solid', id, PROOF),\n ]);\n if (!header || !tx) throw undecided();\n // java-tron writes the block's time into each receipt (`blockTimeStamp`): a receipt\n // dated otherwise is not from the solidified block at its height.\n if (info.blockTimestamp !== header.timestamp) {\n throw contradiction('a receipt does not match its solidified block');\n }\n // `verdictOf` pairs the receipt with the transaction by id, reads the verdict\n // fields strictly and wants evidence that value moved; a contradiction decides\n // nothing.\n const verdict = verdictOf(ctx.codec, tx, info);\n return {\n included: true,\n success: verdict.success,\n blockHeight: info.blockNumber,\n blockHash: header.id,\n txHash: id,\n ...(verdict.reason !== undefined ? { reason: verdict.reason } : {}),\n ...(verdict.failure !== undefined ? { failure: verdict.failure } : {}),\n };\n }\n const bounds = attemptBounds(ordering);\n if (!bounds) throw undecided();\n const top = await expiryBlock(bounds.expiration);\n if (!top) throw undecided();\n await absent(id, bounds, top);\n return { included: false };\n },\n\n async slotConsumed() {\n // Tron has no nonce or sequence: expiry is the only way an Attempt dies.\n return false;\n },\n\n async expired(ordering: OrderingData) {\n if (ordering.kind !== 'expiry' || !Number.isSafeInteger(ordering.expiresAtMs)) {\n return false;\n }\n return (await expiryBlock(ordering.expiresAtMs as number)) !== null;\n },\n\n async blockHash(height, level) {\n if (height < 0n || height > INT64_MAX) return null;\n const header = await api.block(\n level === 'finalized' ? 'solid' : 'full',\n height,\n PROOF,\n );\n return header?.id ?? null;\n },\n };\n}\n\nexport function createTronBlocks(ctx: TronContext): BlockSource {\n return {\n async header(height) {\n const header = await ctx.api.block('full', height, MONITOR);\n return header\n ? {\n height: header.number,\n hash: header.id,\n parentHash: header.parentId,\n timestamp: unixSeconds(header.timestamp),\n }\n : null;\n },\n async transactions(block, filter) {\n // Genesis holds only the chain's initial allocations, which are not reported,\n // and java-tron answers `{}` for its receipts, which a scanner would retry for ever.\n if (block.height === 0n) return [];\n const read = await ctx.api.blockWithTransactions(block.height, MONITOR);\n if (!read || read.header.id !== block.hash) {\n throw new ProviderError(\n 'PROVIDER_INCONSISTENT',\n `block ${block.height} changed while scanning`,\n { retryable: true },\n );\n }\n // Receipts pair with transactions by id, never by position.\n const infos = new Map(read.infos.map((info) => [info.id, info]));\n const txs = read.transactions.map((tx) => {\n const info = infos.get(tx.id);\n if (!info) {\n throw new ProviderError(\n 'PROVIDER_UNAVAILABLE',\n 'a scanned block lacks a receipt',\n );\n }\n return decodeTransaction(ctx.codec, tx, info, block.hash);\n });\n if (!filter?.addresses?.length) return txs;\n const wanted = new Set(filter.addresses.map((a) => toBase58Address(a)));\n return txs.filter(\n (tx) =>\n wanted.has(String(tx.details.owner)) ||\n tx.transfers.some((t) => wanted.has(t.to) || t.from.some((f) => wanted.has(f))),\n );\n },\n };\n}\n\nconst CURSOR = /^([tx]):(.*)$/;\n/** The largest page TronGrid serves. */\nconst MAX_PAGE = 200;\n\n/**\n * TronGrid history, each entry re-read from the full node and decoded like any\n * transaction; confirmed (solidified) entries only (`historyPage`). Phase `t` is\n * `/transactions`: the account's own transactions, TRX sent to it and, for a contract\n * account, other accounts' calls to it. Phase `x` is `/transactions/trc20`: every TRC-20\n * transfer from or to it (a spender's `transferFrom` out of it included), less the account's\n * own calls, which phase `t` listed. A TRC-20 transfer a wallet only received is in phase `x`\n * alone (TronGrid, read-only on Nile, 2026-09-28), but a call to a contract account that moves\n * its own tokens comes in both phases, so callers dedupe on `transfer.id`.\n * Paging follows the raw page's fingerprint, never how many items survive the filter, and\n * an entry the node cannot serve yet decides nothing: dropping it would skip it for good.\n */\nexport function createTronHistory(\n ctx: TronContext,\n indexer: Transport,\n getTransaction: (id: string) => Promise<DriverTransaction | null>,\n): AddressHistorySource {\n return {\n async list(address, options) {\n const match = CURSOR.exec(options.cursor ?? 't:');\n if (!match) throw new ConfigError('CONFIG_INVALID', 'not a Tron history cursor');\n const phase = match[1] as 't' | 'x';\n const fingerprint = match[2] as string;\n const owner = toBase58Address(address);\n const page = await historyPage(\n indexer,\n owner,\n phase === 't' ? 'transactions' : 'trc20',\n {\n limit: Math.min(Math.max(Math.trunc(options.limit) || 1, 1), MAX_PAGE),\n ...(fingerprint ? { fingerprint } : {}),\n },\n READ,\n );\n const items: DriverTransaction[] = [];\n for (const id of page.ids) {\n const tx = await getTransaction(id);\n // The index lists it as confirmed: a node that serves nothing, or only its pool\n // copy, is behind; listing that copy would move the cursor past it for good.\n if (!tx || tx.observation.seen !== 'block') throw notServable();\n // Phase x skips the account's own calls: phase t listed them.\n if (!(phase === 'x' && tx.details.owner === owner)) items.push(tx);\n }\n const next = page.next ? `${phase}:${page.next}` : phase === 't' ? 'x:' : undefined;\n return { items, ...(next !== undefined ? { next } : {}) };\n },\n };\n}\n"]}
@@ -166,7 +166,7 @@ function createTronReader(ctx) {
166
166
  height: header.number,
167
167
  hash: header.id,
168
168
  parentHash: header.parentId,
169
- timestamp: header.timestamp,
169
+ timestamp: (0, http_1.unixSeconds)(header.timestamp),
170
170
  }
171
171
  : null;
172
172
  },
@@ -1 +1 @@
1
- {"version":3,"file":"reader.js","sourceRoot":"","sources":["../../../src/adapters/tron/reader.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The Tron `ChainReader` and `ext.tron`. Tags follow the `ChainDriver` contract table:\n * reads `read`, heights and `observe` `monitor`. Addresses reach the node as `41…` hex.\n * A transaction the node holds but cannot serve whole yet (its receipt, its block) is a\n * retryable `PROVIDER_UNAVAILABLE`, never \"not seen\".\n */\nimport type {\n ChainReader,\n DriverBlock,\n DriverTransaction,\n DriverTxObservation,\n} from '../../core/driver/types';\nimport {\n ProviderError,\n UnsupportedCapabilityError,\n ValidationError,\n} from '../../core/errors/error';\nimport type { Logger } from '../../core/events/logger';\nimport type { AssetMetadata, AssetRef, TokenRef } from '../../core/model/asset';\nimport type { ChainInfo, NetworkInfo } from '../../core/model/chain';\nimport type { Clock } from '../../core/util/clock';\nimport { SELECTORS, decodeString, decodeUint256, encodeBalanceOf } from './abi';\nimport { isTronAddress, toBase58Address, toHexAddress } from './address';\nimport { chainVerdict, decodeTransaction, verdictOf } from './decode';\nimport { MONITOR, READ, notServable, type TronApi, type TronTxJson } from './http';\nimport type { TronNetworkConfig } from './network';\nimport type { TronCallTags, TronCodec, TronExt, TronResources } from './types';\n\nexport interface TronContext {\n readonly api: TronApi;\n readonly codec: TronCodec;\n readonly chain: ChainInfo;\n readonly network: NetworkInfo;\n readonly config: TronNetworkConfig;\n readonly clock: Clock;\n readonly log: Logger;\n}\n\nconst TX_ID = /^[0-9a-f]{64}$/;\n/** java-tron's block heights are `long`s. */\nconst INT64_MAX = 2n ** 63n - 1n;\n\n/** A lower-case transaction or block id, or `null` (length checked before any work). */\nfunction idOf(value: string): string | null {\n if (typeof value !== 'string' || value.length !== 64) return null;\n const id = value.toLowerCase();\n return TX_ID.test(id) ? id : null;\n}\n\n/**\n * Token metadata is read under the proof quorum: the core caches a token's decimals,\n * symbol and \"no such token\" for the container's life, so one lagging or buggy endpoint\n * must not decide them. The constant call's quorum key compares the verdict only, since\n * honest nodes never agree on its whole answer; endpoints that disagree throw retryable\n * `PROVIDER_INCONSISTENT`.\n */\nconst METADATA: TronCallTags = { ...READ, quorum: 'proof' };\n\nfunction tokenProblem(reason: string): ValidationError {\n return new ValidationError('ASSET_RESOLUTION', `TRC-20 token unusable: ${reason}`);\n}\n\n/**\n * The `41…` hex contract of a TRC-20 ref. `UNSUPPORTED_CAPABILITY` for TRX or another token\n * standard; `ASSET_RESOLUTION` for a contract that is not a Tron address.\n */\nexport function trc20Contract(ref: AssetRef): string {\n if (ref === 'native' || ref.standard !== 'trc20') {\n throw new UnsupportedCapabilityError(\n 'UNSUPPORTED_CAPABILITY',\n 'Tron supports TRX and TRC-20 tokens only',\n );\n }\n if (!isTronAddress(ref.contract)) throw tokenProblem('not a Tron contract address');\n return toHexAddress(ref.contract);\n}\n\n/**\n * A constant call on a token: a revert, a VM failure or no contract is the\n * token's own permanent problem (`ASSET_RESOLUTION`, cached by the core); node refusals stay\n * retryable and every other error propagates unchanged. \"No contract\" is a node's text, so\n * it counts only once `/wallet/getcontract` confirms it structurally with the same tags; a\n * node that shows a contract there decides nothing.\n */\nexport async function tokenCall(\n ctx: TronContext,\n owner: string,\n contract: string,\n data: string,\n tags: TronCallTags,\n): Promise<string> {\n const answer = await ctx.api.constantCall(owner, contract, data, tags);\n if (answer.kind === 'no-contract') {\n if (await ctx.api.contractExists(contract, tags)) {\n throw new ProviderError(\n 'PROVIDER_INCONSISTENT',\n 'the node both holds and lacks this contract',\n { retryable: true },\n );\n }\n throw tokenProblem('no contract at this address');\n }\n if (answer.kind === 'failed') throw tokenProblem('the call failed');\n return answer.result;\n}\n\n/** A holder's TRC-20 balance. */\nexport async function trc20Balance(\n ctx: TronContext,\n contract: string,\n holder: string,\n tags: TronCallTags = READ,\n): Promise<bigint> {\n const result = await tokenCall(\n ctx,\n toHexAddress(holder),\n contract,\n encodeBalanceOf(holder),\n tags,\n );\n try {\n return decodeUint256(result);\n } catch {\n throw tokenProblem('balanceOf returned no uint256');\n }\n}\n\n/** An ABI `bool` that is `true`: one word, exactly 1 (constant results are lower-case). */\nconst TRUE_WORD = /^0{63}1$/;\n\n/**\n * Whether a token answers `deprecated()` with `true`, as Tether's `TetherToken` (USDT on\n * Tron) does once its owner deprecates it for an upgraded contract (`upgradedAddress`).\n * Only a definitive answer decides: a contract without the method (a revert or VM failure,\n * an answer that is not one ABI `bool`, or a node's \"no contract\", which the balance read\n * beside it settles) is not deprecated. A node refusal or a malformed answer throws\n * retryable, so a failed read is never taken for either answer. The contract's own\n * account is the caller: it always exists.\n */\nexport async function trc20Deprecated(\n ctx: TronContext,\n contract: string,\n tags: TronCallTags,\n): Promise<boolean> {\n const answer = await ctx.api.constantCall(\n contract,\n contract,\n SELECTORS.deprecated,\n tags,\n );\n return answer.kind === 'ok' && TRUE_WORD.test(answer.result);\n}\n\n/**\n * An included transaction's observation. `guard` applies the verdict guard (on-chain\n * evidence that value moved) to our own Attempts; without it (a status lookup by id,\n * `ordering === undefined`), the chain's own view is reported.\n */\nexport async function observeIncluded(\n ctx: TronContext,\n id: string,\n tags: TronCallTags,\n guard: boolean,\n): Promise<DriverTxObservation | null> {\n const info = await ctx.api.transactionInfo('full', id, tags);\n if (!info) return null;\n const [tx, header] = await Promise.all([\n ctx.api.transaction('full', id, tags),\n ctx.api.block('full', info.blockNumber, tags),\n ]);\n // The node indexed the info but cannot serve the transaction or its block yet: decide\n // nothing now (the core keeps its current observation on a retryable error).\n if (!tx || !header) throw notServable();\n const verdict = guard\n ? verdictOf(ctx.codec, tx, info)\n : chainVerdict(ctx.codec, tx, info);\n return {\n seen: 'block',\n txHash: id,\n blockHeight: info.blockNumber,\n blockHash: header.id,\n success: verdict.success,\n ...(verdict.reason ? { reason: verdict.reason } : {}),\n ...(verdict.failure ? { failure: verdict.failure } : {}),\n };\n}\n\nexport function createTronReader(ctx: TronContext): ChainReader {\n const { api } = ctx;\n\n async function getTransaction(id: string): Promise<DriverTransaction | null> {\n const txId = idOf(id);\n if (txId === null) return null;\n const tx = await api.transaction('full', txId, READ);\n if (!tx) {\n const pending: TronTxJson | null = await api.pending(txId, READ);\n return pending\n ? decodeTransaction(ctx.codec, pending, null, undefined, true)\n : null;\n }\n // java-tron serves only included transactions here: without its receipt or its block\n // the answer is \"not yet\", never \"not seen\".\n const info = await api.transactionInfo('full', txId, READ);\n if (!info) throw notServable();\n const header = await api.block('full', info.blockNumber, READ);\n if (!header) throw notServable();\n return decodeTransaction(ctx.codec, tx, info, header.id);\n }\n\n return {\n async getBalance(address, asset) {\n if (asset === 'native')\n return (await api.account(toHexAddress(address), READ)).balance;\n return trc20Balance(ctx, trc20Contract(asset), address);\n },\n async getBlockHeight() {\n return ((await api.block('full', undefined, MONITOR)) as { number: bigint }).number;\n },\n async getFinalizedHeight() {\n return ((await api.block('solid', undefined, MONITOR)) as { number: bigint })\n .number;\n },\n async getBlock(ref): Promise<DriverBlock | null> {\n const key = typeof ref === 'string' ? idOf(ref) : ref;\n if (key === null || (typeof key === 'bigint' && (key < 0n || key > INT64_MAX))) {\n return null;\n }\n const header = await api.block('full', key, READ);\n return header\n ? {\n height: header.number,\n hash: header.id,\n parentHash: header.parentId,\n timestamp: header.timestamp,\n }\n : null;\n },\n getTransaction,\n async observe(ref, ordering) {\n const id = idOf(ref.id);\n if (id === null) return { seen: 'none' };\n const included = await observeIncluded(ctx, id, MONITOR, ordering !== undefined);\n if (included) return included;\n return (await api.pending(id, MONITOR)) ? { seen: 'mempool' } : { seen: 'none' };\n },\n async getTokenMetadata(ref: TokenRef): Promise<AssetMetadata> {\n const contract = trc20Contract(ref);\n // The contract's own account is the caller: it always exists.\n const decimalsWord = await tokenCall(\n ctx,\n contract,\n contract,\n SELECTORS.decimals,\n METADATA,\n );\n const symbolWord = await tokenCall(\n ctx,\n contract,\n contract,\n SELECTORS.symbol,\n METADATA,\n );\n let decimals: bigint;\n let symbol: string;\n try {\n decimals = decodeUint256(decimalsWord);\n symbol = decodeString(symbolWord);\n } catch {\n throw tokenProblem('unreadable decimals or symbol');\n }\n if (decimals > 255n || symbol.length === 0) {\n throw tokenProblem('decimals or symbol out of range');\n }\n return { symbol, decimals: Number(decimals) };\n },\n normalizeTokenRef(ref: TokenRef): TokenRef {\n if (ref.standard !== 'trc20') {\n throw new ValidationError(\n 'ASSET_RESOLUTION',\n 'Tron tokens use the trc20 standard',\n );\n }\n if (!isTronAddress(ref.contract)) throw tokenProblem('not a Tron contract address');\n return { standard: 'trc20', contract: toBase58Address(ref.contract) };\n },\n };\n}\n\n/** `ext.tron`, the Tron family extension. */\nexport function createTronExt(ctx: TronContext): TronExt {\n return {\n tron: {\n getResources: (address: string): Promise<TronResources> =>\n ctx.api.resources(toHexAddress(address), READ),\n },\n };\n}\n"]}
1
+ {"version":3,"file":"reader.js","sourceRoot":"","sources":["../../../src/adapters/tron/reader.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The Tron `ChainReader` and `ext.tron`. Tags follow the `ChainDriver` contract table:\n * reads `read`, heights and `observe` `monitor`. Addresses reach the node as `41…` hex.\n * A transaction the node holds but cannot serve whole yet (its receipt, its block) is a\n * retryable `PROVIDER_UNAVAILABLE`, never \"not seen\".\n */\nimport type {\n ChainReader,\n DriverBlock,\n DriverTransaction,\n DriverTxObservation,\n} from '../../core/driver/types';\nimport {\n ProviderError,\n UnsupportedCapabilityError,\n ValidationError,\n} from '../../core/errors/error';\nimport type { Logger } from '../../core/events/logger';\nimport type { AssetMetadata, AssetRef, TokenRef } from '../../core/model/asset';\nimport type { ChainInfo, NetworkInfo } from '../../core/model/chain';\nimport type { Clock } from '../../core/util/clock';\nimport { SELECTORS, decodeString, decodeUint256, encodeBalanceOf } from './abi';\nimport { isTronAddress, toBase58Address, toHexAddress } from './address';\nimport { chainVerdict, decodeTransaction, verdictOf } from './decode';\nimport {\n MONITOR,\n READ,\n notServable,\n unixSeconds,\n type TronApi,\n type TronTxJson,\n} from './http';\nimport type { TronNetworkConfig } from './network';\nimport type { TronCallTags, TronCodec, TronExt, TronResources } from './types';\n\nexport interface TronContext {\n readonly api: TronApi;\n readonly codec: TronCodec;\n readonly chain: ChainInfo;\n readonly network: NetworkInfo;\n readonly config: TronNetworkConfig;\n readonly clock: Clock;\n readonly log: Logger;\n}\n\nconst TX_ID = /^[0-9a-f]{64}$/;\n/** java-tron's block heights are `long`s. */\nconst INT64_MAX = 2n ** 63n - 1n;\n\n/** A lower-case transaction or block id, or `null` (length checked before any work). */\nfunction idOf(value: string): string | null {\n if (typeof value !== 'string' || value.length !== 64) return null;\n const id = value.toLowerCase();\n return TX_ID.test(id) ? id : null;\n}\n\n/**\n * Token metadata is read under the proof quorum: the core caches a token's decimals,\n * symbol and \"no such token\" for the container's life, so one lagging or buggy endpoint\n * must not decide them. The constant call's quorum key compares the verdict only, since\n * honest nodes never agree on its whole answer; endpoints that disagree throw retryable\n * `PROVIDER_INCONSISTENT`.\n */\nconst METADATA: TronCallTags = { ...READ, quorum: 'proof' };\n\nfunction tokenProblem(reason: string): ValidationError {\n return new ValidationError('ASSET_RESOLUTION', `TRC-20 token unusable: ${reason}`);\n}\n\n/**\n * The `41…` hex contract of a TRC-20 ref. `UNSUPPORTED_CAPABILITY` for TRX or another token\n * standard; `ASSET_RESOLUTION` for a contract that is not a Tron address.\n */\nexport function trc20Contract(ref: AssetRef): string {\n if (ref === 'native' || ref.standard !== 'trc20') {\n throw new UnsupportedCapabilityError(\n 'UNSUPPORTED_CAPABILITY',\n 'Tron supports TRX and TRC-20 tokens only',\n );\n }\n if (!isTronAddress(ref.contract)) throw tokenProblem('not a Tron contract address');\n return toHexAddress(ref.contract);\n}\n\n/**\n * A constant call on a token: a revert, a VM failure or no contract is the\n * token's own permanent problem (`ASSET_RESOLUTION`, cached by the core); node refusals stay\n * retryable and every other error propagates unchanged. \"No contract\" is a node's text, so\n * it counts only once `/wallet/getcontract` confirms it structurally with the same tags; a\n * node that shows a contract there decides nothing.\n */\nexport async function tokenCall(\n ctx: TronContext,\n owner: string,\n contract: string,\n data: string,\n tags: TronCallTags,\n): Promise<string> {\n const answer = await ctx.api.constantCall(owner, contract, data, tags);\n if (answer.kind === 'no-contract') {\n if (await ctx.api.contractExists(contract, tags)) {\n throw new ProviderError(\n 'PROVIDER_INCONSISTENT',\n 'the node both holds and lacks this contract',\n { retryable: true },\n );\n }\n throw tokenProblem('no contract at this address');\n }\n if (answer.kind === 'failed') throw tokenProblem('the call failed');\n return answer.result;\n}\n\n/** A holder's TRC-20 balance. */\nexport async function trc20Balance(\n ctx: TronContext,\n contract: string,\n holder: string,\n tags: TronCallTags = READ,\n): Promise<bigint> {\n const result = await tokenCall(\n ctx,\n toHexAddress(holder),\n contract,\n encodeBalanceOf(holder),\n tags,\n );\n try {\n return decodeUint256(result);\n } catch {\n throw tokenProblem('balanceOf returned no uint256');\n }\n}\n\n/** An ABI `bool` that is `true`: one word, exactly 1 (constant results are lower-case). */\nconst TRUE_WORD = /^0{63}1$/;\n\n/**\n * Whether a token answers `deprecated()` with `true`, as Tether's `TetherToken` (USDT on\n * Tron) does once its owner deprecates it for an upgraded contract (`upgradedAddress`).\n * Only a definitive answer decides: a contract without the method (a revert or VM failure,\n * an answer that is not one ABI `bool`, or a node's \"no contract\", which the balance read\n * beside it settles) is not deprecated. A node refusal or a malformed answer throws\n * retryable, so a failed read is never taken for either answer. The contract's own\n * account is the caller: it always exists.\n */\nexport async function trc20Deprecated(\n ctx: TronContext,\n contract: string,\n tags: TronCallTags,\n): Promise<boolean> {\n const answer = await ctx.api.constantCall(\n contract,\n contract,\n SELECTORS.deprecated,\n tags,\n );\n return answer.kind === 'ok' && TRUE_WORD.test(answer.result);\n}\n\n/**\n * An included transaction's observation. `guard` applies the verdict guard (on-chain\n * evidence that value moved) to our own Attempts; without it (a status lookup by id,\n * `ordering === undefined`), the chain's own view is reported.\n */\nexport async function observeIncluded(\n ctx: TronContext,\n id: string,\n tags: TronCallTags,\n guard: boolean,\n): Promise<DriverTxObservation | null> {\n const info = await ctx.api.transactionInfo('full', id, tags);\n if (!info) return null;\n const [tx, header] = await Promise.all([\n ctx.api.transaction('full', id, tags),\n ctx.api.block('full', info.blockNumber, tags),\n ]);\n // The node indexed the info but cannot serve the transaction or its block yet: decide\n // nothing now (the core keeps its current observation on a retryable error).\n if (!tx || !header) throw notServable();\n const verdict = guard\n ? verdictOf(ctx.codec, tx, info)\n : chainVerdict(ctx.codec, tx, info);\n return {\n seen: 'block',\n txHash: id,\n blockHeight: info.blockNumber,\n blockHash: header.id,\n success: verdict.success,\n ...(verdict.reason ? { reason: verdict.reason } : {}),\n ...(verdict.failure ? { failure: verdict.failure } : {}),\n };\n}\n\nexport function createTronReader(ctx: TronContext): ChainReader {\n const { api } = ctx;\n\n async function getTransaction(id: string): Promise<DriverTransaction | null> {\n const txId = idOf(id);\n if (txId === null) return null;\n const tx = await api.transaction('full', txId, READ);\n if (!tx) {\n const pending: TronTxJson | null = await api.pending(txId, READ);\n return pending\n ? decodeTransaction(ctx.codec, pending, null, undefined, true)\n : null;\n }\n // java-tron serves only included transactions here: without its receipt or its block\n // the answer is \"not yet\", never \"not seen\".\n const info = await api.transactionInfo('full', txId, READ);\n if (!info) throw notServable();\n const header = await api.block('full', info.blockNumber, READ);\n if (!header) throw notServable();\n return decodeTransaction(ctx.codec, tx, info, header.id);\n }\n\n return {\n async getBalance(address, asset) {\n if (asset === 'native')\n return (await api.account(toHexAddress(address), READ)).balance;\n return trc20Balance(ctx, trc20Contract(asset), address);\n },\n async getBlockHeight() {\n return ((await api.block('full', undefined, MONITOR)) as { number: bigint }).number;\n },\n async getFinalizedHeight() {\n return ((await api.block('solid', undefined, MONITOR)) as { number: bigint })\n .number;\n },\n async getBlock(ref): Promise<DriverBlock | null> {\n const key = typeof ref === 'string' ? idOf(ref) : ref;\n if (key === null || (typeof key === 'bigint' && (key < 0n || key > INT64_MAX))) {\n return null;\n }\n const header = await api.block('full', key, READ);\n return header\n ? {\n height: header.number,\n hash: header.id,\n parentHash: header.parentId,\n timestamp: unixSeconds(header.timestamp),\n }\n : null;\n },\n getTransaction,\n async observe(ref, ordering) {\n const id = idOf(ref.id);\n if (id === null) return { seen: 'none' };\n const included = await observeIncluded(ctx, id, MONITOR, ordering !== undefined);\n if (included) return included;\n return (await api.pending(id, MONITOR)) ? { seen: 'mempool' } : { seen: 'none' };\n },\n async getTokenMetadata(ref: TokenRef): Promise<AssetMetadata> {\n const contract = trc20Contract(ref);\n // The contract's own account is the caller: it always exists.\n const decimalsWord = await tokenCall(\n ctx,\n contract,\n contract,\n SELECTORS.decimals,\n METADATA,\n );\n const symbolWord = await tokenCall(\n ctx,\n contract,\n contract,\n SELECTORS.symbol,\n METADATA,\n );\n let decimals: bigint;\n let symbol: string;\n try {\n decimals = decodeUint256(decimalsWord);\n symbol = decodeString(symbolWord);\n } catch {\n throw tokenProblem('unreadable decimals or symbol');\n }\n if (decimals > 255n || symbol.length === 0) {\n throw tokenProblem('decimals or symbol out of range');\n }\n return { symbol, decimals: Number(decimals) };\n },\n normalizeTokenRef(ref: TokenRef): TokenRef {\n if (ref.standard !== 'trc20') {\n throw new ValidationError(\n 'ASSET_RESOLUTION',\n 'Tron tokens use the trc20 standard',\n );\n }\n if (!isTronAddress(ref.contract)) throw tokenProblem('not a Tron contract address');\n return { standard: 'trc20', contract: toBase58Address(ref.contract) };\n },\n };\n}\n\n/** `ext.tron`, the Tron family extension. */\nexport function createTronExt(ctx: TronContext): TronExt {\n return {\n tron: {\n getResources: (address: string): Promise<TronResources> =>\n ctx.api.resources(toHexAddress(address), READ),\n },\n };\n}\n"]}
@@ -5,6 +5,10 @@
5
5
  import type { DriverFactory } from '../../core/driver/types';
6
6
  import { networkOf } from './codec';
7
7
  import { bitcoin } from './sdk';
8
+ /**
9
+ * What `native(bc, 'bitcoinjs-lib')` hands out. It mirrors the SDK, so it is outside
10
+ * semver: a new bitcoinjs-lib line may change it in a minor release.
11
+ */
8
12
  export interface UtxoNativeClient {
9
13
  /** The bitcoinjs-lib module, with this library's `@noble/curves` ECC backend installed. */
10
14
  readonly bitcoin: typeof bitcoin;
@@ -1 +1 @@
1
- {"version":3,"file":"driver.js","sourceRoot":"","sources":["../../../src/adapters/utxo/driver.ts"],"names":[],"mappings":";;;AAKA,mDAAsD;AAEtD,uCAA0E;AAC1E,mCAAoC;AACpC,uCAAsF;AACtF,uCAAkE;AAClE,uCAA8C;AAC9C,qCAAoD;AACpD,qCAAkF;AAClF,+BAA6C;AAC7C,uCAAiD;AACjD,mCAAsC;AAYtC,SAAS,MAAM,CAAC,gBAAwB;IACtC,MAAM,IAAI,GAAG,CAAC,IAAkB,EAAE,IAAY,EAAE,KAAa,EAAE,EAAE,CAC/D,IAAI,CAAC,IAAI,CAAS,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC,CAAC;IAC1E,OAAO;QACL,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CACvB,IAAA,mBAAS,EAAC,MAAM,IAAI,CAAC,IAAI,EAAE,iBAAiB,EAAE,uBAAuB,CAAC,CAAC;QACzE,gBAAgB;QAChB,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CACrB,IAAA,qBAAW,EAAC,MAAM,IAAI,CAAC,IAAI,EAAE,oBAAoB,EAAE,oBAAoB,CAAC,CAAC;KAC5E,CAAC;AACJ,CAAC;AAEY,QAAA,iBAAiB,GAAkB;IAC9C,KAAK,CAAC,MAAM,CAAC,GAAkB;QAC7B,MAAM,MAAM,GAAG,IAAA,2BAAiB,EAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;QACtE,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;YACjB,MAAM,IAAI,mBAAW,CACnB,gBAAgB,EAChB,8CAA8C,CAC/C,CAAC;QACJ,CAAC;QACD,mFAAmF;QACnF,wEAAwE;QACxE,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC;QACpD,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC;QAClD,MAAM,OAAO,GAAG,IAAI,uBAAa,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;QAC9D,MAAM,IAAI,GAAgB;YACxB,OAAO;YACP,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,OAAO,EAAE,GAAG,CAAC,OAAO;YACpB,MAAM;YACN,GAAG,EAAE,GAAG,CAAC,GAAG;SACb,CAAC;QACF,MAAM,OAAO,GAAG,IAAA,iBAAS,EAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC1C,MAAM,OAAO,GAAG,IAAA,qBAAW,EAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC3C,OAAO;YACL,QAAQ,EAAE,QAAQ;YAClB,YAAY,EAAE,MAAM,CAAC,YAAY;YACjC,OAAO,EAAE,IAAA,qBAAY,EAAC,IAAI,CAAC;YAC3B,MAAM,EAAE,IAAA,oBAAW,EAAC,IAAI,CAAC;YACzB,OAAO;YACP,WAAW,EAAE,IAAA,yBAAe,EAAC,IAAI,CAAC;YAClC,MAAM,EAAE,IAAA,oBAAW,EAAC,IAAI,CAAC;YACzB,WAAW,EAAE,IAAA,yBAAe,EAAC,IAAI,EAAE,OAAO,CAAC;YAC3C,MAAM,EAAE,IAAA,oBAAW,EAAC,IAAI,CAAC;YACzB,OAAO,EAAE,IAAA,uBAAc,EAAC,IAAI,CAAC;YAC7B,GAAG,EAAE;gBACH,IAAI,EAAE;oBACJ,WAAW,EAAE,CAAC,OAAe,EAAE,EAAE,CAAC,IAAA,oBAAW,EAAC,IAAI,EAAE,OAAO,CAAC;oBAC5D,aAAa,EAAE,CAAC,OAAwD,EAAE,EAAE,CAC1E,IAAA,8BAAoB,EAAC,IAAI,EAAE,OAAO,CAAC;iBACtC;aACgB;YACnB,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,mBAAW,EAAE,CAAC;YAC3C,mFAAmF;YACnF,oDAAoD;YACpD,cAAc,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC;gBAC1B,IAAA,uBAAa,EAAC,IAAA,4BAAkB,EAAC,MAAM,EAAE,MAAM,CAAC,CAAC,WAAW,CAAC;aAC9D;YACD,kBAAkB,EAAE,GAAG,EAAE;gBACvB,qFAAqF;gBACrF,IAAA,iBAAW,GAAE,CAAC;gBACd,MAAM,MAAM,GAAqB;oBAC/B,OAAO,EAAP,aAAO;oBACP,OAAO,EAAE,EAAE,GAAG,OAAO,EAAE,KAAK,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,EAAE,EAAE;oBACpD,OAAO,EAAE,CAAI,IAAY,EAAE,eAAgC,MAAM,EAAE,EAAE,CACnE,GAAG,CAAC,SAAS,CAAC,IAAI,CAChB,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,EACvD,cAAI,CACL;iBACJ,CAAC;gBACF,OAAO,EAAE,MAAM,EAAE,CAAC;YACpB,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC","sourcesContent":["/**\n * The UTXO driver factory: validated network config, endpoint probes on both transports,\n * and the ports. Loaded only by the manifest's `load()`, with bitcoinjs-lib.\n */\nimport type { ChainDriver, DriverContext, DriverFactory } from '../../core/driver/types';\nimport { ConfigError } from '../../core/errors/error';\nimport type { EndpointCall, HealthProbes } from '../../core/transport/types';\nimport { utxoBroadcaster, utxoBuilder, utxoReplacement } from './builder';\nimport { networkOf } from './codec';\nimport { READ, parseWalletOptions, signingScheme, type UtxoContext } from './context';\nimport { EsploraClient, parseHash, parseHeight } from './esplora';\nimport { utxoNetworkConfig } from './network';\nimport { blockSource, proofSource } from './proofs';\nimport { addressCodec, addressHistory, chainReader, listUnspent } from './reader';\nimport { bitcoin, useNobleEcc } from './sdk';\nimport { coinSelectionPreview } from './preview';\nimport { MAX_OUTPUTS } from './spend';\nimport type { UtxoExt } from './types';\n\nexport interface UtxoNativeClient {\n /** The bitcoinjs-lib module, with this library's `@noble/curves` ECC backend installed. */\n readonly bitcoin: typeof bitcoin;\n /** A fresh copy of this network's bitcoinjs parameters. */\n readonly network: ReturnType<typeof networkOf>;\n /** A GET to the handle's Esplora (`rpc`) endpoints, through the policy-wrapped transport. */\n esplora<T = unknown>(path: string, responseType?: 'json' | 'text'): Promise<T>;\n}\n\nfunction probes(expectedIdentity: string): HealthProbes {\n const text = (call: EndpointCall, path: string, route: string) =>\n call.http<string>({ method: 'GET', path, route, responseType: 'text' });\n return {\n identity: async (call) =>\n parseHash(await text(call, '/block-height/0', '/block-height/:height')),\n expectedIdentity,\n height: async (call) =>\n parseHeight(await text(call, '/blocks/tip/height', '/blocks/tip/height')),\n };\n}\n\nexport const utxoDriverFactory: DriverFactory = {\n async create(ctx: DriverContext): Promise<ChainDriver> {\n const config = utxoNetworkConfig(ctx.chain, ctx.network, ctx.options);\n if (!ctx.indexer) {\n throw new ConfigError(\n 'CONFIG_INVALID',\n 'the UTXO driver requires an indexer provider',\n );\n }\n // Both transports, before any traffic: the genesis-hash probe keeps an endpoint of\n // another network out of the `rpc` reads and the `indexer` reads alike.\n ctx.transport.setProbes(probes(config.genesisHash));\n ctx.indexer.setProbes(probes(config.genesisHash));\n const esplora = new EsploraClient(ctx.transport, ctx.indexer);\n const utxo: UtxoContext = {\n esplora,\n chain: ctx.chain,\n network: ctx.network,\n config,\n log: ctx.log,\n };\n const network = networkOf(config.address);\n const builder = utxoBuilder(utxo, network);\n return {\n ordering: 'inputs',\n capabilities: config.capabilities,\n address: addressCodec(utxo),\n reader: chainReader(utxo),\n builder,\n broadcaster: utxoBroadcaster(utxo),\n proofs: proofSource(utxo),\n replacement: utxoReplacement(utxo, network),\n blocks: blockSource(utxo),\n history: addressHistory(utxo),\n ext: {\n utxo: {\n listUnspent: (address: string) => listUnspent(utxo, address),\n coinSelection: (request: Parameters<UtxoExt['utxo']['coinSelection']>[0]) =>\n coinSelectionPreview(utxo, request),\n },\n } satisfies UtxoExt,\n limits: () => ({ maxOutputs: MAX_OUTPUTS }),\n // One scheme per address type, so a p2tr wallet's ECDSA-only signer (a KMS key) is\n // refused when the wallet resolves, not at signing.\n signingSchemes: (wallet) => [\n signingScheme(parseWalletOptions(wallet, config).addressType),\n ],\n createNativeClient: () => {\n // The doc's promise: taproot works on this module (and a swapped backend is undone).\n useNobleEcc();\n const client: UtxoNativeClient = {\n bitcoin,\n network: { ...network, bip32: { ...network.bip32 } },\n esplora: <T>(path: string, responseType: 'json' | 'text' = 'json') =>\n ctx.transport.http<T>(\n { method: 'GET', path, route: '/native', responseType },\n READ,\n ),\n };\n return { client };\n },\n };\n },\n};\n"]}
1
+ {"version":3,"file":"driver.js","sourceRoot":"","sources":["../../../src/adapters/utxo/driver.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The UTXO driver factory: validated network config, endpoint probes on both transports,\n * and the ports. Loaded only by the manifest's `load()`, with bitcoinjs-lib.\n */\nimport type { ChainDriver, DriverContext, DriverFactory } from '../../core/driver/types';\nimport { ConfigError } from '../../core/errors/error';\nimport type { EndpointCall, HealthProbes } from '../../core/transport/types';\nimport { utxoBroadcaster, utxoBuilder, utxoReplacement } from './builder';\nimport { networkOf } from './codec';\nimport { READ, parseWalletOptions, signingScheme, type UtxoContext } from './context';\nimport { EsploraClient, parseHash, parseHeight } from './esplora';\nimport { utxoNetworkConfig } from './network';\nimport { blockSource, proofSource } from './proofs';\nimport { addressCodec, addressHistory, chainReader, listUnspent } from './reader';\nimport { bitcoin, useNobleEcc } from './sdk';\nimport { coinSelectionPreview } from './preview';\nimport { MAX_OUTPUTS } from './spend';\nimport type { UtxoExt } from './types';\n\n/**\n * What `native(bc, 'bitcoinjs-lib')` hands out. It mirrors the SDK, so it is outside\n * semver: a new bitcoinjs-lib line may change it in a minor release.\n */\nexport interface UtxoNativeClient {\n /** The bitcoinjs-lib module, with this library's `@noble/curves` ECC backend installed. */\n readonly bitcoin: typeof bitcoin;\n /** A fresh copy of this network's bitcoinjs parameters. */\n readonly network: ReturnType<typeof networkOf>;\n /** A GET to the handle's Esplora (`rpc`) endpoints, through the policy-wrapped transport. */\n esplora<T = unknown>(path: string, responseType?: 'json' | 'text'): Promise<T>;\n}\n\nfunction probes(expectedIdentity: string): HealthProbes {\n const text = (call: EndpointCall, path: string, route: string) =>\n call.http<string>({ method: 'GET', path, route, responseType: 'text' });\n return {\n identity: async (call) =>\n parseHash(await text(call, '/block-height/0', '/block-height/:height')),\n expectedIdentity,\n height: async (call) =>\n parseHeight(await text(call, '/blocks/tip/height', '/blocks/tip/height')),\n };\n}\n\nexport const utxoDriverFactory: DriverFactory = {\n async create(ctx: DriverContext): Promise<ChainDriver> {\n const config = utxoNetworkConfig(ctx.chain, ctx.network, ctx.options);\n if (!ctx.indexer) {\n throw new ConfigError(\n 'CONFIG_INVALID',\n 'the UTXO driver requires an indexer provider',\n );\n }\n // Both transports, before any traffic: the genesis-hash probe keeps an endpoint of\n // another network out of the `rpc` reads and the `indexer` reads alike.\n ctx.transport.setProbes(probes(config.genesisHash));\n ctx.indexer.setProbes(probes(config.genesisHash));\n const esplora = new EsploraClient(ctx.transport, ctx.indexer);\n const utxo: UtxoContext = {\n esplora,\n chain: ctx.chain,\n network: ctx.network,\n config,\n log: ctx.log,\n };\n const network = networkOf(config.address);\n const builder = utxoBuilder(utxo, network);\n return {\n ordering: 'inputs',\n capabilities: config.capabilities,\n address: addressCodec(utxo),\n reader: chainReader(utxo),\n builder,\n broadcaster: utxoBroadcaster(utxo),\n proofs: proofSource(utxo),\n replacement: utxoReplacement(utxo, network),\n blocks: blockSource(utxo),\n history: addressHistory(utxo),\n ext: {\n utxo: {\n listUnspent: (address: string) => listUnspent(utxo, address),\n coinSelection: (request: Parameters<UtxoExt['utxo']['coinSelection']>[0]) =>\n coinSelectionPreview(utxo, request),\n },\n } satisfies UtxoExt,\n limits: () => ({ maxOutputs: MAX_OUTPUTS }),\n // One scheme per address type, so a p2tr wallet's ECDSA-only signer (a KMS key) is\n // refused when the wallet resolves, not at signing.\n signingSchemes: (wallet) => [\n signingScheme(parseWalletOptions(wallet, config).addressType),\n ],\n createNativeClient: () => {\n // The doc's promise: taproot works on this module (and a swapped backend is undone).\n useNobleEcc();\n const client: UtxoNativeClient = {\n bitcoin,\n network: { ...network, bip32: { ...network.bip32 } },\n esplora: <T>(path: string, responseType: 'json' | 'text' = 'json') =>\n ctx.transport.http<T>(\n { method: 'GET', path, route: '/native', responseType },\n READ,\n ),\n };\n return { client };\n },\n };\n },\n};\n"]}
@@ -25,6 +25,12 @@ export declare const PREVIOUS_TX_CACHE: Readonly<{
25
25
  /** Bitcoin Core's `MAX_MONEY`: no output, and no balance, is larger. */
26
26
  export declare const MAX_MONEY = 2100000000000000n;
27
27
  export declare function malformed(what: string): ProviderError;
28
+ /**
29
+ * An indexer's refusal to serve an address beyond its own limits, which another indexer
30
+ * may serve: electrs answers HTTP 400 with "Too many unspent transaction outputs", "Too many
31
+ * history entries" or "Scripthash history too large to scan" for a busy address.
32
+ */
33
+ export declare function isAddressLimit(error: unknown): boolean;
28
34
  /** A definitive 404 (not an ambiguous or retried failure): the resource is not there. */
29
35
  export declare function isNotFound(error: unknown): boolean;
30
36
  export declare function parseHeight(text: unknown): bigint;
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.EsploraClient = exports.isHash = exports.MAX_MONEY = exports.PREVIOUS_TX_CACHE = void 0;
4
4
  exports.malformed = malformed;
5
+ exports.isAddressLimit = isAddressLimit;
5
6
  exports.isNotFound = isNotFound;
6
7
  exports.parseHeight = parseHeight;
7
8
  exports.parseHash = parseHash;
@@ -40,6 +41,22 @@ const isHex = (value) => value.length % 2 === 0 && /^[0-9a-f]*$/.test(value);
40
41
  function malformed(what) {
41
42
  return new error_1.ProviderError('PROVIDER_UNAVAILABLE', `malformed Esplora answer: ${what}`);
42
43
  }
44
+ /**
45
+ * An indexer's refusal to serve an address beyond its own limits, which another indexer
46
+ * may serve: electrs answers HTTP 400 with "Too many unspent transaction outputs", "Too many
47
+ * history entries" or "Scripthash history too large to scan" for a busy address.
48
+ */
49
+ function isAddressLimit(error) {
50
+ if (!(0, error_1.isCryptoAioError)(error, 'RPC_ERROR') || error.details?.status !== 400)
51
+ return false;
52
+ const body = error.details.body;
53
+ return typeof body === 'string' && /\btoo (?:many|large)\b/i.test(body);
54
+ }
55
+ /** The tags of a read of an address route: another indexer is asked past one's limit. */
56
+ const addressRead = (tags) => ({
57
+ ...tags,
58
+ endpointLimit: isAddressLimit,
59
+ });
43
60
  /** A definitive 404 (not an ambiguous or retried failure): the resource is not there. */
44
61
  function isNotFound(error) {
45
62
  return ((0, error_1.isCryptoAioError)(error, 'RPC_ERROR') &&
@@ -471,11 +488,11 @@ class EsploraClient {
471
488
  return answer.trim();
472
489
  }
473
490
  async addressUtxos(address, tags) {
474
- const utxos = await this.#get(this.indexer, `/address/${segment(address, 'address')}/utxo`, '/address/:address/utxo', tags);
491
+ const utxos = await this.#get(this.indexer, `/address/${segment(address, 'address')}/utxo`, '/address/:address/utxo', addressRead(tags));
475
492
  return list(utxos, 'utxo list', parseUtxo);
476
493
  }
477
494
  async addressStats(address, tags) {
478
- const info = record(await this.#get(this.indexer, `/address/${segment(address, 'address')}`, '/address/:address', tags, 'json', true), 'address');
495
+ const info = record(await this.#get(this.indexer, `/address/${segment(address, 'address')}`, '/address/:address', addressRead(tags), 'json', true), 'address');
479
496
  const chain = record(info.chain_stats, 'chain_stats');
480
497
  const funded = total(chain.funded_txo_sum, 'funded_txo_sum');
481
498
  const spent = total(chain.spent_txo_sum, 'spent_txo_sum');
@@ -491,7 +508,7 @@ class EsploraClient {
491
508
  const route = lastSeen
492
509
  ? '/address/:address/txs/chain/:last_seen_txid'
493
510
  : '/address/:address/txs/chain';
494
- return list(await this.#get(this.indexer, path, route, tags), 'address txs', parseTx);
511
+ return list(await this.#get(this.indexer, path, route, addressRead(tags)), 'address txs', parseTx);
495
512
  }
496
513
  }
497
514
  exports.EsploraClient = EsploraClient;