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
|
@@ -4,7 +4,14 @@ exports.EVM_PEER_DEPENDENCIES = void 0;
|
|
|
4
4
|
exports.evmManifests = evmManifests;
|
|
5
5
|
exports.evmPlugin = evmPlugin;
|
|
6
6
|
exports.evmChainPlugin = evmChainPlugin;
|
|
7
|
+
/**
|
|
8
|
+
* The EVM family plugin: chains, tokens and provider presets as data, plus one
|
|
9
|
+
* adapter manifest per library. SDK-free: only a manifest's `load()` requires a client
|
|
10
|
+
* module, and with it the SDK. `ethers` is registered first, so it is the family default.
|
|
11
|
+
*/
|
|
12
|
+
const sha3_1 = require("@noble/hashes/sha3");
|
|
7
13
|
const error_1 = require("../../core/errors/error");
|
|
14
|
+
const bytes_1 = require("../../core/util/bytes");
|
|
8
15
|
const chains_1 = require("./chains");
|
|
9
16
|
const network_1 = require("./network");
|
|
10
17
|
const presets_1 = require("./presets");
|
|
@@ -67,9 +74,48 @@ function evmPlugin() {
|
|
|
67
74
|
}
|
|
68
75
|
/** A plugin name: lower-case letters, digits and hyphens, starting with a letter. */
|
|
69
76
|
const PLUGIN_NAME = /^[a-z][a-z0-9-]*$/;
|
|
77
|
+
/** `0x` and 40 hex digits, in any case. */
|
|
78
|
+
const HEX_ADDRESS = /^0x[0-9a-fA-F]{40}$/;
|
|
79
|
+
/** EIP-55: each letter upper-cased where the keccak-256 of the lower-case hex has 8 or more. */
|
|
80
|
+
function eip55(address) {
|
|
81
|
+
const hex = address.slice(2).toLowerCase();
|
|
82
|
+
const hash = (0, bytes_1.toHex)((0, sha3_1.keccak_256)((0, bytes_1.utf8ToBytes)(hex)));
|
|
83
|
+
let out = '0x';
|
|
84
|
+
for (let i = 0; i < hex.length; i++) {
|
|
85
|
+
const c = hex[i];
|
|
86
|
+
out += Number.parseInt(hash[i], 16) >= 8 ? c.toUpperCase() : c;
|
|
87
|
+
}
|
|
88
|
+
return out;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* An ERC-20 registration under the contract the driver names it by. The driver normalizes
|
|
92
|
+
* every token ref it is given, reads or decodes to the EIP-55 form, and an asset id carries
|
|
93
|
+
* the contract as registered, so a lower-case registration would be a second asset of the
|
|
94
|
+
* same token: its alias would resolve to one id, and the token's own transfers, deposits
|
|
95
|
+
* and balances by ref to another. A mixed-case contract with a wrong checksum is a typo,
|
|
96
|
+
* refused as the driver refuses it in a transfer. The refusal never repeats the value.
|
|
97
|
+
*/
|
|
98
|
+
function erc20Registration(asset, name) {
|
|
99
|
+
const { ref } = asset;
|
|
100
|
+
if (ref === 'native')
|
|
101
|
+
return asset;
|
|
102
|
+
const fail = (reason) => {
|
|
103
|
+
throw new error_1.ConfigError('CONFIG_INVALID', `EVM chain plugin '${name}': the asset ${JSON.stringify(asset.metadata.symbol)} on ${asset.chain}:${asset.network} ${reason}`);
|
|
104
|
+
};
|
|
105
|
+
if (ref.standard !== 'erc20')
|
|
106
|
+
fail(`must use the 'erc20' standard`);
|
|
107
|
+
if (!HEX_ADDRESS.test(ref.contract))
|
|
108
|
+
fail('needs a 0x-prefixed 20-byte hex contract');
|
|
109
|
+
const contract = eip55(ref.contract);
|
|
110
|
+
const digits = ref.contract.slice(2);
|
|
111
|
+
const mixedCase = /[a-f]/.test(digits) && /[A-F]/.test(digits);
|
|
112
|
+
if (mixedCase && contract !== ref.contract)
|
|
113
|
+
fail('has a contract with a wrong checksum');
|
|
114
|
+
return contract === ref.contract ? asset : { ...asset, ref: { ...ref, contract } };
|
|
115
|
+
}
|
|
70
116
|
/**
|
|
71
117
|
* A plugin for EVM chains of your own, served by the built-in EVM driver with either
|
|
72
|
-
* library. Every network is validated here, so bad data fails at registration.
|
|
118
|
+
* library. Every network and token is validated here, so bad data fails at registration.
|
|
73
119
|
*/
|
|
74
120
|
function evmChainPlugin(options) {
|
|
75
121
|
if (!PLUGIN_NAME.test(options.name)) {
|
|
@@ -96,7 +142,9 @@ function evmChainPlugin(options) {
|
|
|
96
142
|
chains: options.chains,
|
|
97
143
|
adapters: evmManifests(name, options.chains.map((chain) => chain.id)),
|
|
98
144
|
...(options.presets ? { presets: options.presets } : {}),
|
|
99
|
-
...(options.assets
|
|
145
|
+
...(options.assets
|
|
146
|
+
? { assets: options.assets.map((asset) => erc20Registration(asset, name)) }
|
|
147
|
+
: {}),
|
|
100
148
|
};
|
|
101
149
|
}
|
|
102
150
|
//# sourceMappingURL=plugin.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../../src/adapters/evm/plugin.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The EVM family plugin: chains, tokens and provider presets as data, plus one\n * adapter manifest per library. SDK-free: only a manifest's `load()` requires a client\n * module, and with it the SDK. `ethers` is registered first, so it is the family default.\n */\nimport type {\n AdapterManifest,\n DriverFactory,\n PeerDependency,\n} from '../../core/driver/types';\nimport { ConfigError } from '../../core/errors/error';\nimport type { ChainInfo } from '../../core/model/chain';\nimport type { AssetRegistration } from '../../core/registry/assets';\nimport type { Plugin } from '../../core/registry/plugin';\nimport type { ProviderPreset } from '../../core/registry/providers';\nimport { EVM_CHAINS } from './chains';\nimport { EVM_CAPABILITIES, evmNetworkConfig } from './network';\nimport { EVM_PRESETS } from './presets';\nimport { EVM_TOKENS } from './tokens';\n\n/** The SDK versions this adapter is validated against. */\nexport const EVM_PEER_DEPENDENCIES: Readonly<Record<'ethers' | 'web3', PeerDependency>> =\n {\n ethers: { name: 'ethers', range: '^6.17.0' },\n web3: { name: 'web3', range: '^4.16.0' },\n };\n\n/**\n * The manifests' `load` functions, shared by every `evmManifests(...)` call, so that\n * registering `evmPlugin()` or the same `evmChainPlugin(...)` again is the same plugin:\n * the registry compares a plugin's functions by identity, and refuses a different plugin\n * under a registered name. Each `require`s its client module, and with it the SDK, only\n * when called.\n */\nconst loadEthers = async (): Promise<DriverFactory> => {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const mod = require('./ethers-client') as typeof import('./ethers-client');\n return mod.ethersDriverFactory;\n};\n\nconst loadWeb3 = async (): Promise<DriverFactory> => {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const mod = require('./web3-client') as typeof import('./web3-client');\n return mod.web3DriverFactory;\n};\n\n/** The `ethers` and `web3` manifests for `chains`, keyed `<family>/<library>`. */\nexport function evmManifests(\n family: string,\n chains: readonly string[],\n): AdapterManifest[] {\n return [\n {\n family,\n library: 'ethers',\n chains,\n capabilities: EVM_CAPABILITIES,\n peerDependencies: [EVM_PEER_DEPENDENCIES.ethers],\n load: loadEthers,\n },\n {\n family,\n library: 'web3',\n chains,\n capabilities: EVM_CAPABILITIES,\n peerDependencies: [EVM_PEER_DEPENDENCIES.web3],\n load: loadWeb3,\n },\n ];\n}\n\n/**\n * The built-in EVM family: Ethereum, BNB Smart Chain, Polygon PoS, Avalanche C-Chain,\n * Arbitrum One, OP Mainnet and Base, with their testnets.\n */\nexport function evmPlugin(): Plugin {\n return {\n name: 'evm',\n chains: EVM_CHAINS,\n adapters: evmManifests(\n 'evm',\n EVM_CHAINS.map((chain) => chain.id),\n ),\n presets: EVM_PRESETS,\n assets: EVM_TOKENS,\n };\n}\n\n/** A plugin name: lower-case letters, digits and hyphens, starting with a letter. */\nconst PLUGIN_NAME = /^[a-z][a-z0-9-]*$/;\n\nexport interface EvmChainPluginOptions {\n /**\n * A unique name matching `/^[a-z][a-z0-9-]*$/`. The plugin registers as `evm:<name>`, so\n * it never collides with a family plugin, and its manifests as `evm:<name>/ethers` and\n * `evm:<name>/web3`.\n */\n readonly name: string;\n /** Chains with `family: 'evm'`, nonce ordering and the `secp256k1-ecdsa` scheme. */\n readonly chains: readonly ChainInfo[];\n readonly presets?: readonly ProviderPreset[];\n readonly assets?: readonly AssetRegistration[];\n}\n\n/**\n * A plugin for EVM chains of your own, served by the built-in EVM driver with either\n * library. Every network is validated here, so bad data fails at registration.\n */\nexport function evmChainPlugin(options: EvmChainPluginOptions): Plugin {\n if (!PLUGIN_NAME.test(options.name)) {\n throw new ConfigError(\n 'CONFIG_INVALID',\n `EVM chain plugin name ${JSON.stringify(options.name)} must match ${String(PLUGIN_NAME)}`,\n );\n }\n const name = `evm:${options.name}`;\n for (const chain of options.chains) {\n const fail = (reason: string): never => {\n throw new ConfigError('CONFIG_INVALID', `EVM chain '${chain.id}': ${reason}`);\n };\n if (chain.family !== 'evm') fail(`its family must be 'evm'`);\n if (chain.model !== 'account' || chain.ordering !== 'nonce') {\n fail(`it must use the account model and nonce ordering`);\n }\n if (chain.schemes.length !== 1 || chain.schemes[0] !== 'secp256k1-ecdsa') {\n fail(`its only scheme must be 'secp256k1-ecdsa'`);\n }\n for (const network of Object.values(chain.networks)) evmNetworkConfig(chain, network);\n }\n return {\n name,\n chains: options.chains,\n adapters: evmManifests(\n name,\n options.chains.map((chain) => chain.id),\n ),\n ...(options.presets ? { presets: options.presets } : {}),\n ...(options.assets ? { assets: options.assets } : {}),\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../../src/adapters/evm/plugin.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The EVM family plugin: chains, tokens and provider presets as data, plus one\n * adapter manifest per library. SDK-free: only a manifest's `load()` requires a client\n * module, and with it the SDK. `ethers` is registered first, so it is the family default.\n */\nimport { keccak_256 } from '@noble/hashes/sha3';\nimport type {\n AdapterManifest,\n DriverFactory,\n PeerDependency,\n} from '../../core/driver/types';\nimport { ConfigError } from '../../core/errors/error';\nimport type { ChainInfo } from '../../core/model/chain';\nimport type { AssetRegistration } from '../../core/registry/assets';\nimport type { Plugin } from '../../core/registry/plugin';\nimport type { ProviderPreset } from '../../core/registry/providers';\nimport { toHex, utf8ToBytes } from '../../core/util/bytes';\nimport { EVM_CHAINS } from './chains';\nimport { EVM_CAPABILITIES, evmNetworkConfig } from './network';\nimport { EVM_PRESETS } from './presets';\nimport { EVM_TOKENS } from './tokens';\n\n/** The SDK versions this adapter is validated against. */\nexport const EVM_PEER_DEPENDENCIES: Readonly<Record<'ethers' | 'web3', PeerDependency>> =\n {\n ethers: { name: 'ethers', range: '^6.17.0' },\n web3: { name: 'web3', range: '^4.16.0' },\n };\n\n/**\n * The manifests' `load` functions, shared by every `evmManifests(...)` call, so that\n * registering `evmPlugin()` or the same `evmChainPlugin(...)` again is the same plugin:\n * the registry compares a plugin's functions by identity, and refuses a different plugin\n * under a registered name. Each `require`s its client module, and with it the SDK, only\n * when called.\n */\nconst loadEthers = async (): Promise<DriverFactory> => {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const mod = require('./ethers-client') as typeof import('./ethers-client');\n return mod.ethersDriverFactory;\n};\n\nconst loadWeb3 = async (): Promise<DriverFactory> => {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const mod = require('./web3-client') as typeof import('./web3-client');\n return mod.web3DriverFactory;\n};\n\n/** The `ethers` and `web3` manifests for `chains`, keyed `<family>/<library>`. */\nexport function evmManifests(\n family: string,\n chains: readonly string[],\n): AdapterManifest[] {\n return [\n {\n family,\n library: 'ethers',\n chains,\n capabilities: EVM_CAPABILITIES,\n peerDependencies: [EVM_PEER_DEPENDENCIES.ethers],\n load: loadEthers,\n },\n {\n family,\n library: 'web3',\n chains,\n capabilities: EVM_CAPABILITIES,\n peerDependencies: [EVM_PEER_DEPENDENCIES.web3],\n load: loadWeb3,\n },\n ];\n}\n\n/**\n * The built-in EVM family: Ethereum, BNB Smart Chain, Polygon PoS, Avalanche C-Chain,\n * Arbitrum One, OP Mainnet and Base, with their testnets.\n */\nexport function evmPlugin(): Plugin {\n return {\n name: 'evm',\n chains: EVM_CHAINS,\n adapters: evmManifests(\n 'evm',\n EVM_CHAINS.map((chain) => chain.id),\n ),\n presets: EVM_PRESETS,\n assets: EVM_TOKENS,\n };\n}\n\n/** A plugin name: lower-case letters, digits and hyphens, starting with a letter. */\nconst PLUGIN_NAME = /^[a-z][a-z0-9-]*$/;\n\n/** `0x` and 40 hex digits, in any case. */\nconst HEX_ADDRESS = /^0x[0-9a-fA-F]{40}$/;\n\n/** EIP-55: each letter upper-cased where the keccak-256 of the lower-case hex has 8 or more. */\nfunction eip55(address: string): string {\n const hex = address.slice(2).toLowerCase();\n const hash = toHex(keccak_256(utf8ToBytes(hex)));\n let out = '0x';\n for (let i = 0; i < hex.length; i++) {\n const c = hex[i] as string;\n out += Number.parseInt(hash[i] as string, 16) >= 8 ? c.toUpperCase() : c;\n }\n return out;\n}\n\n/**\n * An ERC-20 registration under the contract the driver names it by. The driver normalizes\n * every token ref it is given, reads or decodes to the EIP-55 form, and an asset id carries\n * the contract as registered, so a lower-case registration would be a second asset of the\n * same token: its alias would resolve to one id, and the token's own transfers, deposits\n * and balances by ref to another. A mixed-case contract with a wrong checksum is a typo,\n * refused as the driver refuses it in a transfer. The refusal never repeats the value.\n */\nfunction erc20Registration(asset: AssetRegistration, name: string): AssetRegistration {\n const { ref } = asset;\n if (ref === 'native') return asset;\n const fail = (reason: string): never => {\n throw new ConfigError(\n 'CONFIG_INVALID',\n `EVM chain plugin '${name}': the asset ${JSON.stringify(asset.metadata.symbol)} on ${asset.chain}:${asset.network} ${reason}`,\n );\n };\n if (ref.standard !== 'erc20') fail(`must use the 'erc20' standard`);\n if (!HEX_ADDRESS.test(ref.contract)) fail('needs a 0x-prefixed 20-byte hex contract');\n const contract = eip55(ref.contract);\n const digits = ref.contract.slice(2);\n const mixedCase = /[a-f]/.test(digits) && /[A-F]/.test(digits);\n if (mixedCase && contract !== ref.contract)\n fail('has a contract with a wrong checksum');\n return contract === ref.contract ? asset : { ...asset, ref: { ...ref, contract } };\n}\n\nexport interface EvmChainPluginOptions {\n /**\n * A unique name matching `/^[a-z][a-z0-9-]*$/`. The plugin registers as `evm:<name>`, so\n * it never collides with a family plugin, and its manifests as `evm:<name>/ethers` and\n * `evm:<name>/web3`.\n */\n readonly name: string;\n /** Chains with `family: 'evm'`, nonce ordering and the `secp256k1-ecdsa` scheme. */\n readonly chains: readonly ChainInfo[];\n readonly presets?: readonly ProviderPreset[];\n /**\n * Tokens: `erc20` refs, each registered under its EIP-55 checksummed contract, whatever\n * case it is given in, so its alias and its transfers name one asset id.\n */\n readonly assets?: readonly AssetRegistration[];\n}\n\n/**\n * A plugin for EVM chains of your own, served by the built-in EVM driver with either\n * library. Every network and token is validated here, so bad data fails at registration.\n */\nexport function evmChainPlugin(options: EvmChainPluginOptions): Plugin {\n if (!PLUGIN_NAME.test(options.name)) {\n throw new ConfigError(\n 'CONFIG_INVALID',\n `EVM chain plugin name ${JSON.stringify(options.name)} must match ${String(PLUGIN_NAME)}`,\n );\n }\n const name = `evm:${options.name}`;\n for (const chain of options.chains) {\n const fail = (reason: string): never => {\n throw new ConfigError('CONFIG_INVALID', `EVM chain '${chain.id}': ${reason}`);\n };\n if (chain.family !== 'evm') fail(`its family must be 'evm'`);\n if (chain.model !== 'account' || chain.ordering !== 'nonce') {\n fail(`it must use the account model and nonce ordering`);\n }\n if (chain.schemes.length !== 1 || chain.schemes[0] !== 'secp256k1-ecdsa') {\n fail(`its only scheme must be 'secp256k1-ecdsa'`);\n }\n for (const network of Object.values(chain.networks)) evmNetworkConfig(chain, network);\n }\n return {\n name,\n chains: options.chains,\n adapters: evmManifests(\n name,\n options.chains.map((chain) => chain.id),\n ),\n ...(options.presets ? { presets: options.presets } : {}),\n ...(options.assets\n ? { assets: options.assets.map((asset) => erc20Registration(asset, name)) }\n : {}),\n };\n}\n"]}
|
|
@@ -143,12 +143,23 @@ async function nonceConsumer(ctx, txHash, ordering, from) {
|
|
|
143
143
|
}
|
|
144
144
|
return {
|
|
145
145
|
included: true,
|
|
146
|
-
|
|
146
|
+
...verdict(receipt.status === 1, (0, decode_1.tokenTransferLanded)(client.abi, consumer, receipt)),
|
|
147
147
|
blockHeight: height,
|
|
148
148
|
blockHash: block.hash,
|
|
149
149
|
txHash: consumer.hash,
|
|
150
150
|
};
|
|
151
151
|
}
|
|
152
|
+
/**
|
|
153
|
+
* The verdict of an included transaction of ours: a reverted one, or one that executed but
|
|
154
|
+
* logged no token transfer to its recipient (`unevidenced`: value may have moved).
|
|
155
|
+
*/
|
|
156
|
+
function verdict(executed, landed) {
|
|
157
|
+
if (!executed)
|
|
158
|
+
return { success: false };
|
|
159
|
+
return landed
|
|
160
|
+
? { success: true }
|
|
161
|
+
: { success: false, reason: 'token transfer failed', failure: 'unevidenced' };
|
|
162
|
+
}
|
|
152
163
|
function createEvmProofs(ctx) {
|
|
153
164
|
const { client } = ctx;
|
|
154
165
|
return {
|
|
@@ -179,8 +190,9 @@ function createEvmProofs(ctx) {
|
|
|
179
190
|
if (final.hash !== receipt.blockHash) {
|
|
180
191
|
throw new error_1.ProviderError('PROVIDER_INCONSISTENT', 'the receipt is not in the final block at its height');
|
|
181
192
|
}
|
|
182
|
-
|
|
183
|
-
|
|
193
|
+
const executed = receipt.status === 1;
|
|
194
|
+
let landed = true;
|
|
195
|
+
if (executed) {
|
|
184
196
|
// A token transfer that logged no transfer to its recipient paid it nothing
|
|
185
197
|
// (read from the ref alone, the call's arguments from its keyed calldata). The
|
|
186
198
|
// core proves only its own Attempts, so this is always a verdict.
|
|
@@ -188,11 +200,11 @@ function createEvmProofs(ctx) {
|
|
|
188
200
|
if (!tx) {
|
|
189
201
|
throw new error_1.ProviderError('PROVIDER_INCONSISTENT', 'a receipt without its transaction');
|
|
190
202
|
}
|
|
191
|
-
|
|
203
|
+
landed = (0, decode_1.tokenTransferLanded)(client.abi, tx, receipt);
|
|
192
204
|
}
|
|
193
205
|
return {
|
|
194
206
|
included: true,
|
|
195
|
-
|
|
207
|
+
...verdict(executed, landed),
|
|
196
208
|
blockHeight: receipt.blockNumber,
|
|
197
209
|
blockHash: receipt.blockHash,
|
|
198
210
|
txHash: receipt.transactionHash,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proofs.js","sourceRoot":"","sources":["../../../src/adapters/evm/proofs.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Proofs and block scanning. Every proof read is a quorum read under `PROOF`, comparing\n * only consensus facts (`rpc.ts`). No proof lets one endpoint choose the final height: a\n * proof attests the fact it needs at that fact's own\n * height, so honest endpoints disagree only while it is final on one and not yet on another,\n * which decides nothing. The block source serves dense heights with native transfers and\n * ERC-20 `Transfer` logs, as the chain reports them. Every error thrown here is a\n * `PROVIDER_*` code, retryable by the code table: look again later.\n */\nimport { keccak_256 } from '@noble/hashes/sha3';\nimport { hexToBytes } from '@noble/hashes/utils';\nimport type { BlockSource, ProofSource } from '../../core/driver/types';\nimport { ProviderError, isCryptoAioError } from '../../core/errors/error';\nimport type { OrderingData } from '../../core/model/ordering';\nimport { quantity } from './client';\nimport { decodeTransaction, tokenTransferLanded } from './decode';\nimport {\n MONITOR,\n PROOF,\n finalBlockAt,\n provenFinal,\n toDriverBlock,\n type EvmContext,\n} from './reader';\nimport { blockTransactionsKey } from './rpc';\nimport type { EvmClient, EvmFullBlock, EvmLog, EvmReceipt, EvmTx } from './types';\n\n/**\n * A quorum key under which every endpoint whose nonce is past `nonce` agrees. A\n * malformed answer throws, which the transport counts as a disagreement.\n */\nconst nonceAbove =\n (nonce: bigint) =>\n (result: unknown): boolean =>\n quantity(result, 'nonce') > nonce;\n\n/**\n * Node texts for state it does not hold: pruned, beyond its recent-state window, or\n * not served at a tag (geth, op-geth, Nitro, BSC, Erigon, Reth, Besu wordings).\n */\nconst STATE_UNAVAILABLE =\n /missing trie node|historical state .* not available|header not found|state (is )?not available|pruned/i;\n\n/**\n * The boundary of every proof. Only a definitive negative answer may\n * say \"no\", and a JSON-RPC error answer is none: state the node does not hold, an index it\n * is still building (geth's \"transaction indexing is in progress\"), or any other error,\n * ambiguous or not. Every `RPC_ERROR` becomes a retryable `PROVIDER_UNAVAILABLE` (look again\n * later, or elsewhere) that carries it as its cause, so no caller takes it for an answer and\n * the monitor keeps watching. Every other error passes unchanged: `PROVIDER_MISCONFIGURED`\n * stays final, and aborts and foreign errors stay what they are.\n */\nasync function undecided<T>(proof: () => Promise<T>): Promise<T> {\n try {\n return await proof();\n } catch (error) {\n if (!isCryptoAioError(error, 'RPC_ERROR')) throw error;\n const message = String(error.details?.rpcMessage ?? error.message);\n throw new ProviderError(\n 'PROVIDER_UNAVAILABLE',\n STATE_UNAVAILABLE.test(message)\n ? 'finalized state not available'\n : 'the endpoints gave no answer',\n { cause: error },\n );\n }\n}\n\n/** A retryable \"decide nothing\": look again later, or elsewhere. */\nconst undecidable = (reason: string) => new ProviderError('PROVIDER_UNAVAILABLE', reason);\n\n/**\n * At most this many nonce reads look for the height that consumed a nonce. The gallop\n * and the bisection take about two reads per doubling of the distance back: at worst 60\n * reads below a final height of 2^30, and 64 below 2^32, so this reaches every consumption\n * on any chain served today.\n */\nconst MAX_SEARCH_READS = 64;\n\n/**\n * The lowest height at or below `final` where `consumed` holds, given that it holds at\n * `final`. A gallop back (`final` less 1, 2, 4, …) finds a height where it does not, then a\n * bisection the first where it does. `consumed` never turns false again as the height\n * grows, since an account's nonce never falls. Beyond `MAX_SEARCH_READS` reads, it decides\n * nothing.\n */\nexport async function consumptionHeight(\n consumed: (height: bigint) => Promise<boolean>,\n final: bigint,\n): Promise<bigint> {\n let reads = 0;\n const read = (height: bigint): Promise<boolean> => {\n if (reads === MAX_SEARCH_READS) {\n throw undecidable('the nonce was consumed too far back to look up');\n }\n reads += 1;\n return consumed(height);\n };\n // Consumed at `high`; not at `low` (below genesis, until a read says otherwise).\n let high = final;\n let low = -1n;\n for (let step = 1n; high > 0n && low < 0n; step *= 2n) {\n const height = final > step ? final - step : 0n;\n if (await read(height)) high = height;\n else low = height;\n }\n while (high - low > 1n) {\n const middle = (low + high) / 2n;\n if (await read(middle)) high = middle;\n else low = middle;\n }\n return high;\n}\n\ntype Inclusion = Awaited<ReturnType<ProofSource['includedFinal']>>;\n\n/**\n * Whether `txHash` is final, when no endpoint serves its\n * receipt. `null` is no proof of absence: a node answers it for every transaction outside its\n * index (geth indexes the last 2,350,000 blocks by default, and pruning nodes of other\n * clients drop theirs), so \"not included\" would prove a final, executed transfer `replaced`.\n * The nonce's consumer decides instead. The quorum attests the nonce consumed at a final\n * height, a search finds the block that consumed it, and the sender's transaction at that\n * nonce there answers: another one proves ours is not included; ours is included, with the\n * verdict its receipt in that block gives. Anything else decides nothing, and so does\n * an endpoint without the historical state the search reads.\n *\n * Known gap: nothing caches the consumer per sender and nonce, so an undecided Attempt\n * repeats the search on every monitor pass. A nonce that an EIP-7702 authorization\n * consumed (no transaction from the sender) is never decided, the safe direction.\n */\nasync function nonceConsumer(\n ctx: EvmContext,\n txHash: string,\n ordering: OrderingData,\n from: string,\n): Promise<Inclusion> {\n if (ordering.kind !== 'nonce')\n throw undecidable('no nonce to look the transaction up by');\n const { client } = ctx;\n const { nonce } = ordering;\n const tags = { ...PROOF, quorumKey: nonceAbove(nonce) };\n const consumed = async (height: bigint) =>\n (await client.getTransactionCount(from, height, tags)) > nonce;\n const { height: final } = await provenFinal(ctx, PROOF);\n if (!(await consumed(final)))\n throw undecidable('the nonce is not consumed at finality');\n const height = await consumptionHeight(consumed, final);\n const block = await client.getBlockWithTransactions(height, {\n ...PROOF,\n quorumKey: blockTransactionsKey,\n });\n if (block?.number !== height) throw undecidable('the endpoints serve no final block');\n const sender = from.toLowerCase();\n const consumer = block.transactions.find(\n (tx) => tx.from.toLowerCase() === sender && tx.nonce === nonce,\n );\n // No transaction from the sender used the nonce: an EIP-7702 authorization can.\n if (!consumer) throw undecidable('no transaction in its block used the nonce');\n // Another transaction is final at our nonce: ours can never be included.\n if (consumer.hash !== txHash.toLowerCase()) return { included: false };\n const receipts = await client.getBlockReceipts(block.hash, PROOF);\n const receipt = receipts?.find((r) => r.transactionHash === consumer.hash);\n if (receipt?.blockHash !== block.hash) {\n throw undecidable('the final block has no receipts on the endpoints');\n }\n return {\n included: true,\n success: receipt.status === 1 && tokenTransferLanded(client.abi, consumer, receipt),\n blockHeight: height,\n blockHash: block.hash,\n txHash: consumer.hash,\n };\n}\n\nexport function createEvmProofs(ctx: EvmContext): ProofSource {\n const { client } = ctx;\n return {\n finalizedHead: () =>\n undecided(async () => {\n const { height, block } = await provenFinal(ctx, PROOF);\n const final = block ?? (await client.getBlock(height, PROOF));\n if (!final) {\n throw new ProviderError(\n 'PROVIDER_UNAVAILABLE',\n 'the endpoints serve no finalized block',\n );\n }\n return { height: final.number, hash: final.hash, timestamp: final.timestamp };\n }),\n\n includedFinal: (ref, ordering, from) =>\n undecided(async () => {\n const receipt = await client.getReceipt(ref.id, PROOF);\n // No receipt is no proof of absence; the transaction at our nonce decides.\n if (!receipt) return nonceConsumer(ctx, ref.id, ordering, from);\n const final = await finalBlockAt(ctx, receipt.blockNumber, PROOF);\n // The transaction is in a block, just not a final one on these endpoints yet.\n // \"Not included\" would let the core prove a final transfer `replaced` (whenAbsent,\n // after the slot was proven consumed on endpoints whose finality is further along),\n // so this decides nothing.\n if (!final) {\n throw new ProviderError('PROVIDER_UNAVAILABLE', 'receipt not yet final');\n }\n // The endpoints agree on a receipt from a block that is not the final one at its\n // height: the chain reorganized between the reads, or their receipt index lags. The\n // transaction may be final elsewhere, so this decides nothing.\n if (final.hash !== receipt.blockHash) {\n throw new ProviderError(\n 'PROVIDER_INCONSISTENT',\n 'the receipt is not in the final block at its height',\n );\n }\n let success = receipt.status === 1;\n if (success) {\n // A token transfer that logged no transfer to its recipient paid it nothing\n // (read from the ref alone, the call's arguments from its keyed calldata). The\n // core proves only its own Attempts, so this is always a verdict.\n const tx = await client.getTransaction(ref.id, PROOF);\n if (!tx) {\n throw new ProviderError(\n 'PROVIDER_INCONSISTENT',\n 'a receipt without its transaction',\n );\n }\n success = tokenTransferLanded(client.abi, tx, receipt);\n }\n return {\n included: true,\n success,\n blockHeight: receipt.blockNumber,\n blockHash: receipt.blockHash,\n txHash: receipt.transactionHash,\n };\n }),\n\n slotConsumed: (ordering, from, level) =>\n undecided(async () => {\n if (ordering.kind !== 'nonce') return false;\n if (level === 'latest') {\n return (\n (await client.getTransactionCount(from, 'latest', MONITOR)) > ordering.nonce\n );\n }\n // The nonce at a height the quorum attests final (one endpoint's view proposes\n // it, trailed by PEER_SKEW), on tag and confirmation networks alike. State at a final\n // height never changes, so honest endpoints agree however their heads move, and one\n // that over-reports its finalized block cannot advance the height. A number,\n // not the `finalized` tag: some nodes (BSC's) serve no state at the tag.\n const { height } = await provenFinal(ctx, PROOF);\n const count = await client.getTransactionCount(from, height, {\n ...PROOF,\n quorumKey: nonceAbove(ordering.nonce),\n });\n return count > ordering.nonce;\n }),\n\n // Nonce ordering: an EVM transaction never expires.\n expired: async () => false,\n\n blockHash: (height, level) =>\n undecided(async () => {\n if (level === 'finalized') {\n return (await finalBlockAt(ctx, height, PROOF))?.hash ?? null;\n }\n return (await client.getBlock(height, PROOF))?.hash ?? null;\n }),\n };\n}\n\nconst changed = (height: bigint) =>\n new ProviderError('PROVIDER_INCONSISTENT', `block ${height} changed while scanning`);\n\n/**\n * Whether a block's `logsBloom` may hold `value` (a log's address or topic), by the\n * yellow paper's M3:2048: three bits, each the low 11 bits of a byte pair of the value's\n * keccak-256. `false` is definitive; `true` may be a false positive. No bloom may hold\n * anything.\n */\nexport function mayHold(bloom: string | undefined, value: string): boolean {\n if (bloom === undefined) return true;\n const hash = keccak_256(hexToBytes(value.slice(2)));\n for (let i = 0; i < 6; i += 2) {\n const bit = (((hash[i] as number) << 8) | (hash[i + 1] as number)) & 2047;\n // Bit 0 is the last byte's lowest bit.\n const byte = 255 - (bit >> 3);\n const bits = Number.parseInt(bloom.slice(2 + 2 * byte, 4 + 2 * byte), 16);\n if ((bits & (1 << (bit & 7))) === 0) return false;\n }\n return true;\n}\n\n/** Provider texts for a method they do not serve, whatever their error code. */\nconst METHOD_MISSING =\n /method .*(not found|not supported|does not exist|is not available)/i;\n\n/**\n * A definitive answer that the node does not serve `eth_getBlockReceipts`: JSON-RPC's\n * \"method not found\" (-32601), EIP-1474's \"method not supported\" (-32004), or a provider's\n * own code with a text that says so.\n */\nfunction methodMissing(error: unknown): boolean {\n if (!isCryptoAioError(error, 'RPC_ERROR') || error.ambiguous) return false;\n const { rpcCode, rpcMessage } = error.details ?? {};\n return (\n rpcCode === -32601 ||\n rpcCode === -32004 ||\n METHOD_MISSING.test(String(rpcMessage ?? ''))\n );\n}\n\ntype Receipts = ReadonlyMap<string, EvmReceipt>;\n\n/**\n * Every receipt of `block` in one call, by transaction hash. The node reads them by\n * block, never through a log or transaction index that may lag. `undefined` when the node\n * does not serve `eth_getBlockReceipts`.\n */\nasync function blockReceipts(\n client: EvmClient,\n block: EvmFullBlock,\n): Promise<Receipts | undefined> {\n let receipts: readonly EvmReceipt[] | null;\n try {\n receipts = await client.getBlockReceipts(block.hash, MONITOR);\n } catch (error) {\n if (methodMissing(error)) return undefined;\n throw error;\n }\n if (receipts === null) throw changed(block.number);\n return new Map(receipts.map((receipt) => [receipt.transactionHash, receipt]));\n}\n\n/** The fallback: one `eth_getTransactionReceipt` per transaction. */\nasync function receiptsOf(client: EvmClient, txs: readonly EvmTx[]): Promise<Receipts> {\n const receipts = await Promise.all(\n txs.map((tx) => client.getReceipt(tx.hash, MONITOR)),\n );\n return new Map(\n receipts.flatMap((receipt, i) =>\n receipt ? [[txs[i]?.hash as string, receipt]] : [],\n ),\n );\n}\n\n/**\n * The logs of every transaction of `block`. A receipt missing, or from another block, could\n * hide a deposit, so it fails the scan retryably instead.\n */\nfunction blockLogs(block: EvmFullBlock, receipts: Receipts): readonly EvmLog[] {\n return block.transactions.flatMap((tx) => {\n const receipt = receipts.get(tx.hash);\n if (receipt?.blockHash !== block.hash) throw changed(block.number);\n return receipt.logs;\n });\n}\n\nexport function createEvmBlocks(ctx: EvmContext): BlockSource {\n const { client, config } = ctx;\n /**\n * The block's `Transfer` logs without block receipts: `eth_getLogs`, which a lagging\n * log index answers empty without an error. So when it answers nothing while the header's\n * bloom may hold the topic, every transaction's receipt is read before the empty answer\n * is trusted: any call may have logged one.\n */\n const transferLogs = async (\n block: EvmFullBlock,\n ): Promise<{ readonly logs: readonly EvmLog[]; readonly receipts?: Receipts }> => {\n const topic = client.abi.transferTopic;\n const logs = await client.getLogs(\n { blockHash: block.hash, topics: [topic] },\n MONITOR,\n );\n if (logs.length > 0 || !mayHold(block.logsBloom, topic)) return { logs };\n const receipts = await receiptsOf(client, block.transactions);\n return { logs: blockLogs(block, receipts), receipts };\n };\n\n return {\n async header(height) {\n const block = await client.getBlock(height, MONITOR);\n return block ? toDriverBlock(block) : null;\n },\n\n async transactions(block, filter) {\n const full = await client.getBlockWithTransactions(block.height, MONITOR);\n if (!full || full.hash !== block.hash) throw changed(block.height);\n // One call for every receipt of the block, filtered scans included.\n let receipts = await blockReceipts(client, full);\n let selected: readonly EvmTx[] = full.transactions;\n if (filter?.addresses?.length) {\n const wanted = new Set(filter.addresses.map((a) => a.toLowerCase()));\n const watched = (address: string | null) =>\n address !== null && wanted.has(address.toLowerCase());\n let logs: readonly EvmLog[];\n if (receipts) logs = blockLogs(full, receipts);\n else ({ logs, receipts } = await transferLogs(full));\n const tokenTxs = new Set(\n logs\n .filter((log) => {\n const transfer = client.abi.decodeTransfer(log);\n return (\n transfer !== null && (watched(transfer.from) || watched(transfer.to))\n );\n })\n .map((log) => log.transactionHash),\n );\n // A contract creation's recipient is only in its receipt, so every creation stays.\n selected = full.transactions.filter(\n (tx) =>\n tx.to === null || watched(tx.from) || watched(tx.to) || tokenTxs.has(tx.hash),\n );\n }\n receipts ??= await receiptsOf(client, selected);\n return selected.map((tx) => {\n const receipt = receipts.get(tx.hash);\n if (!receipt || receipt.blockHash !== block.hash) throw changed(block.height);\n // The chain's view, with the network's config so bor's system logs do not make a\n // plain Polygon transfer `partial`.\n return decodeTransaction(client.abi, tx, receipt, full.timestamp, config);\n });\n },\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"proofs.js","sourceRoot":"","sources":["../../../src/adapters/evm/proofs.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Proofs and block scanning. Every proof read is a quorum read under `PROOF`, comparing\n * only consensus facts (`rpc.ts`). No proof lets one endpoint choose the final height: a\n * proof attests the fact it needs at that fact's own\n * height, so honest endpoints disagree only while it is final on one and not yet on another,\n * which decides nothing. The block source serves dense heights with native transfers and\n * ERC-20 `Transfer` logs, as the chain reports them. Every error thrown here is a\n * `PROVIDER_*` code, retryable by the code table: look again later.\n */\nimport { keccak_256 } from '@noble/hashes/sha3';\nimport { hexToBytes } from '@noble/hashes/utils';\nimport type { BlockSource, ProofSource } from '../../core/driver/types';\nimport { ProviderError, isCryptoAioError } from '../../core/errors/error';\nimport type { OrderingData } from '../../core/model/ordering';\nimport type { TxFailure } from '../../core/model/transaction';\nimport { quantity } from './client';\nimport { decodeTransaction, tokenTransferLanded } from './decode';\nimport {\n MONITOR,\n PROOF,\n finalBlockAt,\n provenFinal,\n toDriverBlock,\n type EvmContext,\n} from './reader';\nimport { blockTransactionsKey } from './rpc';\nimport type { EvmClient, EvmFullBlock, EvmLog, EvmReceipt, EvmTx } from './types';\n\n/**\n * A quorum key under which every endpoint whose nonce is past `nonce` agrees. A\n * malformed answer throws, which the transport counts as a disagreement.\n */\nconst nonceAbove =\n (nonce: bigint) =>\n (result: unknown): boolean =>\n quantity(result, 'nonce') > nonce;\n\n/**\n * Node texts for state it does not hold: pruned, beyond its recent-state window, or\n * not served at a tag (geth, op-geth, Nitro, BSC, Erigon, Reth, Besu wordings).\n */\nconst STATE_UNAVAILABLE =\n /missing trie node|historical state .* not available|header not found|state (is )?not available|pruned/i;\n\n/**\n * The boundary of every proof. Only a definitive negative answer may\n * say \"no\", and a JSON-RPC error answer is none: state the node does not hold, an index it\n * is still building (geth's \"transaction indexing is in progress\"), or any other error,\n * ambiguous or not. Every `RPC_ERROR` becomes a retryable `PROVIDER_UNAVAILABLE` (look again\n * later, or elsewhere) that carries it as its cause, so no caller takes it for an answer and\n * the monitor keeps watching. Every other error passes unchanged: `PROVIDER_MISCONFIGURED`\n * stays final, and aborts and foreign errors stay what they are.\n */\nasync function undecided<T>(proof: () => Promise<T>): Promise<T> {\n try {\n return await proof();\n } catch (error) {\n if (!isCryptoAioError(error, 'RPC_ERROR')) throw error;\n const message = String(error.details?.rpcMessage ?? error.message);\n throw new ProviderError(\n 'PROVIDER_UNAVAILABLE',\n STATE_UNAVAILABLE.test(message)\n ? 'finalized state not available'\n : 'the endpoints gave no answer',\n { cause: error },\n );\n }\n}\n\n/** A retryable \"decide nothing\": look again later, or elsewhere. */\nconst undecidable = (reason: string) => new ProviderError('PROVIDER_UNAVAILABLE', reason);\n\n/**\n * At most this many nonce reads look for the height that consumed a nonce. The gallop\n * and the bisection take about two reads per doubling of the distance back: at worst 60\n * reads below a final height of 2^30, and 64 below 2^32, so this reaches every consumption\n * on any chain served today.\n */\nconst MAX_SEARCH_READS = 64;\n\n/**\n * The lowest height at or below `final` where `consumed` holds, given that it holds at\n * `final`. A gallop back (`final` less 1, 2, 4, …) finds a height where it does not, then a\n * bisection the first where it does. `consumed` never turns false again as the height\n * grows, since an account's nonce never falls. Beyond `MAX_SEARCH_READS` reads, it decides\n * nothing.\n */\nexport async function consumptionHeight(\n consumed: (height: bigint) => Promise<boolean>,\n final: bigint,\n): Promise<bigint> {\n let reads = 0;\n const read = (height: bigint): Promise<boolean> => {\n if (reads === MAX_SEARCH_READS) {\n throw undecidable('the nonce was consumed too far back to look up');\n }\n reads += 1;\n return consumed(height);\n };\n // Consumed at `high`; not at `low` (below genesis, until a read says otherwise).\n let high = final;\n let low = -1n;\n for (let step = 1n; high > 0n && low < 0n; step *= 2n) {\n const height = final > step ? final - step : 0n;\n if (await read(height)) high = height;\n else low = height;\n }\n while (high - low > 1n) {\n const middle = (low + high) / 2n;\n if (await read(middle)) high = middle;\n else low = middle;\n }\n return high;\n}\n\ntype Inclusion = Awaited<ReturnType<ProofSource['includedFinal']>>;\n\n/**\n * Whether `txHash` is final, when no endpoint serves its\n * receipt. `null` is no proof of absence: a node answers it for every transaction outside its\n * index (geth indexes the last 2,350,000 blocks by default, and pruning nodes of other\n * clients drop theirs), so \"not included\" would prove a final, executed transfer `replaced`.\n * The nonce's consumer decides instead. The quorum attests the nonce consumed at a final\n * height, a search finds the block that consumed it, and the sender's transaction at that\n * nonce there answers: another one proves ours is not included; ours is included, with the\n * verdict its receipt in that block gives. Anything else decides nothing, and so does\n * an endpoint without the historical state the search reads.\n *\n * Known gap: nothing caches the consumer per sender and nonce, so an undecided Attempt\n * repeats the search on every monitor pass. A nonce that an EIP-7702 authorization\n * consumed (no transaction from the sender) is never decided, the safe direction.\n */\nasync function nonceConsumer(\n ctx: EvmContext,\n txHash: string,\n ordering: OrderingData,\n from: string,\n): Promise<Inclusion> {\n if (ordering.kind !== 'nonce')\n throw undecidable('no nonce to look the transaction up by');\n const { client } = ctx;\n const { nonce } = ordering;\n const tags = { ...PROOF, quorumKey: nonceAbove(nonce) };\n const consumed = async (height: bigint) =>\n (await client.getTransactionCount(from, height, tags)) > nonce;\n const { height: final } = await provenFinal(ctx, PROOF);\n if (!(await consumed(final)))\n throw undecidable('the nonce is not consumed at finality');\n const height = await consumptionHeight(consumed, final);\n const block = await client.getBlockWithTransactions(height, {\n ...PROOF,\n quorumKey: blockTransactionsKey,\n });\n if (block?.number !== height) throw undecidable('the endpoints serve no final block');\n const sender = from.toLowerCase();\n const consumer = block.transactions.find(\n (tx) => tx.from.toLowerCase() === sender && tx.nonce === nonce,\n );\n // No transaction from the sender used the nonce: an EIP-7702 authorization can.\n if (!consumer) throw undecidable('no transaction in its block used the nonce');\n // Another transaction is final at our nonce: ours can never be included.\n if (consumer.hash !== txHash.toLowerCase()) return { included: false };\n const receipts = await client.getBlockReceipts(block.hash, PROOF);\n const receipt = receipts?.find((r) => r.transactionHash === consumer.hash);\n if (receipt?.blockHash !== block.hash) {\n throw undecidable('the final block has no receipts on the endpoints');\n }\n return {\n included: true,\n ...verdict(receipt.status === 1, tokenTransferLanded(client.abi, consumer, receipt)),\n blockHeight: height,\n blockHash: block.hash,\n txHash: consumer.hash,\n };\n}\n\n/**\n * The verdict of an included transaction of ours: a reverted one, or one that executed but\n * logged no token transfer to its recipient (`unevidenced`: value may have moved).\n */\nfunction verdict(\n executed: boolean,\n landed: boolean,\n): { readonly success: boolean; readonly reason?: string; readonly failure?: TxFailure } {\n if (!executed) return { success: false };\n return landed\n ? { success: true }\n : { success: false, reason: 'token transfer failed', failure: 'unevidenced' };\n}\n\nexport function createEvmProofs(ctx: EvmContext): ProofSource {\n const { client } = ctx;\n return {\n finalizedHead: () =>\n undecided(async () => {\n const { height, block } = await provenFinal(ctx, PROOF);\n const final = block ?? (await client.getBlock(height, PROOF));\n if (!final) {\n throw new ProviderError(\n 'PROVIDER_UNAVAILABLE',\n 'the endpoints serve no finalized block',\n );\n }\n return { height: final.number, hash: final.hash, timestamp: final.timestamp };\n }),\n\n includedFinal: (ref, ordering, from) =>\n undecided(async () => {\n const receipt = await client.getReceipt(ref.id, PROOF);\n // No receipt is no proof of absence; the transaction at our nonce decides.\n if (!receipt) return nonceConsumer(ctx, ref.id, ordering, from);\n const final = await finalBlockAt(ctx, receipt.blockNumber, PROOF);\n // The transaction is in a block, just not a final one on these endpoints yet.\n // \"Not included\" would let the core prove a final transfer `replaced` (whenAbsent,\n // after the slot was proven consumed on endpoints whose finality is further along),\n // so this decides nothing.\n if (!final) {\n throw new ProviderError('PROVIDER_UNAVAILABLE', 'receipt not yet final');\n }\n // The endpoints agree on a receipt from a block that is not the final one at its\n // height: the chain reorganized between the reads, or their receipt index lags. The\n // transaction may be final elsewhere, so this decides nothing.\n if (final.hash !== receipt.blockHash) {\n throw new ProviderError(\n 'PROVIDER_INCONSISTENT',\n 'the receipt is not in the final block at its height',\n );\n }\n const executed = receipt.status === 1;\n let landed = true;\n if (executed) {\n // A token transfer that logged no transfer to its recipient paid it nothing\n // (read from the ref alone, the call's arguments from its keyed calldata). The\n // core proves only its own Attempts, so this is always a verdict.\n const tx = await client.getTransaction(ref.id, PROOF);\n if (!tx) {\n throw new ProviderError(\n 'PROVIDER_INCONSISTENT',\n 'a receipt without its transaction',\n );\n }\n landed = tokenTransferLanded(client.abi, tx, receipt);\n }\n return {\n included: true,\n ...verdict(executed, landed),\n blockHeight: receipt.blockNumber,\n blockHash: receipt.blockHash,\n txHash: receipt.transactionHash,\n };\n }),\n\n slotConsumed: (ordering, from, level) =>\n undecided(async () => {\n if (ordering.kind !== 'nonce') return false;\n if (level === 'latest') {\n return (\n (await client.getTransactionCount(from, 'latest', MONITOR)) > ordering.nonce\n );\n }\n // The nonce at a height the quorum attests final (one endpoint's view proposes\n // it, trailed by PEER_SKEW), on tag and confirmation networks alike. State at a final\n // height never changes, so honest endpoints agree however their heads move, and one\n // that over-reports its finalized block cannot advance the height. A number,\n // not the `finalized` tag: some nodes (BSC's) serve no state at the tag.\n const { height } = await provenFinal(ctx, PROOF);\n const count = await client.getTransactionCount(from, height, {\n ...PROOF,\n quorumKey: nonceAbove(ordering.nonce),\n });\n return count > ordering.nonce;\n }),\n\n // Nonce ordering: an EVM transaction never expires.\n expired: async () => false,\n\n blockHash: (height, level) =>\n undecided(async () => {\n if (level === 'finalized') {\n return (await finalBlockAt(ctx, height, PROOF))?.hash ?? null;\n }\n return (await client.getBlock(height, PROOF))?.hash ?? null;\n }),\n };\n}\n\nconst changed = (height: bigint) =>\n new ProviderError('PROVIDER_INCONSISTENT', `block ${height} changed while scanning`);\n\n/**\n * Whether a block's `logsBloom` may hold `value` (a log's address or topic), by the\n * yellow paper's M3:2048: three bits, each the low 11 bits of a byte pair of the value's\n * keccak-256. `false` is definitive; `true` may be a false positive. No bloom may hold\n * anything.\n */\nexport function mayHold(bloom: string | undefined, value: string): boolean {\n if (bloom === undefined) return true;\n const hash = keccak_256(hexToBytes(value.slice(2)));\n for (let i = 0; i < 6; i += 2) {\n const bit = (((hash[i] as number) << 8) | (hash[i + 1] as number)) & 2047;\n // Bit 0 is the last byte's lowest bit.\n const byte = 255 - (bit >> 3);\n const bits = Number.parseInt(bloom.slice(2 + 2 * byte, 4 + 2 * byte), 16);\n if ((bits & (1 << (bit & 7))) === 0) return false;\n }\n return true;\n}\n\n/** Provider texts for a method they do not serve, whatever their error code. */\nconst METHOD_MISSING =\n /method .*(not found|not supported|does not exist|is not available)/i;\n\n/**\n * A definitive answer that the node does not serve `eth_getBlockReceipts`: JSON-RPC's\n * \"method not found\" (-32601), EIP-1474's \"method not supported\" (-32004), or a provider's\n * own code with a text that says so.\n */\nfunction methodMissing(error: unknown): boolean {\n if (!isCryptoAioError(error, 'RPC_ERROR') || error.ambiguous) return false;\n const { rpcCode, rpcMessage } = error.details ?? {};\n return (\n rpcCode === -32601 ||\n rpcCode === -32004 ||\n METHOD_MISSING.test(String(rpcMessage ?? ''))\n );\n}\n\ntype Receipts = ReadonlyMap<string, EvmReceipt>;\n\n/**\n * Every receipt of `block` in one call, by transaction hash. The node reads them by\n * block, never through a log or transaction index that may lag. `undefined` when the node\n * does not serve `eth_getBlockReceipts`.\n */\nasync function blockReceipts(\n client: EvmClient,\n block: EvmFullBlock,\n): Promise<Receipts | undefined> {\n let receipts: readonly EvmReceipt[] | null;\n try {\n receipts = await client.getBlockReceipts(block.hash, MONITOR);\n } catch (error) {\n if (methodMissing(error)) return undefined;\n throw error;\n }\n if (receipts === null) throw changed(block.number);\n return new Map(receipts.map((receipt) => [receipt.transactionHash, receipt]));\n}\n\n/** The fallback: one `eth_getTransactionReceipt` per transaction. */\nasync function receiptsOf(client: EvmClient, txs: readonly EvmTx[]): Promise<Receipts> {\n const receipts = await Promise.all(\n txs.map((tx) => client.getReceipt(tx.hash, MONITOR)),\n );\n return new Map(\n receipts.flatMap((receipt, i) =>\n receipt ? [[txs[i]?.hash as string, receipt]] : [],\n ),\n );\n}\n\n/**\n * The logs of every transaction of `block`. A receipt missing, or from another block, could\n * hide a deposit, so it fails the scan retryably instead.\n */\nfunction blockLogs(block: EvmFullBlock, receipts: Receipts): readonly EvmLog[] {\n return block.transactions.flatMap((tx) => {\n const receipt = receipts.get(tx.hash);\n if (receipt?.blockHash !== block.hash) throw changed(block.number);\n return receipt.logs;\n });\n}\n\nexport function createEvmBlocks(ctx: EvmContext): BlockSource {\n const { client, config } = ctx;\n /**\n * The block's `Transfer` logs without block receipts: `eth_getLogs`, which a lagging\n * log index answers empty without an error. So when it answers nothing while the header's\n * bloom may hold the topic, every transaction's receipt is read before the empty answer\n * is trusted: any call may have logged one.\n */\n const transferLogs = async (\n block: EvmFullBlock,\n ): Promise<{ readonly logs: readonly EvmLog[]; readonly receipts?: Receipts }> => {\n const topic = client.abi.transferTopic;\n const logs = await client.getLogs(\n { blockHash: block.hash, topics: [topic] },\n MONITOR,\n );\n if (logs.length > 0 || !mayHold(block.logsBloom, topic)) return { logs };\n const receipts = await receiptsOf(client, block.transactions);\n return { logs: blockLogs(block, receipts), receipts };\n };\n\n return {\n async header(height) {\n const block = await client.getBlock(height, MONITOR);\n return block ? toDriverBlock(block) : null;\n },\n\n async transactions(block, filter) {\n const full = await client.getBlockWithTransactions(block.height, MONITOR);\n if (!full || full.hash !== block.hash) throw changed(block.height);\n // One call for every receipt of the block, filtered scans included.\n let receipts = await blockReceipts(client, full);\n let selected: readonly EvmTx[] = full.transactions;\n if (filter?.addresses?.length) {\n const wanted = new Set(filter.addresses.map((a) => a.toLowerCase()));\n const watched = (address: string | null) =>\n address !== null && wanted.has(address.toLowerCase());\n let logs: readonly EvmLog[];\n if (receipts) logs = blockLogs(full, receipts);\n else ({ logs, receipts } = await transferLogs(full));\n const tokenTxs = new Set(\n logs\n .filter((log) => {\n const transfer = client.abi.decodeTransfer(log);\n return (\n transfer !== null && (watched(transfer.from) || watched(transfer.to))\n );\n })\n .map((log) => log.transactionHash),\n );\n // A contract creation's recipient is only in its receipt, so every creation stays.\n selected = full.transactions.filter(\n (tx) =>\n tx.to === null || watched(tx.from) || watched(tx.to) || tokenTxs.has(tx.hash),\n );\n }\n receipts ??= await receiptsOf(client, selected);\n return selected.map((tx) => {\n const receipt = receipts.get(tx.hash);\n if (!receipt || receipt.blockHash !== block.hash) throw changed(block.height);\n // The chain's view, with the network's config so bor's system logs do not make a\n // plain Polygon transfer `partial`.\n return decodeTransaction(client.abi, tx, receipt, full.timestamp, config);\n });\n },\n };\n}\n"]}
|
|
@@ -60,6 +60,24 @@ export declare function createEvmAddressCodec(client: EvmClient): AddressCodec;
|
|
|
60
60
|
export declare function isExecutionFailure(error: unknown): boolean;
|
|
61
61
|
/** An ERC-20 `balanceOf` at `latest`; `ASSET_RESOLUTION` when the contract gives none. */
|
|
62
62
|
export declare function erc20Balance(client: EvmClient, token: string, owner: string, tags: EvmCallTags): Promise<bigint>;
|
|
63
|
+
/**
|
|
64
|
+
* An `eth_call` at `latest` to a method the contract may lack: `null` when the call reverts
|
|
65
|
+
* or the VM stops it, as a call to a missing method does (the dispatcher reverts, or older
|
|
66
|
+
* code hits an invalid opcode). Any other JSON-RPC error is the node's and is rethrown
|
|
67
|
+
* retryable, and everything else propagates unchanged: a failed read is never an answer.
|
|
68
|
+
*/
|
|
69
|
+
export declare function callIfPresent(client: EvmClient, request: {
|
|
70
|
+
readonly to: string;
|
|
71
|
+
readonly data: string;
|
|
72
|
+
}, tags: EvmCallTags): Promise<string | null>;
|
|
73
|
+
/**
|
|
74
|
+
* Whether a token answers `deprecated()` with `true` at `latest`, as Tether's `TetherToken`
|
|
75
|
+
* does once its owner deprecates it for an upgraded contract (`upgradedAddress`). Only a
|
|
76
|
+
* definitive answer decides: a contract without the method (a revert, a VM failure, `0x`,
|
|
77
|
+
* or an answer that is not one ABI `bool`) is not deprecated, and a failed read throws
|
|
78
|
+
* (`callIfPresent`), so it is never taken for either answer.
|
|
79
|
+
*/
|
|
80
|
+
export declare function erc20Deprecated(client: EvmClient, token: string, tags: EvmCallTags): Promise<boolean>;
|
|
63
81
|
export declare function createEvmReader(ctx: EvmContext): ChainReader;
|
|
64
82
|
export declare function createEvmSequence(client: EvmClient): SequenceSource;
|
|
65
83
|
export declare function createEvmExt(client: EvmClient): EvmExt;
|
|
@@ -9,6 +9,8 @@ exports.finalBlockAt = finalBlockAt;
|
|
|
9
9
|
exports.createEvmAddressCodec = createEvmAddressCodec;
|
|
10
10
|
exports.isExecutionFailure = isExecutionFailure;
|
|
11
11
|
exports.erc20Balance = erc20Balance;
|
|
12
|
+
exports.callIfPresent = callIfPresent;
|
|
13
|
+
exports.erc20Deprecated = erc20Deprecated;
|
|
12
14
|
exports.createEvmReader = createEvmReader;
|
|
13
15
|
exports.createEvmSequence = createEvmSequence;
|
|
14
16
|
exports.createEvmExt = createEvmExt;
|
|
@@ -161,6 +163,38 @@ async function erc20Balance(client, token, owner, tags) {
|
|
|
161
163
|
throw assetError('the token contract returned no balance');
|
|
162
164
|
}
|
|
163
165
|
}
|
|
166
|
+
/**
|
|
167
|
+
* An `eth_call` at `latest` to a method the contract may lack: `null` when the call reverts
|
|
168
|
+
* or the VM stops it, as a call to a missing method does (the dispatcher reverts, or older
|
|
169
|
+
* code hits an invalid opcode). Any other JSON-RPC error is the node's and is rethrown
|
|
170
|
+
* retryable, and everything else propagates unchanged: a failed read is never an answer.
|
|
171
|
+
*/
|
|
172
|
+
async function callIfPresent(client, request, tags) {
|
|
173
|
+
try {
|
|
174
|
+
return await client.call(request, 'latest', tags);
|
|
175
|
+
}
|
|
176
|
+
catch (error) {
|
|
177
|
+
if (isRevert(error) || isExecutionFailure(error))
|
|
178
|
+
return null;
|
|
179
|
+
if ((0, error_1.isCryptoAioError)(error, 'RPC_ERROR')) {
|
|
180
|
+
throw (0, error_1.withContext)(error, {}, { retryable: true });
|
|
181
|
+
}
|
|
182
|
+
throw error;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
/** An ABI `bool` that is `true`: one word, exactly 1 (`call` answers lower-case). */
|
|
186
|
+
const TRUE_WORD = /^0x0{63}1$/;
|
|
187
|
+
/**
|
|
188
|
+
* Whether a token answers `deprecated()` with `true` at `latest`, as Tether's `TetherToken`
|
|
189
|
+
* does once its owner deprecates it for an upgraded contract (`upgradedAddress`). Only a
|
|
190
|
+
* definitive answer decides: a contract without the method (a revert, a VM failure, `0x`,
|
|
191
|
+
* or an answer that is not one ABI `bool`) is not deprecated, and a failed read throws
|
|
192
|
+
* (`callIfPresent`), so it is never taken for either answer.
|
|
193
|
+
*/
|
|
194
|
+
async function erc20Deprecated(client, token, tags) {
|
|
195
|
+
const data = await callIfPresent(client, { to: token, data: client.abi.encodeDeprecated() }, tags);
|
|
196
|
+
return data !== null && TRUE_WORD.test(data);
|
|
197
|
+
}
|
|
164
198
|
function tokenOf(asset) {
|
|
165
199
|
if (asset === 'native' || asset.standard !== 'erc20') {
|
|
166
200
|
throw assetError(`EVM tokens use the 'erc20' standard`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reader.js","sourceRoot":"","sources":["../../../src/adapters/evm/reader.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * EVM addresses, reads, nonces, finality and the `ext.evm` API. Every call carries the tags\n * of the `ChainDriver` contract table (`src/core/driver/types.ts`): `read` for point\n * queries, `monitor` for heights, observations and nonces, and `proof` for the finality\n * that proofs attest.\n */\nimport type {\n AddressCodec,\n ChainReader,\n DriverBlock,\n SequenceSource,\n} from '../../core/driver/types';\nimport {\n ProviderError,\n ValidationError,\n isCryptoAioError,\n withContext,\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 { quantity } from './client';\nimport { chainObservation, decodeTransaction, evmObservation } from './decode';\nimport type { EvmNetworkConfig } from './network';\nimport type { EvmBlock, EvmCallTags, EvmClient, EvmExt } from './types';\n\n/** What every EVM port is built from. */\nexport interface EvmContext {\n readonly client: EvmClient;\n readonly chain: ChainInfo;\n readonly network: NetworkInfo;\n readonly config: EvmNetworkConfig;\n readonly log: Logger;\n}\n\nexport const READ: EvmCallTags = { purpose: 'read', retry: 'safe' };\nexport const MONITOR: EvmCallTags = { purpose: 'monitor', retry: 'safe' };\nexport const PROOF: EvmCallTags = { purpose: 'proof', retry: 'safe', quorum: 'proof' };\n\nexport const withSignal = (tags: EvmCallTags, signal?: AbortSignal): EvmCallTags =>\n signal ? { ...tags, signal } : tags;\n\nexport function toDriverBlock(block: EvmBlock): DriverBlock {\n return {\n height: block.number,\n hash: block.hash,\n parentHash: block.parentHash,\n timestamp: block.timestamp,\n transactionIds: block.transactions,\n };\n}\n\n/** Whether a definitive (non-ambiguous) JSON-RPC error says the call reverted. */\nexport function isRevert(error: unknown): boolean {\n if (!isCryptoAioError(error, 'RPC_ERROR') || error.ambiguous) return false;\n const { rpcCode, rpcMessage } = error.details ?? {};\n return rpcCode === 3 || /revert/i.test(String(rpcMessage ?? error.message));\n}\n\n/**\n * How many blocks a proof's final height trails the one endpoint that proposed it, so\n * a quorum peer up to this far behind that endpoint still attests it.\n */\nexport const PEER_SKEW = 2n;\n\n/** `height - depth`, or genesis. */\nconst below = (height: bigint, depth: bigint): bigint =>\n height > depth ? height - depth : 0n;\n\n/**\n * A quorum key under which every endpoint whose block is at or past `height` agrees,\n * so honest endpoints at different heights agree, and one that is not there disagrees.\n * A malformed answer throws, which the transport counts as a disagreement.\n */\nconst atOrPast =\n (height: bigint) =>\n (result: unknown): boolean =>\n result !== null &&\n quantity((result as { readonly number?: unknown }).number, 'block number') >= height;\n\n/** Whether every quorum endpoint's `finalized` block is at or past `height`. */\nasync function finalizedAtOrPast(\n ctx: EvmContext,\n height: bigint,\n tags: EvmCallTags,\n): Promise<boolean> {\n const block = await ctx.client.getBlock('finalized', {\n ...tags,\n quorumKey: atOrPast(height),\n });\n // The endpoints agreed on the predicate, so the first one's block states it for all.\n return block !== null && block.number >= height;\n}\n\n/**\n * The highest final block as one endpoint sees it (a `monitor` view): the `finalized` tag,\n * or the head minus the confirmations; the head read carries the signal of `tags`. Proofs\n * never use it as a final height: `provenFinal` attests one.\n */\nexport async function finalizedHeight(\n ctx: EvmContext,\n tags: EvmCallTags,\n): Promise<bigint> {\n const { finality } = ctx.config;\n if (finality.kind === 'confirmations') {\n const head = await ctx.client.blockNumber(withSignal(MONITOR, tags.signal));\n return below(head, BigInt(finality.confirmations - 1));\n }\n const block = await ctx.client.getBlock('finalized', tags);\n if (!block) {\n throw new ProviderError(\n 'PROVIDER_UNAVAILABLE',\n 'the endpoint reports no finalized block',\n );\n }\n return block.number;\n}\n\n/**\n * A height that is final on every endpoint of the proof quorum (`tags`), and the quorum's\n * block at it when the proof read that block anyway. One endpoint's view (a `monitor` read)\n * only proposes: the height trails it by `PEER_SKEW` blocks, and the quorum attests it. On\n * tag networks every quorum endpoint's `finalized` block must be at or past it; on\n * confirmation networks every one must hold the block that confirms it. So an\n * endpoint that over-reports cannot advance finality, and a peer that trails the proposer\n * by up to `PEER_SKEW` blocks still agrees.\n */\nexport async function provenFinal(\n ctx: EvmContext,\n tags: EvmCallTags,\n): Promise<{ readonly height: bigint; readonly block?: EvmBlock }> {\n const { finality } = ctx.config;\n const view = withSignal(MONITOR, tags.signal);\n if (finality.kind === 'confirmations') {\n const confirming = below(await ctx.client.blockNumber(view), PEER_SKEW);\n const block = await ctx.client.getBlock(confirming, tags);\n if (block?.number !== confirming) {\n throw new ProviderError(\n 'PROVIDER_INCONSISTENT',\n 'the endpoints do not hold the confirming block',\n );\n }\n const height = below(confirming, BigInt(finality.confirmations - 1));\n return height === confirming ? { height, block } : { height };\n }\n const height = below(await finalizedHeight(ctx, view), PEER_SKEW);\n if (!(await finalizedAtOrPast(ctx, height, tags))) {\n throw new ProviderError(\n 'PROVIDER_INCONSISTENT',\n 'the endpoints do not attest the proposed finalized block',\n );\n }\n return { height };\n}\n\n/**\n * The quorum's block at `height` when `height` is final on every endpoint of the proof\n * quorum (`tags`), else `null`. Anchored at `height` itself, not at any endpoint's view:\n * honest endpoints disagree only while `height` is final on one and not yet on another, and\n * that decides nothing (a retryable `PROVIDER_INCONSISTENT`).\n */\nexport async function finalBlockAt(\n ctx: EvmContext,\n height: bigint,\n tags: EvmCallTags,\n): Promise<EvmBlock | null> {\n const { client } = ctx;\n const { finality } = ctx.config;\n if (finality.kind === 'tag') {\n if (!(await finalizedAtOrPast(ctx, height, tags))) return null;\n return client.getBlock(height, tags);\n }\n // The block that gives `height` its confirmations; with one, it is `height`'s own.\n const depth = BigInt(finality.confirmations - 1);\n const confirming = await client.getBlock(height + depth, tags);\n if (confirming === null) return null;\n return depth === 0n ? confirming : client.getBlock(height, tags);\n}\n\nexport function createEvmAddressCodec(client: EvmClient): AddressCodec {\n return {\n validate: (value) => client.isAddress(value),\n normalize: (value) => {\n if (!client.isAddress(value)) {\n throw new ValidationError('INVALID_ADDRESS', 'not an EVM address');\n }\n const canonical = client.checksum(value);\n return { canonical, display: canonical };\n },\n fromPublicKey: (publicKey) => {\n // The client's strict decode already throws a specific `INVALID_ADDRESS`.\n const canonical = client.addressFromPublicKey(publicKey);\n return { canonical, display: canonical };\n },\n };\n}\n\nconst assetError = (reason: string) => new ValidationError('ASSET_RESOLUTION', reason);\n\n/** geth's texts for an EVM that stopped the called code itself (`core/vm/errors.go`). */\nconst VM_FAILURE =\n /^(out of gas|invalid opcode|invalid jump destination|stack (underflow|limit reached)|write protection|return data out of bounds)/i;\n\n/** Whether a definitive (non-ambiguous) JSON-RPC error says the EVM stopped the code. */\nexport function isExecutionFailure(error: unknown): boolean {\n if (!isCryptoAioError(error, 'RPC_ERROR') || error.ambiguous) return false;\n const { rpcMessage } = error.details ?? {};\n return typeof rpcMessage === 'string' && VM_FAILURE.test(rpcMessage);\n}\n\n/** An ERC-20 `balanceOf` at `latest`; `ASSET_RESOLUTION` when the contract gives none. */\nexport async function erc20Balance(\n client: EvmClient,\n token: string,\n owner: string,\n tags: EvmCallTags,\n): Promise<bigint> {\n const data = await client.call(\n { to: token, data: client.abi.encodeBalanceOf(owner) },\n 'latest',\n tags,\n );\n try {\n return client.abi.decodeUint256(data);\n } catch {\n throw assetError('the token contract returned no balance');\n }\n}\n\nfunction tokenOf(asset: AssetRef): string {\n if (asset === 'native' || asset.standard !== 'erc20') {\n throw assetError(`EVM tokens use the 'erc20' standard`);\n }\n return asset.contract;\n}\n\n/** The text of an ABI `string`, or of a `bytes32` (older tokens such as MKR return one). */\nfunction symbolText(client: EvmClient, data: string): string {\n try {\n return client.abi.decodeString(data);\n } catch {\n if (!/^0x[0-9a-fA-F]{64}$/.test(data))\n throw assetError('the token symbol is unreadable');\n return Buffer.from(data.slice(2), 'hex').toString('utf8').replace(/\\0+$/, '');\n }\n}\n\n/**\n * Token metadata is read under the proof quorum, stricter than the contract table's\n * minimum. The core caches it for the container's life, and one endpoint's wrong `decimals`\n * (a lagging, misrouted or buggy backend) would mis-scale every amount by orders of\n * magnitude until restart. `decimals` never changes, so honest endpoints always agree.\n */\nconst METADATA: EvmCallTags = { ...READ, quorum: 'proof' };\n\nexport function createEvmReader(ctx: EvmContext): ChainReader {\n const { client } = ctx;\n /**\n * A revert or a VM execution failure is the token's own permanent problem\n * (`ASSET_RESOLUTION`, which the core caches until restart, even if the call would\n * later run). Any other JSON-RPC error is the node's, so it is rethrown retryable: a\n * provider fault never pins a token. Everything else propagates unchanged: a\n * misconfigured endpoint stays final, and a retryable failure is already retryable.\n */\n const tokenCall = async (contract: string, data: string): Promise<string> => {\n try {\n return await client.call({ to: contract, data }, 'latest', METADATA);\n } catch (error) {\n if (isRevert(error)) throw assetError('the token contract reverted');\n if (isExecutionFailure(error)) throw assetError('the token contract failed to run');\n if (isCryptoAioError(error, 'RPC_ERROR')) {\n throw withContext(error, {}, { retryable: true });\n }\n throw error;\n }\n };\n\n return {\n getBalance: async (address, asset) => {\n if (asset === 'native') return client.getBalance(address, 'latest', READ);\n return erc20Balance(client, tokenOf(asset), address, READ);\n },\n getBlockHeight: () => client.blockNumber(MONITOR),\n getFinalizedHeight: () => finalizedHeight(ctx, MONITOR),\n getBlock: async (ref) => {\n const block = await client.getBlock(ref, READ);\n return block ? toDriverBlock(block) : null;\n },\n getTransaction: async (id) => {\n const tx = await client.getTransaction(id, READ);\n if (!tx) return null;\n const receipt = tx.blockHash !== null ? await client.getReceipt(id, READ) : null;\n return decodeTransaction(client.abi, tx, receipt, undefined, ctx.config);\n },\n /**\n * With an ordering, the token verdict on one of our own Attempts. Without one (a\n * status lookup by id, for a transaction the library does not manage) the chain's\n * view, so a third party's call that shares the `transfer` selector is not reported\n * failed.\n */\n observe: async (ref, ordering) => {\n const tx = await client.getTransaction(ref.id, MONITOR);\n if (!tx) return { seen: 'none' };\n const receipt =\n tx.blockHash === null ? null : await client.getReceipt(ref.id, MONITOR);\n return ordering === undefined\n ? chainObservation(tx, receipt)\n : evmObservation(client.abi, tx, receipt);\n },\n getTokenMetadata: async (ref: TokenRef): Promise<AssetMetadata> => {\n const contract = tokenOf(ref);\n const decimalsData = await tokenCall(contract, client.abi.encodeDecimals());\n if (decimalsData === '0x') throw assetError('no token contract at this address');\n let decimals: bigint;\n try {\n decimals = client.abi.decodeUint256(decimalsData);\n } catch {\n throw assetError('the token decimals are unreadable');\n }\n if (decimals > 255n) throw assetError('the token decimals are out of range');\n const symbol = symbolText(\n client,\n await tokenCall(contract, client.abi.encodeSymbol()),\n );\n if (!symbol) throw assetError('the token has no symbol');\n return { symbol, decimals: Number(decimals) };\n },\n normalizeTokenRef: (ref) => {\n const contract = tokenOf(ref);\n if (!client.isAddress(contract)) throw assetError('not an EVM contract address');\n return { standard: 'erc20', contract: client.checksum(contract) };\n },\n };\n}\n\nexport function createEvmSequence(client: EvmClient): SequenceSource {\n return {\n pending: (address) => client.getTransactionCount(address, 'pending', MONITOR),\n latest: (address) => client.getTransactionCount(address, 'latest', MONITOR),\n };\n}\n\nexport function createEvmExt(client: EvmClient): EvmExt {\n return {\n evm: {\n getNonce: async (address, block = 'latest') => {\n if (block !== 'latest' && block !== 'pending') {\n throw new ValidationError(\n 'INVALID_INTENT',\n `block must be 'latest' or 'pending'`,\n );\n }\n const codec = createEvmAddressCodec(client);\n return client.getTransactionCount(\n codec.normalize(address).canonical,\n block,\n READ,\n );\n },\n },\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"reader.js","sourceRoot":"","sources":["../../../src/adapters/evm/reader.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * EVM addresses, reads, nonces, finality and the `ext.evm` API. Every call carries the tags\n * of the `ChainDriver` contract table (`src/core/driver/types.ts`): `read` for point\n * queries, `monitor` for heights, observations and nonces, and `proof` for the finality\n * that proofs attest.\n */\nimport type {\n AddressCodec,\n ChainReader,\n DriverBlock,\n SequenceSource,\n} from '../../core/driver/types';\nimport {\n ProviderError,\n ValidationError,\n isCryptoAioError,\n withContext,\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 { quantity } from './client';\nimport { chainObservation, decodeTransaction, evmObservation } from './decode';\nimport type { EvmNetworkConfig } from './network';\nimport type { EvmBlock, EvmCallTags, EvmClient, EvmExt } from './types';\n\n/** What every EVM port is built from. */\nexport interface EvmContext {\n readonly client: EvmClient;\n readonly chain: ChainInfo;\n readonly network: NetworkInfo;\n readonly config: EvmNetworkConfig;\n readonly log: Logger;\n}\n\nexport const READ: EvmCallTags = { purpose: 'read', retry: 'safe' };\nexport const MONITOR: EvmCallTags = { purpose: 'monitor', retry: 'safe' };\nexport const PROOF: EvmCallTags = { purpose: 'proof', retry: 'safe', quorum: 'proof' };\n\nexport const withSignal = (tags: EvmCallTags, signal?: AbortSignal): EvmCallTags =>\n signal ? { ...tags, signal } : tags;\n\nexport function toDriverBlock(block: EvmBlock): DriverBlock {\n return {\n height: block.number,\n hash: block.hash,\n parentHash: block.parentHash,\n timestamp: block.timestamp,\n transactionIds: block.transactions,\n };\n}\n\n/** Whether a definitive (non-ambiguous) JSON-RPC error says the call reverted. */\nexport function isRevert(error: unknown): boolean {\n if (!isCryptoAioError(error, 'RPC_ERROR') || error.ambiguous) return false;\n const { rpcCode, rpcMessage } = error.details ?? {};\n return rpcCode === 3 || /revert/i.test(String(rpcMessage ?? error.message));\n}\n\n/**\n * How many blocks a proof's final height trails the one endpoint that proposed it, so\n * a quorum peer up to this far behind that endpoint still attests it.\n */\nexport const PEER_SKEW = 2n;\n\n/** `height - depth`, or genesis. */\nconst below = (height: bigint, depth: bigint): bigint =>\n height > depth ? height - depth : 0n;\n\n/**\n * A quorum key under which every endpoint whose block is at or past `height` agrees,\n * so honest endpoints at different heights agree, and one that is not there disagrees.\n * A malformed answer throws, which the transport counts as a disagreement.\n */\nconst atOrPast =\n (height: bigint) =>\n (result: unknown): boolean =>\n result !== null &&\n quantity((result as { readonly number?: unknown }).number, 'block number') >= height;\n\n/** Whether every quorum endpoint's `finalized` block is at or past `height`. */\nasync function finalizedAtOrPast(\n ctx: EvmContext,\n height: bigint,\n tags: EvmCallTags,\n): Promise<boolean> {\n const block = await ctx.client.getBlock('finalized', {\n ...tags,\n quorumKey: atOrPast(height),\n });\n // The endpoints agreed on the predicate, so the first one's block states it for all.\n return block !== null && block.number >= height;\n}\n\n/**\n * The highest final block as one endpoint sees it (a `monitor` view): the `finalized` tag,\n * or the head minus the confirmations; the head read carries the signal of `tags`. Proofs\n * never use it as a final height: `provenFinal` attests one.\n */\nexport async function finalizedHeight(\n ctx: EvmContext,\n tags: EvmCallTags,\n): Promise<bigint> {\n const { finality } = ctx.config;\n if (finality.kind === 'confirmations') {\n const head = await ctx.client.blockNumber(withSignal(MONITOR, tags.signal));\n return below(head, BigInt(finality.confirmations - 1));\n }\n const block = await ctx.client.getBlock('finalized', tags);\n if (!block) {\n throw new ProviderError(\n 'PROVIDER_UNAVAILABLE',\n 'the endpoint reports no finalized block',\n );\n }\n return block.number;\n}\n\n/**\n * A height that is final on every endpoint of the proof quorum (`tags`), and the quorum's\n * block at it when the proof read that block anyway. One endpoint's view (a `monitor` read)\n * only proposes: the height trails it by `PEER_SKEW` blocks, and the quorum attests it. On\n * tag networks every quorum endpoint's `finalized` block must be at or past it; on\n * confirmation networks every one must hold the block that confirms it. So an\n * endpoint that over-reports cannot advance finality, and a peer that trails the proposer\n * by up to `PEER_SKEW` blocks still agrees.\n */\nexport async function provenFinal(\n ctx: EvmContext,\n tags: EvmCallTags,\n): Promise<{ readonly height: bigint; readonly block?: EvmBlock }> {\n const { finality } = ctx.config;\n const view = withSignal(MONITOR, tags.signal);\n if (finality.kind === 'confirmations') {\n const confirming = below(await ctx.client.blockNumber(view), PEER_SKEW);\n const block = await ctx.client.getBlock(confirming, tags);\n if (block?.number !== confirming) {\n throw new ProviderError(\n 'PROVIDER_INCONSISTENT',\n 'the endpoints do not hold the confirming block',\n );\n }\n const height = below(confirming, BigInt(finality.confirmations - 1));\n return height === confirming ? { height, block } : { height };\n }\n const height = below(await finalizedHeight(ctx, view), PEER_SKEW);\n if (!(await finalizedAtOrPast(ctx, height, tags))) {\n throw new ProviderError(\n 'PROVIDER_INCONSISTENT',\n 'the endpoints do not attest the proposed finalized block',\n );\n }\n return { height };\n}\n\n/**\n * The quorum's block at `height` when `height` is final on every endpoint of the proof\n * quorum (`tags`), else `null`. Anchored at `height` itself, not at any endpoint's view:\n * honest endpoints disagree only while `height` is final on one and not yet on another, and\n * that decides nothing (a retryable `PROVIDER_INCONSISTENT`).\n */\nexport async function finalBlockAt(\n ctx: EvmContext,\n height: bigint,\n tags: EvmCallTags,\n): Promise<EvmBlock | null> {\n const { client } = ctx;\n const { finality } = ctx.config;\n if (finality.kind === 'tag') {\n if (!(await finalizedAtOrPast(ctx, height, tags))) return null;\n return client.getBlock(height, tags);\n }\n // The block that gives `height` its confirmations; with one, it is `height`'s own.\n const depth = BigInt(finality.confirmations - 1);\n const confirming = await client.getBlock(height + depth, tags);\n if (confirming === null) return null;\n return depth === 0n ? confirming : client.getBlock(height, tags);\n}\n\nexport function createEvmAddressCodec(client: EvmClient): AddressCodec {\n return {\n validate: (value) => client.isAddress(value),\n normalize: (value) => {\n if (!client.isAddress(value)) {\n throw new ValidationError('INVALID_ADDRESS', 'not an EVM address');\n }\n const canonical = client.checksum(value);\n return { canonical, display: canonical };\n },\n fromPublicKey: (publicKey) => {\n // The client's strict decode already throws a specific `INVALID_ADDRESS`.\n const canonical = client.addressFromPublicKey(publicKey);\n return { canonical, display: canonical };\n },\n };\n}\n\nconst assetError = (reason: string) => new ValidationError('ASSET_RESOLUTION', reason);\n\n/** geth's texts for an EVM that stopped the called code itself (`core/vm/errors.go`). */\nconst VM_FAILURE =\n /^(out of gas|invalid opcode|invalid jump destination|stack (underflow|limit reached)|write protection|return data out of bounds)/i;\n\n/** Whether a definitive (non-ambiguous) JSON-RPC error says the EVM stopped the code. */\nexport function isExecutionFailure(error: unknown): boolean {\n if (!isCryptoAioError(error, 'RPC_ERROR') || error.ambiguous) return false;\n const { rpcMessage } = error.details ?? {};\n return typeof rpcMessage === 'string' && VM_FAILURE.test(rpcMessage);\n}\n\n/** An ERC-20 `balanceOf` at `latest`; `ASSET_RESOLUTION` when the contract gives none. */\nexport async function erc20Balance(\n client: EvmClient,\n token: string,\n owner: string,\n tags: EvmCallTags,\n): Promise<bigint> {\n const data = await client.call(\n { to: token, data: client.abi.encodeBalanceOf(owner) },\n 'latest',\n tags,\n );\n try {\n return client.abi.decodeUint256(data);\n } catch {\n throw assetError('the token contract returned no balance');\n }\n}\n\n/**\n * An `eth_call` at `latest` to a method the contract may lack: `null` when the call reverts\n * or the VM stops it, as a call to a missing method does (the dispatcher reverts, or older\n * code hits an invalid opcode). Any other JSON-RPC error is the node's and is rethrown\n * retryable, and everything else propagates unchanged: a failed read is never an answer.\n */\nexport async function callIfPresent(\n client: EvmClient,\n request: { readonly to: string; readonly data: string },\n tags: EvmCallTags,\n): Promise<string | null> {\n try {\n return await client.call(request, 'latest', tags);\n } catch (error) {\n if (isRevert(error) || isExecutionFailure(error)) return null;\n if (isCryptoAioError(error, 'RPC_ERROR')) {\n throw withContext(error, {}, { retryable: true });\n }\n throw error;\n }\n}\n\n/** An ABI `bool` that is `true`: one word, exactly 1 (`call` answers lower-case). */\nconst TRUE_WORD = /^0x0{63}1$/;\n\n/**\n * Whether a token answers `deprecated()` with `true` at `latest`, as Tether's `TetherToken`\n * does once its owner deprecates it for an upgraded contract (`upgradedAddress`). Only a\n * definitive answer decides: a contract without the method (a revert, a VM failure, `0x`,\n * or an answer that is not one ABI `bool`) is not deprecated, and a failed read throws\n * (`callIfPresent`), so it is never taken for either answer.\n */\nexport async function erc20Deprecated(\n client: EvmClient,\n token: string,\n tags: EvmCallTags,\n): Promise<boolean> {\n const data = await callIfPresent(\n client,\n { to: token, data: client.abi.encodeDeprecated() },\n tags,\n );\n return data !== null && TRUE_WORD.test(data);\n}\n\nfunction tokenOf(asset: AssetRef): string {\n if (asset === 'native' || asset.standard !== 'erc20') {\n throw assetError(`EVM tokens use the 'erc20' standard`);\n }\n return asset.contract;\n}\n\n/** The text of an ABI `string`, or of a `bytes32` (older tokens such as MKR return one). */\nfunction symbolText(client: EvmClient, data: string): string {\n try {\n return client.abi.decodeString(data);\n } catch {\n if (!/^0x[0-9a-fA-F]{64}$/.test(data))\n throw assetError('the token symbol is unreadable');\n return Buffer.from(data.slice(2), 'hex').toString('utf8').replace(/\\0+$/, '');\n }\n}\n\n/**\n * Token metadata is read under the proof quorum, stricter than the contract table's\n * minimum. The core caches it for the container's life, and one endpoint's wrong `decimals`\n * (a lagging, misrouted or buggy backend) would mis-scale every amount by orders of\n * magnitude until restart. `decimals` never changes, so honest endpoints always agree.\n */\nconst METADATA: EvmCallTags = { ...READ, quorum: 'proof' };\n\nexport function createEvmReader(ctx: EvmContext): ChainReader {\n const { client } = ctx;\n /**\n * A revert or a VM execution failure is the token's own permanent problem\n * (`ASSET_RESOLUTION`, which the core caches until restart, even if the call would\n * later run). Any other JSON-RPC error is the node's, so it is rethrown retryable: a\n * provider fault never pins a token. Everything else propagates unchanged: a\n * misconfigured endpoint stays final, and a retryable failure is already retryable.\n */\n const tokenCall = async (contract: string, data: string): Promise<string> => {\n try {\n return await client.call({ to: contract, data }, 'latest', METADATA);\n } catch (error) {\n if (isRevert(error)) throw assetError('the token contract reverted');\n if (isExecutionFailure(error)) throw assetError('the token contract failed to run');\n if (isCryptoAioError(error, 'RPC_ERROR')) {\n throw withContext(error, {}, { retryable: true });\n }\n throw error;\n }\n };\n\n return {\n getBalance: async (address, asset) => {\n if (asset === 'native') return client.getBalance(address, 'latest', READ);\n return erc20Balance(client, tokenOf(asset), address, READ);\n },\n getBlockHeight: () => client.blockNumber(MONITOR),\n getFinalizedHeight: () => finalizedHeight(ctx, MONITOR),\n getBlock: async (ref) => {\n const block = await client.getBlock(ref, READ);\n return block ? toDriverBlock(block) : null;\n },\n getTransaction: async (id) => {\n const tx = await client.getTransaction(id, READ);\n if (!tx) return null;\n const receipt = tx.blockHash !== null ? await client.getReceipt(id, READ) : null;\n return decodeTransaction(client.abi, tx, receipt, undefined, ctx.config);\n },\n /**\n * With an ordering, the token verdict on one of our own Attempts. Without one (a\n * status lookup by id, for a transaction the library does not manage) the chain's\n * view, so a third party's call that shares the `transfer` selector is not reported\n * failed.\n */\n observe: async (ref, ordering) => {\n const tx = await client.getTransaction(ref.id, MONITOR);\n if (!tx) return { seen: 'none' };\n const receipt =\n tx.blockHash === null ? null : await client.getReceipt(ref.id, MONITOR);\n return ordering === undefined\n ? chainObservation(tx, receipt)\n : evmObservation(client.abi, tx, receipt);\n },\n getTokenMetadata: async (ref: TokenRef): Promise<AssetMetadata> => {\n const contract = tokenOf(ref);\n const decimalsData = await tokenCall(contract, client.abi.encodeDecimals());\n if (decimalsData === '0x') throw assetError('no token contract at this address');\n let decimals: bigint;\n try {\n decimals = client.abi.decodeUint256(decimalsData);\n } catch {\n throw assetError('the token decimals are unreadable');\n }\n if (decimals > 255n) throw assetError('the token decimals are out of range');\n const symbol = symbolText(\n client,\n await tokenCall(contract, client.abi.encodeSymbol()),\n );\n if (!symbol) throw assetError('the token has no symbol');\n return { symbol, decimals: Number(decimals) };\n },\n normalizeTokenRef: (ref) => {\n const contract = tokenOf(ref);\n if (!client.isAddress(contract)) throw assetError('not an EVM contract address');\n return { standard: 'erc20', contract: client.checksum(contract) };\n },\n };\n}\n\nexport function createEvmSequence(client: EvmClient): SequenceSource {\n return {\n pending: (address) => client.getTransactionCount(address, 'pending', MONITOR),\n latest: (address) => client.getTransactionCount(address, 'latest', MONITOR),\n };\n}\n\nexport function createEvmExt(client: EvmClient): EvmExt {\n return {\n evm: {\n getNonce: async (address, block = 'latest') => {\n if (block !== 'latest' && block !== 'pending') {\n throw new ValidationError(\n 'INVALID_INTENT',\n `block must be 'latest' or 'pending'`,\n );\n }\n const codec = createEvmAddressCodec(client);\n return client.getTransactionCount(\n codec.normalize(address).canonical,\n block,\n READ,\n );\n },\n },\n };\n}\n"]}
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
* Well-known tokens: USDT and USDC where their issuers deploy them natively on
|
|
3
3
|
* a built-in mainnet (Tether's supported-protocols page, Circle's USDC addresses page).
|
|
4
4
|
* Addresses are EIP-55 checksummed; decimals are verified on each chain's explorer.
|
|
5
|
+
* Ethereum's USDT is Tether's `TetherToken`, which can deprecate itself for an upgraded
|
|
6
|
+
* contract; the builder then refuses its transfers (`ASSET_RESOLUTION`) until the alias
|
|
7
|
+
* moves.
|
|
5
8
|
*/
|
|
6
9
|
import type { AssetRegistration } from '../../core/registry/assets';
|
|
7
10
|
export declare const EVM_TOKENS: readonly AssetRegistration[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tokens.js","sourceRoot":"","sources":["../../../src/adapters/evm/tokens.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"tokens.js","sourceRoot":"","sources":["../../../src/adapters/evm/tokens.ts"],"names":[],"mappings":";;;AAUA,SAAS,KAAK,CACZ,KAAa,EACb,MAAuB,EACvB,QAAgB;IAEhB,OAAO;QACL,KAAK;QACL,OAAO,EAAE,SAAS;QAClB,GAAG,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE;QACpC,QAAQ,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE;QACjC,OAAO,EAAE,CAAC,MAAM,CAAC;KAClB,CAAC;AACJ,CAAC;AAEY,QAAA,UAAU,GAAiC;IACtD,KAAK,CAAC,UAAU,EAAE,MAAM,EAAE,4CAA4C,CAAC;IACvE,KAAK,CAAC,UAAU,EAAE,MAAM,EAAE,4CAA4C,CAAC;IACvE,KAAK,CAAC,WAAW,EAAE,MAAM,EAAE,4CAA4C,CAAC;IACxE,KAAK,CAAC,WAAW,EAAE,MAAM,EAAE,4CAA4C,CAAC;IACxE,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,4CAA4C,CAAC;IACtE,KAAK,CAAC,UAAU,EAAE,MAAM,EAAE,4CAA4C,CAAC;IACvE,KAAK,CAAC,UAAU,EAAE,MAAM,EAAE,4CAA4C,CAAC;IACvE,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,4CAA4C,CAAC;CACpE,CAAC","sourcesContent":["/**\n * Well-known tokens: USDT and USDC where their issuers deploy them natively on\n * a built-in mainnet (Tether's supported-protocols page, Circle's USDC addresses page).\n * Addresses are EIP-55 checksummed; decimals are verified on each chain's explorer.\n * Ethereum's USDT is Tether's `TetherToken`, which can deprecate itself for an upgraded\n * contract; the builder then refuses its transfers (`ASSET_RESOLUTION`) until the alias\n * moves.\n */\nimport type { AssetRegistration } from '../../core/registry/assets';\n\nfunction token(\n chain: string,\n symbol: 'USDT' | 'USDC',\n contract: string,\n): AssetRegistration {\n return {\n chain,\n network: 'mainnet',\n ref: { standard: 'erc20', contract },\n metadata: { symbol, decimals: 6 },\n aliases: [symbol],\n };\n}\n\nexport const EVM_TOKENS: readonly AssetRegistration[] = [\n token('ethereum', 'USDT', '0xdAC17F958D2ee523a2206206994597C13D831ec7'),\n token('ethereum', 'USDC', '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'),\n token('avalanche', 'USDT', '0x9702230A8Ea53601f5cD2dc00fDBc13d4dF4A8c7'),\n token('avalanche', 'USDC', '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E'),\n token('polygon', 'USDC', '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359'),\n token('arbitrum', 'USDC', '0xaf88d065e77c8cC2239327C5EDb3A432268e5831'),\n token('optimism', 'USDC', '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85'),\n token('base', 'USDC', '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'),\n];\n"]}
|
|
@@ -64,6 +64,12 @@ export interface EvmFeeDetails {
|
|
|
64
64
|
readonly gasPrice?: bigint;
|
|
65
65
|
/** OP Stack networks: the L1 data fee estimate, also charged as `l1-data`. */
|
|
66
66
|
readonly l1Fee?: bigint;
|
|
67
|
+
/**
|
|
68
|
+
* OP Stack networks since Isthmus, where it is not zero: the operator fee for the whole
|
|
69
|
+
* gas limit (an upper bound at the chain's current operator settings), also charged as
|
|
70
|
+
* `operator`.
|
|
71
|
+
*/
|
|
72
|
+
readonly operatorFee?: bigint;
|
|
67
73
|
/** The expected total cost in wei; the `network` charge is its upper bound. */
|
|
68
74
|
readonly expected: bigint;
|
|
69
75
|
}
|
|
@@ -187,8 +193,12 @@ export interface EvmAbi {
|
|
|
187
193
|
encodeBalanceOf(owner: string): string;
|
|
188
194
|
encodeDecimals(): string;
|
|
189
195
|
encodeSymbol(): string;
|
|
196
|
+
/** `deprecated()`, which Tether's `TetherToken` answers `true` once it forwards transfers. */
|
|
197
|
+
encodeDeprecated(): string;
|
|
190
198
|
/** OP Stack `GasPriceOracle.getL1Fee(bytes)` over an unsigned serialized transaction. */
|
|
191
199
|
encodeGetL1Fee(unsignedTx: string): string;
|
|
200
|
+
/** OP Stack `GasPriceOracle.getOperatorFee(uint256)` for `gasUsed` (since Isthmus). */
|
|
201
|
+
encodeGetOperatorFee(gasUsed: bigint): string;
|
|
192
202
|
/** Throws on data that is not one ABI `uint256` word. */
|
|
193
203
|
decodeUint256(data: string): bigint;
|
|
194
204
|
/** Throws on data that is not an ABI `string`. */
|