crypto-aio 0.0.3 → 0.1.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 +17 -0
- package/README.md +144 -14
- package/dist/adapters/avalanche/address.d.ts +15 -0
- package/dist/adapters/avalanche/address.js +74 -0
- package/dist/adapters/avalanche/address.js.map +1 -0
- package/dist/adapters/avalanche/api.d.ts +100 -0
- package/dist/adapters/avalanche/api.js +381 -0
- package/dist/adapters/avalanche/api.js.map +1 -0
- package/dist/adapters/avalanche/builder.d.ts +13 -0
- package/dist/adapters/avalanche/builder.js +336 -0
- package/dist/adapters/avalanche/builder.js.map +1 -0
- package/dist/adapters/avalanche/cb58.d.ts +7 -0
- package/dist/adapters/avalanche/cb58.js +49 -0
- package/dist/adapters/avalanche/cb58.js.map +1 -0
- package/dist/adapters/avalanche/chains.d.ts +21 -0
- package/dist/adapters/avalanche/chains.js +79 -0
- package/dist/adapters/avalanche/chains.js.map +1 -0
- package/dist/adapters/avalanche/codec.d.ts +94 -0
- package/dist/adapters/avalanche/codec.js +371 -0
- package/dist/adapters/avalanche/codec.js.map +1 -0
- package/dist/adapters/avalanche/context.d.ts +59 -0
- package/dist/adapters/avalanche/context.js +114 -0
- package/dist/adapters/avalanche/context.js.map +1 -0
- package/dist/adapters/avalanche/decode.d.ts +16 -0
- package/dist/adapters/avalanche/decode.js +101 -0
- package/dist/adapters/avalanche/decode.js.map +1 -0
- package/dist/adapters/avalanche/driver.d.ts +22 -0
- package/dist/adapters/avalanche/driver.js +81 -0
- package/dist/adapters/avalanche/driver.js.map +1 -0
- package/dist/adapters/avalanche/errors.d.ts +18 -0
- package/dist/adapters/avalanche/errors.js +61 -0
- package/dist/adapters/avalanche/errors.js.map +1 -0
- package/dist/adapters/avalanche/fees.d.ts +23 -0
- package/dist/adapters/avalanche/fees.js +105 -0
- package/dist/adapters/avalanche/fees.js.map +1 -0
- package/dist/adapters/avalanche/index.d.ts +19 -0
- package/dist/adapters/avalanche/index.js +8 -0
- package/dist/adapters/avalanche/index.js.map +1 -0
- package/dist/adapters/avalanche/network.d.ts +37 -0
- package/dist/adapters/avalanche/network.js +135 -0
- package/dist/adapters/avalanche/network.js.map +1 -0
- package/dist/adapters/avalanche/plugin.d.ts +21 -0
- package/dist/adapters/avalanche/plugin.js +46 -0
- package/dist/adapters/avalanche/plugin.js.map +1 -0
- package/dist/adapters/avalanche/presets.d.ts +6 -0
- package/dist/adapters/avalanche/presets.js +86 -0
- package/dist/adapters/avalanche/presets.js.map +1 -0
- package/dist/adapters/avalanche/proofs.d.ts +41 -0
- package/dist/adapters/avalanche/proofs.js +270 -0
- package/dist/adapters/avalanche/proofs.js.map +1 -0
- package/dist/adapters/avalanche/reader.d.ts +40 -0
- package/dist/adapters/avalanche/reader.js +231 -0
- package/dist/adapters/avalanche/reader.js.map +1 -0
- package/dist/adapters/avalanche/sdk.d.ts +182 -0
- package/dist/adapters/avalanche/sdk.js +21 -0
- package/dist/adapters/avalanche/sdk.js.map +1 -0
- package/dist/adapters/avalanche/types.d.ts +86 -0
- package/dist/{type/common.js → adapters/avalanche/types.js} +1 -1
- package/dist/adapters/avalanche/types.js.map +1 -0
- package/dist/adapters/evm/builder.d.ts +11 -0
- package/dist/adapters/evm/builder.js +326 -0
- package/dist/adapters/evm/builder.js.map +1 -0
- package/dist/adapters/evm/chains.d.ts +6 -0
- package/dist/adapters/evm/chains.js +203 -0
- package/dist/adapters/evm/chains.js.map +1 -0
- package/dist/adapters/evm/client.d.ts +84 -0
- package/dist/adapters/evm/client.js +335 -0
- package/dist/adapters/evm/client.js.map +1 -0
- package/dist/adapters/evm/decode.d.ts +35 -0
- package/dist/adapters/evm/decode.js +170 -0
- package/dist/adapters/evm/decode.js.map +1 -0
- package/dist/adapters/evm/driver.d.ts +8 -0
- package/dist/adapters/evm/driver.js +61 -0
- package/dist/adapters/evm/driver.js.map +1 -0
- package/dist/adapters/evm/errors.d.ts +20 -0
- package/dist/adapters/evm/errors.js +110 -0
- package/dist/adapters/evm/errors.js.map +1 -0
- package/dist/adapters/evm/ethers-client.d.ts +43 -0
- package/dist/adapters/evm/ethers-client.js +135 -0
- package/dist/adapters/evm/ethers-client.js.map +1 -0
- package/dist/adapters/evm/fees.d.ts +79 -0
- package/dist/adapters/evm/fees.js +234 -0
- package/dist/adapters/evm/fees.js.map +1 -0
- package/dist/adapters/evm/index.d.ts +20 -0
- package/dist/adapters/evm/index.js +11 -0
- package/dist/adapters/evm/index.js.map +1 -0
- package/dist/adapters/evm/network.d.ts +60 -0
- package/dist/adapters/evm/network.js +131 -0
- package/dist/adapters/evm/network.js.map +1 -0
- package/dist/adapters/evm/plugin.d.ts +36 -0
- package/dist/adapters/evm/plugin.js +102 -0
- package/dist/adapters/evm/plugin.js.map +1 -0
- package/dist/adapters/evm/presets.d.ts +2 -0
- package/dist/adapters/evm/presets.js +105 -0
- package/dist/adapters/evm/presets.js.map +1 -0
- package/dist/adapters/evm/proofs.d.ts +19 -0
- package/dist/adapters/evm/proofs.js +358 -0
- package/dist/adapters/evm/proofs.js.map +1 -0
- package/dist/adapters/evm/rawtx.d.ts +25 -0
- package/dist/adapters/evm/rawtx.js +176 -0
- package/dist/adapters/evm/rawtx.js.map +1 -0
- package/dist/adapters/evm/reader.d.ts +65 -0
- package/dist/adapters/evm/reader.js +292 -0
- package/dist/adapters/evm/reader.js.map +1 -0
- package/dist/adapters/evm/rpc.d.ts +39 -0
- package/dist/adapters/evm/rpc.js +152 -0
- package/dist/adapters/evm/rpc.js.map +1 -0
- package/dist/adapters/evm/tokens.d.ts +7 -0
- package/dist/adapters/evm/tokens.js +23 -0
- package/dist/adapters/evm/tokens.js.map +1 -0
- package/dist/adapters/evm/types.d.ts +255 -0
- package/dist/{type/account.js → adapters/evm/types.js} +1 -1
- package/dist/adapters/evm/types.js.map +1 -0
- package/dist/adapters/evm/web3-client.d.ts +23 -0
- package/dist/adapters/evm/web3-client.js +159 -0
- package/dist/adapters/evm/web3-client.js.map +1 -0
- package/dist/adapters/solana/builder.d.ts +18 -0
- package/dist/adapters/solana/builder.js +545 -0
- package/dist/adapters/solana/builder.js.map +1 -0
- package/dist/adapters/solana/chains.d.ts +13 -0
- package/dist/adapters/solana/chains.js +37 -0
- package/dist/adapters/solana/chains.js.map +1 -0
- package/dist/adapters/solana/decode.d.ts +111 -0
- package/dist/adapters/solana/decode.js +595 -0
- package/dist/adapters/solana/decode.js.map +1 -0
- package/dist/adapters/solana/driver.d.ts +15 -0
- package/dist/adapters/solana/driver.js +72 -0
- package/dist/adapters/solana/driver.js.map +1 -0
- package/dist/adapters/solana/errors.d.ts +36 -0
- package/dist/adapters/solana/errors.js +154 -0
- package/dist/adapters/solana/errors.js.map +1 -0
- package/dist/adapters/solana/fees.d.ts +68 -0
- package/dist/adapters/solana/fees.js +205 -0
- package/dist/adapters/solana/fees.js.map +1 -0
- package/dist/adapters/solana/heights.d.ts +47 -0
- package/dist/adapters/solana/heights.js +185 -0
- package/dist/adapters/solana/heights.js.map +1 -0
- package/dist/adapters/solana/history.d.ts +10 -0
- package/dist/adapters/solana/history.js +71 -0
- package/dist/adapters/solana/history.js.map +1 -0
- package/dist/adapters/solana/index.d.ts +16 -0
- package/dist/adapters/solana/index.js +9 -0
- package/dist/adapters/solana/index.js.map +1 -0
- package/dist/adapters/solana/keys.d.ts +13 -0
- package/dist/adapters/solana/keys.js +69 -0
- package/dist/adapters/solana/keys.js.map +1 -0
- package/dist/adapters/solana/network.d.ts +24 -0
- package/dist/adapters/solana/network.js +95 -0
- package/dist/adapters/solana/network.js.map +1 -0
- package/dist/adapters/solana/plugin.d.ts +18 -0
- package/dist/adapters/solana/plugin.js +41 -0
- package/dist/adapters/solana/plugin.js.map +1 -0
- package/dist/adapters/solana/presets.d.ts +2 -0
- package/dist/adapters/solana/presets.js +77 -0
- package/dist/adapters/solana/presets.js.map +1 -0
- package/dist/adapters/solana/programs.d.ts +44 -0
- package/dist/adapters/solana/programs.js +159 -0
- package/dist/adapters/solana/programs.js.map +1 -0
- package/dist/adapters/solana/proofs.d.ts +56 -0
- package/dist/adapters/solana/proofs.js +540 -0
- package/dist/adapters/solana/proofs.js.map +1 -0
- package/dist/adapters/solana/reader.d.ts +82 -0
- package/dist/adapters/solana/reader.js +326 -0
- package/dist/adapters/solana/reader.js.map +1 -0
- package/dist/adapters/solana/rpc.d.ts +102 -0
- package/dist/adapters/solana/rpc.js +301 -0
- package/dist/adapters/solana/rpc.js.map +1 -0
- package/dist/adapters/solana/tokens.d.ts +7 -0
- package/dist/adapters/solana/tokens.js +19 -0
- package/dist/adapters/solana/tokens.js.map +1 -0
- package/dist/adapters/solana/types.d.ts +121 -0
- package/dist/{type/contract.js → adapters/solana/types.js} +1 -1
- package/dist/adapters/solana/types.js.map +1 -0
- package/dist/adapters/solana/web3.d.ts +5 -0
- package/dist/adapters/solana/web3.js +83 -0
- package/dist/adapters/solana/web3.js.map +1 -0
- package/dist/adapters/solana/wire.d.ts +62 -0
- package/dist/adapters/solana/wire.js +168 -0
- package/dist/adapters/solana/wire.js.map +1 -0
- package/dist/adapters/ton/address.d.ts +43 -0
- package/dist/adapters/ton/address.js +168 -0
- package/dist/adapters/ton/address.js.map +1 -0
- package/dist/adapters/ton/api.d.ts +344 -0
- package/dist/adapters/ton/api.js +942 -0
- package/dist/adapters/ton/api.js.map +1 -0
- package/dist/adapters/ton/builder.d.ts +18 -0
- package/dist/adapters/ton/builder.js +701 -0
- package/dist/adapters/ton/builder.js.map +1 -0
- package/dist/adapters/ton/chains.d.ts +16 -0
- package/dist/adapters/ton/chains.js +39 -0
- package/dist/adapters/ton/chains.js.map +1 -0
- package/dist/adapters/ton/decode.d.ts +43 -0
- package/dist/adapters/ton/decode.js +219 -0
- package/dist/adapters/ton/decode.js.map +1 -0
- package/dist/adapters/ton/driver.d.ts +10 -0
- package/dist/adapters/ton/driver.js +117 -0
- package/dist/adapters/ton/driver.js.map +1 -0
- package/dist/adapters/ton/errors.d.ts +36 -0
- package/dist/adapters/ton/errors.js +89 -0
- package/dist/adapters/ton/errors.js.map +1 -0
- package/dist/adapters/ton/fees.d.ts +28 -0
- package/dist/adapters/ton/fees.js +121 -0
- package/dist/adapters/ton/fees.js.map +1 -0
- package/dist/adapters/ton/index.d.ts +16 -0
- package/dist/adapters/ton/index.js +9 -0
- package/dist/adapters/ton/index.js.map +1 -0
- package/dist/adapters/ton/messages.d.ts +157 -0
- package/dist/adapters/ton/messages.js +397 -0
- package/dist/adapters/ton/messages.js.map +1 -0
- package/dist/adapters/ton/native-client.d.ts +10 -0
- package/dist/adapters/ton/native-client.js +47 -0
- package/dist/adapters/ton/native-client.js.map +1 -0
- package/dist/adapters/ton/network.d.ts +58 -0
- package/dist/adapters/ton/network.js +207 -0
- package/dist/adapters/ton/network.js.map +1 -0
- package/dist/adapters/ton/plugin.d.ts +24 -0
- package/dist/adapters/ton/plugin.js +57 -0
- package/dist/adapters/ton/plugin.js.map +1 -0
- package/dist/adapters/ton/presets.d.ts +6 -0
- package/dist/adapters/ton/presets.js +94 -0
- package/dist/adapters/ton/presets.js.map +1 -0
- package/dist/adapters/ton/proofs.d.ts +66 -0
- package/dist/adapters/ton/proofs.js +813 -0
- package/dist/adapters/ton/proofs.js.map +1 -0
- package/dist/adapters/ton/reader.d.ts +194 -0
- package/dist/adapters/ton/reader.js +781 -0
- package/dist/adapters/ton/reader.js.map +1 -0
- package/dist/adapters/ton/tokens.d.ts +10 -0
- package/dist/adapters/ton/tokens.js +27 -0
- package/dist/adapters/ton/tokens.js.map +1 -0
- package/dist/adapters/ton/trace.d.ts +48 -0
- package/dist/adapters/ton/trace.js +277 -0
- package/dist/adapters/ton/trace.js.map +1 -0
- package/dist/adapters/ton/types.d.ts +105 -0
- package/dist/{type/transact.js → adapters/ton/types.js} +1 -1
- package/dist/adapters/ton/types.js.map +1 -0
- package/dist/adapters/ton/wallets.d.ts +86 -0
- package/dist/adapters/ton/wallets.js +373 -0
- package/dist/adapters/ton/wallets.js.map +1 -0
- package/dist/adapters/tron/abi.d.ts +39 -0
- package/dist/adapters/tron/abi.js +110 -0
- package/dist/adapters/tron/abi.js.map +1 -0
- package/dist/adapters/tron/address.d.ts +20 -0
- package/dist/adapters/tron/address.js +110 -0
- package/dist/adapters/tron/address.js.map +1 -0
- package/dist/adapters/tron/builder.d.ts +12 -0
- package/dist/adapters/tron/builder.js +553 -0
- package/dist/adapters/tron/builder.js.map +1 -0
- package/dist/adapters/tron/chains.d.ts +12 -0
- package/dist/adapters/tron/chains.js +35 -0
- package/dist/adapters/tron/chains.js.map +1 -0
- package/dist/adapters/tron/codec.d.ts +10 -0
- package/dist/adapters/tron/codec.js +322 -0
- package/dist/adapters/tron/codec.js.map +1 -0
- package/dist/adapters/tron/decode.d.ts +50 -0
- package/dist/adapters/tron/decode.js +280 -0
- package/dist/adapters/tron/decode.js.map +1 -0
- package/dist/adapters/tron/driver.d.ts +12 -0
- package/dist/adapters/tron/driver.js +106 -0
- package/dist/adapters/tron/driver.js.map +1 -0
- package/dist/adapters/tron/errors.d.ts +74 -0
- package/dist/adapters/tron/errors.js +261 -0
- package/dist/adapters/tron/errors.js.map +1 -0
- package/dist/adapters/tron/fees.d.ts +49 -0
- package/dist/adapters/tron/fees.js +166 -0
- package/dist/adapters/tron/fees.js.map +1 -0
- package/dist/adapters/tron/http.d.ts +173 -0
- package/dist/adapters/tron/http.js +729 -0
- package/dist/adapters/tron/http.js.map +1 -0
- package/dist/adapters/tron/index.d.ts +16 -0
- package/dist/adapters/tron/index.js +15 -0
- package/dist/adapters/tron/index.js.map +1 -0
- package/dist/adapters/tron/network.d.ts +44 -0
- package/dist/adapters/tron/network.js +163 -0
- package/dist/adapters/tron/network.js.map +1 -0
- package/dist/adapters/tron/plugin.d.ts +17 -0
- package/dist/adapters/tron/plugin.js +39 -0
- package/dist/adapters/tron/plugin.js.map +1 -0
- package/dist/adapters/tron/presets.d.ts +5 -0
- package/dist/adapters/tron/presets.js +68 -0
- package/dist/adapters/tron/presets.js.map +1 -0
- package/dist/adapters/tron/proofs.d.ts +80 -0
- package/dist/adapters/tron/proofs.js +370 -0
- package/dist/adapters/tron/proofs.js.map +1 -0
- package/dist/adapters/tron/protobuf.d.ts +36 -0
- package/dist/adapters/tron/protobuf.js +90 -0
- package/dist/adapters/tron/protobuf.js.map +1 -0
- package/dist/adapters/tron/reader.d.ts +47 -0
- package/dist/adapters/tron/reader.js +203 -0
- package/dist/adapters/tron/reader.js.map +1 -0
- package/dist/adapters/tron/tokens.d.ts +7 -0
- package/dist/adapters/tron/tokens.js +14 -0
- package/dist/adapters/tron/tokens.js.map +1 -0
- package/dist/adapters/tron/types.d.ts +166 -0
- package/dist/adapters/tron/types.js +3 -0
- package/dist/adapters/tron/types.js.map +1 -0
- package/dist/adapters/utxo/address.d.ts +51 -0
- package/dist/adapters/utxo/address.js +341 -0
- package/dist/adapters/utxo/address.js.map +1 -0
- package/dist/adapters/utxo/builder.d.ts +35 -0
- package/dist/adapters/utxo/builder.js +380 -0
- package/dist/adapters/utxo/builder.js.map +1 -0
- package/dist/adapters/utxo/chains.d.ts +17 -0
- package/dist/adapters/utxo/chains.js +99 -0
- package/dist/adapters/utxo/chains.js.map +1 -0
- package/dist/adapters/utxo/codec.d.ts +120 -0
- package/dist/adapters/utxo/codec.js +408 -0
- package/dist/adapters/utxo/codec.js.map +1 -0
- package/dist/adapters/utxo/coinselect.d.ts +48 -0
- package/dist/adapters/utxo/coinselect.js +131 -0
- package/dist/adapters/utxo/coinselect.js.map +1 -0
- package/dist/adapters/utxo/context.d.ts +57 -0
- package/dist/adapters/utxo/context.js +118 -0
- package/dist/adapters/utxo/context.js.map +1 -0
- package/dist/adapters/utxo/decode.d.ts +14 -0
- package/dist/adapters/utxo/decode.js +85 -0
- package/dist/adapters/utxo/decode.js.map +1 -0
- package/dist/adapters/utxo/driver.d.ts +16 -0
- package/dist/adapters/utxo/driver.js +74 -0
- package/dist/adapters/utxo/driver.js.map +1 -0
- package/dist/adapters/utxo/ecc.d.ts +9 -0
- package/dist/adapters/utxo/ecc.js +26 -0
- package/dist/adapters/utxo/ecc.js.map +1 -0
- package/dist/adapters/utxo/errors.d.ts +52 -0
- package/dist/adapters/utxo/errors.js +191 -0
- package/dist/adapters/utxo/errors.js.map +1 -0
- package/dist/adapters/utxo/esplora.d.ts +79 -0
- package/dist/adapters/utxo/esplora.js +451 -0
- package/dist/adapters/utxo/esplora.js.map +1 -0
- package/dist/adapters/utxo/fees.d.ts +41 -0
- package/dist/adapters/utxo/fees.js +125 -0
- package/dist/adapters/utxo/fees.js.map +1 -0
- package/dist/adapters/utxo/index.d.ts +17 -0
- package/dist/adapters/utxo/index.js +8 -0
- package/dist/adapters/utxo/index.js.map +1 -0
- package/dist/adapters/utxo/network.d.ts +50 -0
- package/dist/adapters/utxo/network.js +165 -0
- package/dist/adapters/utxo/network.js.map +1 -0
- package/dist/adapters/utxo/plugin.d.ts +17 -0
- package/dist/adapters/utxo/plugin.js +41 -0
- package/dist/adapters/utxo/plugin.js.map +1 -0
- package/dist/adapters/utxo/presets.d.ts +12 -0
- package/dist/adapters/utxo/presets.js +47 -0
- package/dist/adapters/utxo/presets.js.map +1 -0
- package/dist/adapters/utxo/preview.d.ts +3 -0
- package/dist/adapters/utxo/preview.js +65 -0
- package/dist/adapters/utxo/preview.js.map +1 -0
- package/dist/adapters/utxo/proofs.d.ts +57 -0
- package/dist/adapters/utxo/proofs.js +331 -0
- package/dist/adapters/utxo/proofs.js.map +1 -0
- package/dist/adapters/utxo/rawtx.d.ts +59 -0
- package/dist/adapters/utxo/rawtx.js +234 -0
- package/dist/adapters/utxo/rawtx.js.map +1 -0
- package/dist/adapters/utxo/reader.d.ts +36 -0
- package/dist/adapters/utxo/reader.js +265 -0
- package/dist/adapters/utxo/reader.js.map +1 -0
- package/dist/adapters/utxo/sdk.d.ts +18 -0
- package/dist/adapters/utxo/sdk.js +17 -0
- package/dist/adapters/utxo/sdk.js.map +1 -0
- package/dist/adapters/utxo/signed-psbt.d.ts +36 -0
- package/dist/adapters/utxo/signed-psbt.js +428 -0
- package/dist/adapters/utxo/signed-psbt.js.map +1 -0
- package/dist/adapters/utxo/spend.d.ts +59 -0
- package/dist/adapters/utxo/spend.js +230 -0
- package/dist/adapters/utxo/spend.js.map +1 -0
- package/dist/adapters/utxo/types.d.ts +167 -0
- package/dist/adapters/utxo/types.js +3 -0
- package/dist/adapters/utxo/types.js.map +1 -0
- package/dist/core/assets/service.d.ts +18 -0
- package/dist/core/assets/service.js +69 -0
- package/dist/core/assets/service.js.map +1 -0
- package/dist/core/blockchain/default-ref.d.ts +4 -0
- package/dist/core/blockchain/default-ref.js +16 -0
- package/dist/core/blockchain/default-ref.js.map +1 -0
- package/dist/core/blockchain/handle.d.ts +200 -0
- package/dist/core/blockchain/handle.js +579 -0
- package/dist/core/blockchain/handle.js.map +1 -0
- package/dist/core/blockchain/internal.d.ts +19 -0
- package/dist/core/blockchain/internal.js +16 -0
- package/dist/core/blockchain/internal.js.map +1 -0
- package/dist/core/blockchain/mapping.d.ts +22 -0
- package/dist/core/blockchain/mapping.js +136 -0
- package/dist/core/blockchain/mapping.js.map +1 -0
- package/dist/core/config/env.d.ts +8 -0
- package/dist/core/config/env.js +60 -0
- package/dist/core/config/env.js.map +1 -0
- package/dist/core/config/merge.d.ts +26 -0
- package/dist/core/config/merge.js +144 -0
- package/dist/core/config/merge.js.map +1 -0
- package/dist/core/config/resolve.d.ts +12 -0
- package/dist/core/config/resolve.js +251 -0
- package/dist/core/config/resolve.js.map +1 -0
- package/dist/core/config/types.d.ts +165 -0
- package/dist/core/config/types.js +3 -0
- package/dist/core/config/types.js.map +1 -0
- package/dist/core/container/builtins.d.ts +4 -0
- package/dist/core/container/builtins.js +13 -0
- package/dist/core/container/builtins.js.map +1 -0
- package/dist/core/container/container.d.ts +69 -0
- package/dist/core/container/container.js +466 -0
- package/dist/core/container/container.js.map +1 -0
- package/dist/core/container/default.d.ts +15 -0
- package/dist/core/container/default.js +70 -0
- package/dist/core/container/default.js.map +1 -0
- package/dist/core/container/internals.d.ts +54 -0
- package/dist/core/container/internals.js +21 -0
- package/dist/core/container/internals.js.map +1 -0
- package/dist/core/container/pool.d.ts +27 -0
- package/dist/core/container/pool.js +77 -0
- package/dist/core/container/pool.js.map +1 -0
- package/dist/core/driver/types.d.ts +346 -0
- package/dist/core/driver/types.js +3 -0
- package/dist/core/driver/types.js.map +1 -0
- package/dist/core/errors/codes.d.ts +153 -0
- package/dist/core/errors/codes.js +49 -0
- package/dist/core/errors/codes.js.map +1 -0
- package/dist/core/errors/error.d.ts +66 -0
- package/dist/core/errors/error.js +129 -0
- package/dist/core/errors/error.js.map +1 -0
- package/dist/core/events/bus.d.ts +12 -0
- package/dist/core/events/bus.js +46 -0
- package/dist/core/events/bus.js.map +1 -0
- package/dist/core/events/logger.d.ts +13 -0
- package/dist/core/events/logger.js +42 -0
- package/dist/core/events/logger.js.map +1 -0
- package/dist/core/events/types.d.ts +131 -0
- package/dist/core/events/types.js +3 -0
- package/dist/core/events/types.js.map +1 -0
- package/dist/core/lifecycle/engine-rules.d.ts +107 -0
- package/dist/core/lifecycle/engine-rules.js +257 -0
- package/dist/core/lifecycle/engine-rules.js.map +1 -0
- package/dist/core/lifecycle/engine.d.ts +500 -0
- package/dist/core/lifecycle/engine.js +1732 -0
- package/dist/core/lifecycle/engine.js.map +1 -0
- package/dist/core/lifecycle/evaluate.d.ts +19 -0
- package/dist/core/lifecycle/evaluate.js +72 -0
- package/dist/core/lifecycle/evaluate.js.map +1 -0
- package/dist/core/lifecycle/intent.d.ts +11 -0
- package/dist/core/lifecycle/intent.js +88 -0
- package/dist/core/lifecycle/intent.js.map +1 -0
- package/dist/core/lifecycle/monitor.d.ts +138 -0
- package/dist/core/lifecycle/monitor.js +606 -0
- package/dist/core/lifecycle/monitor.js.map +1 -0
- package/dist/core/lifecycle/observations.d.ts +17 -0
- package/dist/core/lifecycle/observations.js +59 -0
- package/dist/core/lifecycle/observations.js.map +1 -0
- package/dist/core/lifecycle/reconcile.d.ts +58 -0
- package/dist/core/lifecycle/reconcile.js +112 -0
- package/dist/core/lifecycle/reconcile.js.map +1 -0
- package/dist/core/lifecycle/views.d.ts +49 -0
- package/dist/core/lifecycle/views.js +57 -0
- package/dist/core/lifecycle/views.js.map +1 -0
- package/dist/core/lifecycle/workers.d.ts +82 -0
- package/dist/core/lifecycle/workers.js +329 -0
- package/dist/core/lifecycle/workers.js.map +1 -0
- package/dist/core/model/address.d.ts +32 -0
- package/dist/core/model/address.js +43 -0
- package/dist/core/model/address.js.map +1 -0
- package/dist/core/model/amount.d.ts +25 -0
- package/dist/core/model/amount.js +102 -0
- package/dist/core/model/amount.js.map +1 -0
- package/dist/core/model/asset.d.ts +28 -0
- package/dist/core/model/asset.js +47 -0
- package/dist/core/model/asset.js.map +1 -0
- package/dist/core/model/capability.d.ts +3 -0
- package/dist/core/model/capability.js +18 -0
- package/dist/core/model/capability.js.map +1 -0
- package/dist/core/model/chain.d.ts +63 -0
- package/dist/core/model/chain.js +8 -0
- package/dist/core/model/chain.js.map +1 -0
- package/dist/core/model/fee.d.ts +36 -0
- package/dist/core/model/fee.js +17 -0
- package/dist/core/model/fee.js.map +1 -0
- package/dist/core/model/ids.d.ts +37 -0
- package/dist/core/model/ids.js +13 -0
- package/dist/core/model/ids.js.map +1 -0
- package/dist/core/model/intent.d.ts +63 -0
- package/dist/core/model/intent.js +81 -0
- package/dist/core/model/intent.js.map +1 -0
- package/dist/core/model/ordering.d.ts +20 -0
- package/dist/core/model/ordering.js +29 -0
- package/dist/core/model/ordering.js.map +1 -0
- package/dist/core/model/transaction.d.ts +116 -0
- package/dist/{type/lib-types.js → core/model/transaction.js} +1 -1
- package/dist/core/model/transaction.js.map +1 -0
- package/dist/core/observe/scanner.d.ts +135 -0
- package/dist/core/observe/scanner.js +355 -0
- package/dist/core/observe/scanner.js.map +1 -0
- package/dist/core/ordering/reservations.d.ts +16 -0
- package/dist/core/ordering/reservations.js +53 -0
- package/dist/core/ordering/reservations.js.map +1 -0
- package/dist/core/ordering/sequence.d.ts +61 -0
- package/dist/core/ordering/sequence.js +155 -0
- package/dist/core/ordering/sequence.js.map +1 -0
- package/dist/core/registry/adapters.d.ts +10 -0
- package/dist/core/registry/adapters.js +56 -0
- package/dist/core/registry/adapters.js.map +1 -0
- package/dist/core/registry/assets.d.ts +18 -0
- package/dist/core/registry/assets.js +90 -0
- package/dist/core/registry/assets.js.map +1 -0
- package/dist/core/registry/chains.d.ts +10 -0
- package/dist/core/registry/chains.js +80 -0
- package/dist/core/registry/chains.js.map +1 -0
- package/dist/core/registry/plugin.d.ts +41 -0
- package/dist/core/registry/plugin.js +109 -0
- package/dist/core/registry/plugin.js.map +1 -0
- package/dist/core/registry/providers.d.ts +31 -0
- package/dist/core/registry/providers.js +43 -0
- package/dist/core/registry/providers.js.map +1 -0
- package/dist/core/registry/schemes.d.ts +30 -0
- package/dist/core/registry/schemes.js +84 -0
- package/dist/core/registry/schemes.js.map +1 -0
- package/dist/core/secret/fragments.d.ts +33 -0
- package/dist/core/secret/fragments.js +110 -0
- package/dist/core/secret/fragments.js.map +1 -0
- package/dist/core/secret/redact.d.ts +10 -0
- package/dist/core/secret/redact.js +110 -0
- package/dist/core/secret/redact.js.map +1 -0
- package/dist/core/secret/secret.d.ts +14 -0
- package/dist/core/secret/secret.js +42 -0
- package/dist/core/secret/secret.js.map +1 -0
- package/dist/core/signing/callback.d.ts +10 -0
- package/dist/core/signing/callback.js +22 -0
- package/dist/core/signing/callback.js.map +1 -0
- package/dist/core/signing/guard.d.ts +18 -0
- package/dist/core/signing/guard.js +72 -0
- package/dist/core/signing/guard.js.map +1 -0
- package/dist/core/signing/hd.d.ts +36 -0
- package/dist/core/signing/hd.js +167 -0
- package/dist/core/signing/hd.js.map +1 -0
- package/dist/core/signing/local.d.ts +48 -0
- package/dist/core/signing/local.js +190 -0
- package/dist/core/signing/local.js.map +1 -0
- package/dist/core/signing/orchestrator.d.ts +40 -0
- package/dist/core/signing/orchestrator.js +300 -0
- package/dist/core/signing/orchestrator.js.map +1 -0
- package/dist/core/signing/types.d.ts +64 -0
- package/dist/core/signing/types.js +3 -0
- package/dist/core/signing/types.js.map +1 -0
- package/dist/core/signing/wallet.d.ts +48 -0
- package/dist/core/signing/wallet.js +153 -0
- package/dist/core/signing/wallet.js.map +1 -0
- package/dist/core/store/clone.d.ts +25 -0
- package/dist/core/store/clone.js +71 -0
- package/dist/core/store/clone.js.map +1 -0
- package/dist/core/store/memory.d.ts +38 -0
- package/dist/core/store/memory.js +325 -0
- package/dist/core/store/memory.js.map +1 -0
- package/dist/core/store/types.d.ts +246 -0
- package/dist/core/store/types.js +117 -0
- package/dist/core/store/types.js.map +1 -0
- package/dist/core/transport/backoff.d.ts +8 -0
- package/dist/core/transport/backoff.js +27 -0
- package/dist/core/transport/backoff.js.map +1 -0
- package/dist/core/transport/circuit.d.ts +25 -0
- package/dist/core/transport/circuit.js +61 -0
- package/dist/core/transport/circuit.js.map +1 -0
- package/dist/core/transport/http-transport.d.ts +30 -0
- package/dist/core/transport/http-transport.js +1695 -0
- package/dist/core/transport/http-transport.js.map +1 -0
- package/dist/core/transport/rate-limit.d.ts +27 -0
- package/dist/core/transport/rate-limit.js +78 -0
- package/dist/core/transport/rate-limit.js.map +1 -0
- package/dist/core/transport/stale-view.d.ts +11 -0
- package/dist/core/transport/stale-view.js +17 -0
- package/dist/core/transport/stale-view.js.map +1 -0
- package/dist/core/transport/types.d.ts +144 -0
- package/dist/core/transport/types.js +6 -0
- package/dist/core/transport/types.js.map +1 -0
- package/dist/core/util/bytes.d.ts +9 -0
- package/dist/core/util/bytes.js +40 -0
- package/dist/core/util/bytes.js.map +1 -0
- package/dist/core/util/clock.d.ts +6 -0
- package/dist/core/util/clock.js +26 -0
- package/dist/core/util/clock.js.map +1 -0
- package/dist/core/util/freeze.d.ts +8 -0
- package/dist/core/util/freeze.js +31 -0
- package/dist/core/util/freeze.js.map +1 -0
- package/dist/core/util/json.d.ts +29 -0
- package/dist/core/util/json.js +165 -0
- package/dist/core/util/json.js.map +1 -0
- package/dist/core/util/names.d.ts +21 -0
- package/dist/core/util/names.js +46 -0
- package/dist/core/util/names.js.map +1 -0
- package/dist/index.d.ts +64 -14
- package/dist/index.js +105 -49
- package/dist/index.js.map +1 -1
- package/dist/native.d.ts +21 -0
- package/dist/native.js +44 -0
- package/dist/native.js.map +1 -0
- package/dist/testing/contracts/api.d.ts +12 -0
- package/dist/testing/contracts/api.js +58 -0
- package/dist/testing/contracts/api.js.map +1 -0
- package/dist/testing/contracts/cursors.d.ts +6 -0
- package/dist/testing/contracts/cursors.js +43 -0
- package/dist/testing/contracts/cursors.js.map +1 -0
- package/dist/testing/contracts/locks.d.ts +10 -0
- package/dist/testing/contracts/locks.js +63 -0
- package/dist/testing/contracts/locks.js.map +1 -0
- package/dist/testing/contracts/operations.d.ts +21 -0
- package/dist/testing/contracts/operations.js +718 -0
- package/dist/testing/contracts/operations.js.map +1 -0
- package/dist/testing/contracts/sequences.d.ts +6 -0
- package/dist/testing/contracts/sequences.js +68 -0
- package/dist/testing/contracts/sequences.js.map +1 -0
- package/dist/testing/env.d.ts +63 -0
- package/dist/testing/env.js +105 -0
- package/dist/testing/env.js.map +1 -0
- package/dist/testing/fake-chain.d.ts +118 -0
- package/dist/testing/fake-chain.js +536 -0
- package/dist/testing/fake-chain.js.map +1 -0
- package/dist/testing/fake-clock.d.ts +15 -0
- package/dist/testing/fake-clock.js +86 -0
- package/dist/testing/fake-clock.js.map +1 -0
- package/dist/testing/fake-driver.d.ts +15 -0
- package/dist/testing/fake-driver.js +458 -0
- package/dist/testing/fake-driver.js.map +1 -0
- package/dist/testing/fake-fetch.d.ts +32 -0
- package/dist/testing/fake-fetch.js +81 -0
- package/dist/testing/fake-fetch.js.map +1 -0
- package/dist/testing/fake-plugin.d.ts +30 -0
- package/dist/testing/fake-plugin.js +66 -0
- package/dist/testing/fake-plugin.js.map +1 -0
- package/dist/testing/faulty-store.d.ts +36 -0
- package/dist/testing/faulty-store.js +66 -0
- package/dist/testing/faulty-store.js.map +1 -0
- package/dist/testing/generation.d.ts +60 -0
- package/dist/testing/generation.js +252 -0
- package/dist/testing/generation.js.map +1 -0
- package/dist/testing/index.d.ts +28 -0
- package/dist/testing/index.js +51 -0
- package/dist/testing/index.js.map +1 -0
- package/package.json +188 -45
- package/dist/libs/eth/account.d.ts +0 -9
- package/dist/libs/eth/account.js +0 -58
- package/dist/libs/eth/account.js.map +0 -1
- package/dist/libs/eth/contract.d.ts +0 -7
- package/dist/libs/eth/contract.js +0 -42
- package/dist/libs/eth/contract.js.map +0 -1
- package/dist/libs/eth/index.d.ts +0 -24
- package/dist/libs/eth/index.js +0 -72
- package/dist/libs/eth/index.js.map +0 -1
- package/dist/libs/eth/transact.d.ts +0 -7
- package/dist/libs/eth/transact.js +0 -26
- package/dist/libs/eth/transact.js.map +0 -1
- package/dist/libs/index.d.ts +0 -2
- package/dist/libs/index.js +0 -19
- package/dist/libs/index.js.map +0 -1
- package/dist/libs/trx/account.d.ts +0 -9
- package/dist/libs/trx/account.js +0 -55
- package/dist/libs/trx/account.js.map +0 -1
- package/dist/libs/trx/contract.d.ts +0 -7
- package/dist/libs/trx/contract.js +0 -27
- package/dist/libs/trx/contract.js.map +0 -1
- package/dist/libs/trx/index.d.ts +0 -22
- package/dist/libs/trx/index.js +0 -64
- package/dist/libs/trx/index.js.map +0 -1
- package/dist/libs/trx/transact.d.ts +0 -7
- package/dist/libs/trx/transact.js +0 -26
- package/dist/libs/trx/transact.js.map +0 -1
- package/dist/tool/common.d.ts +0 -28
- package/dist/tool/common.js +0 -33
- package/dist/tool/common.js.map +0 -1
- package/dist/tool/eth-tools.d.ts +0 -3
- package/dist/tool/eth-tools.js +0 -33
- package/dist/tool/eth-tools.js.map +0 -1
- package/dist/tool/index.d.ts +0 -5
- package/dist/tool/index.js +0 -22
- package/dist/tool/index.js.map +0 -1
- package/dist/tool/logging.d.ts +0 -3
- package/dist/tool/logging.js +0 -11
- package/dist/tool/logging.js.map +0 -1
- package/dist/tool/options.d.ts +0 -6
- package/dist/tool/options.js +0 -41
- package/dist/tool/options.js.map +0 -1
- package/dist/tool/trx-tools.d.ts +0 -3
- package/dist/tool/trx-tools.js +0 -20
- package/dist/tool/trx-tools.js.map +0 -1
- package/dist/type/account.d.ts +0 -9
- package/dist/type/account.js.map +0 -1
- package/dist/type/common.d.ts +0 -18
- package/dist/type/common.js.map +0 -1
- package/dist/type/contract.d.ts +0 -10
- package/dist/type/contract.js.map +0 -1
- package/dist/type/index.d.ts +0 -5
- package/dist/type/index.js +0 -22
- package/dist/type/index.js.map +0 -1
- package/dist/type/lib-types.d.ts +0 -9
- package/dist/type/lib-types.js.map +0 -1
- package/dist/type/transact.d.ts +0 -7
- package/dist/type/transact.js.map +0 -1
|
@@ -0,0 +1,813 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WALK_PAGES = exports.CONSUMER_PAGES = void 0;
|
|
4
|
+
exports.attestedHead = attestedHead;
|
|
5
|
+
exports.expiredAt = expiredAt;
|
|
6
|
+
exports.replayVerdict = replayVerdict;
|
|
7
|
+
exports.createTonProofs = createTonProofs;
|
|
8
|
+
exports.createTonHistory = createTonHistory;
|
|
9
|
+
/**
|
|
10
|
+
* Proofs and address history. Every proof attests a fact at its own height, with a
|
|
11
|
+
* monotone predicate or at a fixed block, and no endpoint proposes a height. The one
|
|
12
|
+
* exception is the unanchored head: one endpoint's masterchain head, trailed by
|
|
13
|
+
* `finalitySkewBlocks` and attested by a quorum read of that block, retried at the
|
|
14
|
+
* transport's own lag tolerance. Every lookup is bound to what it asked for: a header
|
|
15
|
+
* names the block asked, the shard tops cover the basechain, a state and a get-method
|
|
16
|
+
* name the block asked and the state read there.
|
|
17
|
+
*
|
|
18
|
+
* "Not included" rests only on authenticated chain data, never on an indexer's records: a
|
|
19
|
+
* lying or lagging indexer can miss a message that ran, and a `rebuild` on its word would
|
|
20
|
+
* pay twice. The proof reads, at an attested block where the message is expired, the
|
|
21
|
+
* account's own chain of transactions, as the liteserver serves their cells, each hashed
|
|
22
|
+
* here and linked by its `prev_trans` fields back from the attested state's last
|
|
23
|
+
* transaction. A wallet can be reset (deleted, or destroyed to uninitialized, then
|
|
24
|
+
* re-deployed from its public `StateInit` with seqno 0), so an activation, a destruction
|
|
25
|
+
* or a chain start inside what the proof must see decides nothing, unless the chain
|
|
26
|
+
* itself shows our transaction. Anything not yet decidable throws a retryable
|
|
27
|
+
* `PROVIDER_UNAVAILABLE`, and an answer the chain could not have produced a retryable
|
|
28
|
+
* `PROVIDER_INCONSISTENT`; both decide nothing.
|
|
29
|
+
*/
|
|
30
|
+
const core_1 = require("@ton/core");
|
|
31
|
+
const error_1 = require("../../core/errors/error");
|
|
32
|
+
const api_1 = require("./api");
|
|
33
|
+
const messages_1 = require("./messages");
|
|
34
|
+
const reader_1 = require("./reader");
|
|
35
|
+
const network_1 = require("./network");
|
|
36
|
+
const trace_1 = require("./trace");
|
|
37
|
+
const wallets_1 = require("./wallets");
|
|
38
|
+
/** How far back the consumer of a seqno is searched: pages of `CONSUMER_PAGE` transactions. */
|
|
39
|
+
exports.CONSUMER_PAGES = 8;
|
|
40
|
+
const CONSUMER_PAGE = 64;
|
|
41
|
+
/** How far the chain is walked: pages of `WALK_PAGE` transactions. */
|
|
42
|
+
exports.WALK_PAGES = 16;
|
|
43
|
+
const WALK_PAGE = 32;
|
|
44
|
+
/** How far an anchored indexer history is read: pages of `HISTORY_PAGE` transactions. */
|
|
45
|
+
const HISTORY_PAGES = 8;
|
|
46
|
+
const HISTORY_PAGE = 64;
|
|
47
|
+
/** toncenter v3 refuses a page of more rows ("limit is not allowed: 1001 > 1000", live). */
|
|
48
|
+
const HISTORY_PAGE_MAX = 1000;
|
|
49
|
+
/** A logical time is a u64; a history cursor is one, in decimal. */
|
|
50
|
+
const MAX_LT = (1n << 64n) - 1n;
|
|
51
|
+
const MAX_LT_DIGITS = 20;
|
|
52
|
+
/** A wallet seqno is a u32: any other number is no seqno. */
|
|
53
|
+
const MAX_WALLET_SEQNO = 0xffffffffn;
|
|
54
|
+
/** The shard id space of a workchain: 2^64 ids, which its shards partition. */
|
|
55
|
+
const SHARD_SPACE = 1n << 64n;
|
|
56
|
+
const undecided = (reason) => new error_1.ProviderError('PROVIDER_UNAVAILABLE', reason, { retryable: true });
|
|
57
|
+
const inconsistent = (reason) => new error_1.ProviderError('PROVIDER_INCONSISTENT', reason, { retryable: true });
|
|
58
|
+
/**
|
|
59
|
+
* The masterchain block `seqno`, attested by the proof quorum (ids, hashes, time, global
|
|
60
|
+
* id), and bound to the block asked: an answer about another block or network decides
|
|
61
|
+
* nothing.
|
|
62
|
+
*/
|
|
63
|
+
async function masterchainBlock(ctx, seqno) {
|
|
64
|
+
const header = await ctx.api.masterchainHeader(seqno, api_1.PROOF);
|
|
65
|
+
const { id } = header;
|
|
66
|
+
if (id.workchain !== -1 ||
|
|
67
|
+
id.shard !== api_1.MASTERCHAIN_SHARD ||
|
|
68
|
+
id.seqno !== seqno ||
|
|
69
|
+
header.globalId !== ctx.config.globalId) {
|
|
70
|
+
throw inconsistent('the endpoints answered another block than the one asked');
|
|
71
|
+
}
|
|
72
|
+
return header;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* The one unanchored head: one endpoint's head, trailed by the network's skew and
|
|
76
|
+
* attested by the quorum; when a healthy peer trails further, retried at the transport's
|
|
77
|
+
* lag tolerance, the furthest a proof endpoint may trail. Never a false head, only a
|
|
78
|
+
* later one.
|
|
79
|
+
*/
|
|
80
|
+
async function attestedHead(ctx) {
|
|
81
|
+
const head = await ctx.api.masterchainHead(api_1.MONITOR);
|
|
82
|
+
const skew = ctx.config.finalitySkewBlocks;
|
|
83
|
+
const lag = ctx.api.lagTolerance;
|
|
84
|
+
let last;
|
|
85
|
+
for (const trail of lag > skew ? [skew, lag] : [skew]) {
|
|
86
|
+
try {
|
|
87
|
+
return await masterchainBlock(ctx, Math.max(1, head - trail));
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
if (!(0, error_1.isCryptoAioError)(error) || !error.retryable)
|
|
91
|
+
throw error;
|
|
92
|
+
last = error;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
throw last;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Whether the basechain shards among `tops` partition its whole id space: a shard id is its
|
|
99
|
+
* prefix, then a 1 bit, then zeros, so it covers `id ± lowest set bit` (unsigned). A set that
|
|
100
|
+
* leaves a shard out would hide that shard's time.
|
|
101
|
+
*/
|
|
102
|
+
function coversBasechain(tops) {
|
|
103
|
+
const ranges = [];
|
|
104
|
+
for (const top of tops) {
|
|
105
|
+
if (top.workchain !== 0)
|
|
106
|
+
continue;
|
|
107
|
+
const id = BigInt.asUintN(64, BigInt(top.shard));
|
|
108
|
+
const half = id & -id;
|
|
109
|
+
if (half === 0n)
|
|
110
|
+
return false;
|
|
111
|
+
ranges.push([id - half, id + half]);
|
|
112
|
+
}
|
|
113
|
+
ranges.sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));
|
|
114
|
+
let next = 0n;
|
|
115
|
+
for (const [start, end] of ranges) {
|
|
116
|
+
if (start !== next)
|
|
117
|
+
return false;
|
|
118
|
+
next = end;
|
|
119
|
+
}
|
|
120
|
+
return next === SHARD_SPACE;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* The earliest chain time our message can have run at. The build recorded it
|
|
124
|
+
* (`TonSeqnoOrdering.validFrom`); less the builder's chain-time tolerance, it covers an
|
|
125
|
+
* endpoint whose time ran ahead of the chain within that tolerance, whatever the
|
|
126
|
+
* network's `validForSeconds` is now (a window from today's setting could start after an
|
|
127
|
+
* earlier run, and a reset wallet's history would then prove "not included" falsely).
|
|
128
|
+
* Without a well-formed record (an attempt built before it, or bytes this driver did not
|
|
129
|
+
* assemble), the widest lifetime any network allows before `validUntil`, less the
|
|
130
|
+
* tolerance.
|
|
131
|
+
* Known gap: an endpoint and the local clock both more than the tolerance ahead of the
|
|
132
|
+
* chain start the window too late; the host's clock must stay in sync.
|
|
133
|
+
*/
|
|
134
|
+
function windowStartOf(slot) {
|
|
135
|
+
const recorded = (0, network_1.recordedValidFrom)(slot);
|
|
136
|
+
return (recorded ?? slot.validUntil - network_1.MAX_VALID_FOR_SECONDS) - network_1.CHAIN_TIME_TOLERANCE;
|
|
137
|
+
}
|
|
138
|
+
/** A lifetime is a positive chain time; the reservation's placeholder 0 is none. */
|
|
139
|
+
const hasLifetime = (validUntil) => Number.isSafeInteger(validUntil) && validUntil > 0;
|
|
140
|
+
/**
|
|
141
|
+
* No block after `header` can include a message valid until `validUntil`: the
|
|
142
|
+
* masterchain block and every shard top it commits are at least that old, every later block
|
|
143
|
+
* of a shard is younger than its top (the collator's `now` rises), and a wallet rejects a
|
|
144
|
+
* message once `valid_until <= now()`. The shard tops are asked for the attested block's
|
|
145
|
+
* seqno; toncenter's answer names no block (live), so only the proof quorum binds the list
|
|
146
|
+
* to it, and it must cover the basechain. Each top's header is read under the quorum
|
|
147
|
+
* and bound to the id the list gives. A lifetime that is no time decides nothing.
|
|
148
|
+
*/
|
|
149
|
+
async function expiredAt(ctx, header, validUntil) {
|
|
150
|
+
if (!hasLifetime(validUntil))
|
|
151
|
+
throw undecided('a TON attempt needs its lifetime');
|
|
152
|
+
if (validUntil > header.genUtime)
|
|
153
|
+
return false;
|
|
154
|
+
const tops = await ctx.api.shards(header.id.seqno, api_1.PROOF);
|
|
155
|
+
if (!coversBasechain(tops)) {
|
|
156
|
+
throw inconsistent('the shard tops do not cover the basechain');
|
|
157
|
+
}
|
|
158
|
+
for (const top of tops) {
|
|
159
|
+
const shard = await ctx.api.blockHeader(top, api_1.PROOF);
|
|
160
|
+
if (!(0, api_1.sameBlock)(shard.id, top) || shard.globalId !== ctx.config.globalId) {
|
|
161
|
+
throw inconsistent('the endpoints answered another shard block than the one asked');
|
|
162
|
+
}
|
|
163
|
+
if (validUntil > shard.genUtime)
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
return true;
|
|
167
|
+
}
|
|
168
|
+
/** The seqno a `seqno` get-method answers; undefined when it answers none. */
|
|
169
|
+
function seqnoIn(result) {
|
|
170
|
+
const first = result.stack[0];
|
|
171
|
+
return result.exitCode === 0 &&
|
|
172
|
+
first?.type === 'num' &&
|
|
173
|
+
first.value >= 0n &&
|
|
174
|
+
first.value <= MAX_WALLET_SEQNO
|
|
175
|
+
? first.value
|
|
176
|
+
: undefined;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* The account state at the attested block `head`, bound to it: the block the
|
|
180
|
+
* answer names is `head`, its workchain, shard, seqno and hashes.
|
|
181
|
+
*/
|
|
182
|
+
async function stateAt(ctx, wallet, head) {
|
|
183
|
+
const state = await ctx.api.account(wallet, api_1.PROOF, head.id.seqno);
|
|
184
|
+
if (!(0, api_1.sameBlock)(state.block, head.id)) {
|
|
185
|
+
throw inconsistent('the endpoints answered the state at another block');
|
|
186
|
+
}
|
|
187
|
+
return state;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* The wallet's seqno in the attested `state`: the get-method's answer must name the
|
|
191
|
+
* attested block and the state's last transaction, so it is the state whose status was
|
|
192
|
+
* read, never an endpoint's latest one. The quorum key is the seqno and that binding, as
|
|
193
|
+
* parsed values, so formatting never splits the quorum; it never throws.
|
|
194
|
+
*/
|
|
195
|
+
async function seqnoAt(ctx, wallet, head, state) {
|
|
196
|
+
const bound = (result) => (0, api_1.sameBlock)(result.block, head.id) &&
|
|
197
|
+
result.lastTransaction.lt === state.lastLt &&
|
|
198
|
+
result.lastTransaction.hash === state.lastHash;
|
|
199
|
+
const key = (body) => {
|
|
200
|
+
try {
|
|
201
|
+
const result = (0, api_1.boundRunResultOf)(body);
|
|
202
|
+
return { seqno: seqnoIn(result)?.toString() ?? null, bound: bound(result) };
|
|
203
|
+
}
|
|
204
|
+
catch {
|
|
205
|
+
return 'malformed';
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
const result = await ctx.api.runGetMethodAt(wallet, 'seqno', [], { ...api_1.PROOF, quorumKey: key }, head.id.seqno);
|
|
209
|
+
if (!bound(result)) {
|
|
210
|
+
throw inconsistent('the seqno was read at another state than the attested one');
|
|
211
|
+
}
|
|
212
|
+
return seqnoIn(result);
|
|
213
|
+
}
|
|
214
|
+
/** An Attempt id (a 32-byte hash in hex, either case) in lower case; undefined otherwise. */
|
|
215
|
+
const attemptId = (id) => /^[0-9a-fA-F]{64}$/.test(id) ? id.toLowerCase() : undefined;
|
|
216
|
+
/**
|
|
217
|
+
* A positive-path hint only: the wallet transaction the indexer lists as the consumer of
|
|
218
|
+
* `seqno`, searched newest-first below the wallet's last transaction at the attested
|
|
219
|
+
* block `head`, on the indexer's pages as served. Only a proven request counts
|
|
220
|
+
* (`provenRequest`), and one whose request had expired by its transaction's time
|
|
221
|
+
* contradicts the chain. The caller takes it only when it is our own; it is never the
|
|
222
|
+
* basis of "not included". `undefined` when none is indexed.
|
|
223
|
+
*/
|
|
224
|
+
async function consumerOf(ctx, from, seqno, head, state) {
|
|
225
|
+
const keyAtHead = (0, reader_1.publicKeyAt)(ctx, from, api_1.PROOF, head.id, state);
|
|
226
|
+
const key = () => keyAtHead();
|
|
227
|
+
let endLt = state.lastLt;
|
|
228
|
+
for (let page = 0; page < exports.CONSUMER_PAGES; page++) {
|
|
229
|
+
const { transactions, next } = await ctx.api.accountTransactionsPage(from, { limit: CONSUMER_PAGE, endLt }, api_1.PROOF);
|
|
230
|
+
for (const tx of transactions) {
|
|
231
|
+
const request = await (0, reader_1.provenRequest)(ctx, tx, from, key);
|
|
232
|
+
if (!request)
|
|
233
|
+
continue;
|
|
234
|
+
const claimed = BigInt(request.seqno);
|
|
235
|
+
if (claimed > seqno)
|
|
236
|
+
continue;
|
|
237
|
+
if (claimed < seqno)
|
|
238
|
+
return undefined;
|
|
239
|
+
if (request.validUntil <= tx.now) {
|
|
240
|
+
throw inconsistent('the seqno consumer ran after its request expired');
|
|
241
|
+
}
|
|
242
|
+
return tx;
|
|
243
|
+
}
|
|
244
|
+
if (next === undefined)
|
|
245
|
+
return undefined;
|
|
246
|
+
endLt = next;
|
|
247
|
+
}
|
|
248
|
+
ctx.log.warn('the seqno consumer is beyond the search window', {
|
|
249
|
+
code: 'SEQNO_CONSUMER_NOT_FOUND',
|
|
250
|
+
});
|
|
251
|
+
return undefined;
|
|
252
|
+
}
|
|
253
|
+
// ---- the account's own chain --------------------------------------------------------------
|
|
254
|
+
const hex256 = (value) => value.toString(16).padStart(64, '0');
|
|
255
|
+
/**
|
|
256
|
+
* A transaction the liteserver served, authenticated: its cell (capped by the API before
|
|
257
|
+
* this decodes it) hashes to the id expected, and it is the account's own at the lt
|
|
258
|
+
* expected. Anything else is not the chain's.
|
|
259
|
+
*/
|
|
260
|
+
const notTheChains = () => inconsistent("the liteserver answered a transaction that is not the chain's");
|
|
261
|
+
function authenticated(row, expected, account) {
|
|
262
|
+
if (row.lt !== expected.lt || row.hash !== expected.hash)
|
|
263
|
+
throw notTheChains();
|
|
264
|
+
let cell;
|
|
265
|
+
let tx;
|
|
266
|
+
try {
|
|
267
|
+
const cells = core_1.Cell.fromBoc(Buffer.from(row.boc, 'base64'));
|
|
268
|
+
if (cells.length !== 1)
|
|
269
|
+
throw notTheChains();
|
|
270
|
+
cell = cells[0];
|
|
271
|
+
tx = (0, core_1.loadTransaction)(cell.beginParse());
|
|
272
|
+
}
|
|
273
|
+
catch {
|
|
274
|
+
throw notTheChains();
|
|
275
|
+
}
|
|
276
|
+
if (cell.hash().toString('hex') !== expected.hash ||
|
|
277
|
+
tx.lt !== expected.lt ||
|
|
278
|
+
tx.address !== account) {
|
|
279
|
+
throw notTheChains();
|
|
280
|
+
}
|
|
281
|
+
return tx;
|
|
282
|
+
}
|
|
283
|
+
/** The most transactions one walk visits, fetched or kept: `WALK_PAGES` full pages. */
|
|
284
|
+
const WALK_LIMIT = exports.WALK_PAGES * WALK_PAGE;
|
|
285
|
+
/**
|
|
286
|
+
* The account's chain from `from` back, one authenticated transaction at a time, each naming
|
|
287
|
+
* the next by its `prev_trans_lt`/`prev_trans_hash`; `visit` returns true to stop. Ends at
|
|
288
|
+
* the chain's start (`prev_trans_lt` 0: the account's first transaction, or its first since
|
|
289
|
+
* a deletion, transaction.cpp `init_new`), or after `WALK_LIMIT` transactions or
|
|
290
|
+
* `WALK_PAGES` pages. The replay guard walks before every resend, so a transaction
|
|
291
|
+
* authenticated once is kept by its id (`chainTxs`), and a walk fetches only the part of
|
|
292
|
+
* the chain it has not seen; a kept one is bound to the account as a fetched one is.
|
|
293
|
+
*/
|
|
294
|
+
async function walkChain(ctx, wallet, from, visit) {
|
|
295
|
+
const account = BigInt(`0x${wallet.slice(wallet.indexOf(':') + 1)}`);
|
|
296
|
+
let expected = from;
|
|
297
|
+
let page = [];
|
|
298
|
+
let fetched = 0;
|
|
299
|
+
for (let visited = 0; visited < WALK_LIMIT; visited++) {
|
|
300
|
+
const key = `${expected.lt}:${expected.hash}`;
|
|
301
|
+
const row = page.shift();
|
|
302
|
+
let tx = ctx.chainTxs.get(key);
|
|
303
|
+
if (tx !== undefined) {
|
|
304
|
+
if (tx.address !== account)
|
|
305
|
+
throw notTheChains();
|
|
306
|
+
// The page fetched earlier no longer follows the walk: drop it.
|
|
307
|
+
if (row !== undefined && (row.lt !== expected.lt || row.hash !== expected.hash)) {
|
|
308
|
+
page = [];
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
else {
|
|
312
|
+
let next = row;
|
|
313
|
+
if (next === undefined) {
|
|
314
|
+
if (fetched === exports.WALK_PAGES)
|
|
315
|
+
return 'exhausted';
|
|
316
|
+
fetched += 1;
|
|
317
|
+
page = await ctx.api.rawTransactions(wallet, expected, WALK_PAGE, api_1.PROOF);
|
|
318
|
+
next = page.shift();
|
|
319
|
+
if (next === undefined) {
|
|
320
|
+
throw undecided('the liteserver does not hold the transaction asked');
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
tx = authenticated(next, expected, account);
|
|
324
|
+
// Only a wallet-sized transaction is kept (a lying endpoint's is not): the memo
|
|
325
|
+
// stays bounded.
|
|
326
|
+
if (next.boc.length <= reader_1.MEMO_TX_LENGTH)
|
|
327
|
+
(0, reader_1.keep)(ctx.chainTxs, key, tx, reader_1.CHAIN_MEMO);
|
|
328
|
+
}
|
|
329
|
+
if (await visit(tx, expected.hash))
|
|
330
|
+
return 'stopped';
|
|
331
|
+
if (tx.prevTransactionLt === 0n)
|
|
332
|
+
return 'start';
|
|
333
|
+
expected = { lt: tx.prevTransactionLt, hash: hex256(tx.prevTransactionHash) };
|
|
334
|
+
}
|
|
335
|
+
return 'exhausted';
|
|
336
|
+
}
|
|
337
|
+
const CODE = new Set(['active', 'frozen']);
|
|
338
|
+
const NO_CODE = new Set(['uninitialized', 'non-existing']);
|
|
339
|
+
/** What a transaction did, as the chain records it. */
|
|
340
|
+
function phasesOf(tx) {
|
|
341
|
+
const d = tx.description;
|
|
342
|
+
const compute = 'computePhase' in d ? d.computePhase : undefined;
|
|
343
|
+
const vm = compute?.type === 'vm' ? compute : undefined;
|
|
344
|
+
return {
|
|
345
|
+
/** The wallet's code ran: the chain runs it only when code exists or a StateInit
|
|
346
|
+
* activates the account (transaction.cpp). */
|
|
347
|
+
ran: vm !== undefined,
|
|
348
|
+
/** A request ran to the end, so a seqno moved (the action phase keeps it). */
|
|
349
|
+
consumed: d.type === 'generic' && vm?.success === true && d.actionPhase?.success === true,
|
|
350
|
+
/** The account had code before or after. */
|
|
351
|
+
lived: CODE.has(tx.oldStatus) || CODE.has(tx.endStatus),
|
|
352
|
+
/** A re-deploy from no code: the seqno starts again (transaction.cpp activation). */
|
|
353
|
+
activation: NO_CODE.has(tx.oldStatus) && tx.endStatus === 'active',
|
|
354
|
+
/** The code went (+32 destroy, storage deletion): the seqno goes with it. */
|
|
355
|
+
destruction: (CODE.has(tx.oldStatus) && NO_CODE.has(tx.endStatus)) ||
|
|
356
|
+
('destroyed' in d && d.destroyed),
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* The seqno a request the wallet ran claims, read from its signed header alone (so a
|
|
361
|
+
* v4r2 plugin request or a W5 extended-action request counts too): an external request, or
|
|
362
|
+
* a W5 `internal_signed` one, signed by the wallet's key for this very wallet
|
|
363
|
+
* (`requestIsOwn`: a v5r1 wallet runs a forged relayed body and ignores it).
|
|
364
|
+
*/
|
|
365
|
+
async function claimedSeqno(ctx, wallet, message, key) {
|
|
366
|
+
if (!message)
|
|
367
|
+
return undefined;
|
|
368
|
+
const { body } = message;
|
|
369
|
+
const op = body.bits.length >= 32 ? body.beginParse().preloadUint(32) : undefined;
|
|
370
|
+
const w5 = op === messages_1.OP.w5SignedExternal || op === messages_1.OP.w5SignedInternal;
|
|
371
|
+
if (message.info.type === 'internal'
|
|
372
|
+
? op !== messages_1.OP.w5SignedInternal
|
|
373
|
+
: message.info.type !== 'external-in') {
|
|
374
|
+
return undefined;
|
|
375
|
+
}
|
|
376
|
+
let seqno;
|
|
377
|
+
try {
|
|
378
|
+
const s = body.beginParse();
|
|
379
|
+
// W5: op, wallet id, valid_until, seqno; v4r2: signature, subwallet id, valid_until, seqno.
|
|
380
|
+
s.skip(w5 ? 32 + 32 + 32 : 512 + 32 + 32);
|
|
381
|
+
seqno = s.loadUint(32);
|
|
382
|
+
}
|
|
383
|
+
catch {
|
|
384
|
+
return undefined;
|
|
385
|
+
}
|
|
386
|
+
const publicKey = await key();
|
|
387
|
+
return publicKey && (0, wallets_1.requestIsOwn)(wallet, body, publicKey, ctx.config.globalId)
|
|
388
|
+
? BigInt(seqno)
|
|
389
|
+
: undefined;
|
|
390
|
+
}
|
|
391
|
+
const resetSuspected = (ctx) => {
|
|
392
|
+
ctx.log.warn('the wallet may have been reset since our message', {
|
|
393
|
+
code: 'WALLET_RESET_SUSPECTED',
|
|
394
|
+
});
|
|
395
|
+
return undecided('the wallet may have been reset since our message');
|
|
396
|
+
};
|
|
397
|
+
const walkExhausted = (ctx) => {
|
|
398
|
+
ctx.log.warn('the wallet history is beyond the proof window', {
|
|
399
|
+
code: 'TX_CHAIN_WALK_EXHAUSTED',
|
|
400
|
+
});
|
|
401
|
+
return undecided('the wallet history is beyond the proof window');
|
|
402
|
+
};
|
|
403
|
+
/**
|
|
404
|
+
* The wallet's code never ran in the history the indexer holds
|
|
405
|
+
* below lt `below` (an earlier incarnation, before a chain start), or in all of it when
|
|
406
|
+
* `below` is undefined (no chain now: never created, or deleted with its last transaction),
|
|
407
|
+
* read under the proof quorum once the indexer has indexed masterchain block `reached`: no
|
|
408
|
+
* compute phase that ran, and no status with code. Our message runs only in the wallet's
|
|
409
|
+
* code, so an incarnation whose code never ran cannot hold it, whether the wallet is active
|
|
410
|
+
* or uninitialized now (a deposit that bounced before the wallet existed is no reset).
|
|
411
|
+
* A row where the code ran, a row without its statuses, or a history past the window
|
|
412
|
+
* decides nothing.
|
|
413
|
+
*/
|
|
414
|
+
async function codeNeverRan(ctx, wallet, reached, below) {
|
|
415
|
+
if (!(await ctx.api.indexerReached(reached, api_1.PROOF))) {
|
|
416
|
+
throw undecided('the indexer has not reached the attested block yet');
|
|
417
|
+
}
|
|
418
|
+
let endLt = below === undefined ? undefined : below - 1n;
|
|
419
|
+
for (let page = 0; page < HISTORY_PAGES; page++) {
|
|
420
|
+
const { transactions, next } = await ctx.api.accountTransactionsPage(wallet, { limit: HISTORY_PAGE, ...(endLt !== undefined ? { endLt } : {}) }, api_1.PROOF);
|
|
421
|
+
for (const tx of transactions) {
|
|
422
|
+
const { origStatus, endStatus } = tx;
|
|
423
|
+
if (!tx.compute.skipped ||
|
|
424
|
+
origStatus === undefined ||
|
|
425
|
+
endStatus === undefined ||
|
|
426
|
+
origStatus === 'active' ||
|
|
427
|
+
origStatus === 'frozen' ||
|
|
428
|
+
endStatus === 'active' ||
|
|
429
|
+
endStatus === 'frozen') {
|
|
430
|
+
throw resetSuspected(ctx);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
if (next === undefined)
|
|
434
|
+
return;
|
|
435
|
+
endLt = next;
|
|
436
|
+
}
|
|
437
|
+
throw walkExhausted(ctx);
|
|
438
|
+
}
|
|
439
|
+
/**
|
|
440
|
+
* At an attested block where the message is expired, whether our message
|
|
441
|
+
* consumed its seqno, from the account's own chain alone, walked back from the attested
|
|
442
|
+
* state's last transaction:
|
|
443
|
+
* - our message (its TEP-467 hash computed here) run to the end: ours, proven by the caller;
|
|
444
|
+
* - otherwise "absent" only when the chain shows no reset: the walk reaches the earliest
|
|
445
|
+
* time our message could have run (`windowStart`, from the attempt's own record) with,
|
|
446
|
+
* when our seqno is consumed at `head`, its consumer found (another request, by its
|
|
447
|
+
* signed header); or it reaches the chain's start inside that window, and the anchored
|
|
448
|
+
* indexer history shows that the code never ran before it.
|
|
449
|
+
* An activation, a destruction, or a consumer of a lower seqno first is a reset: from then
|
|
450
|
+
* on the wallet must never have run, as far as the chain goes back into the window; a walk
|
|
451
|
+
* past its cap decides nothing. An uninitialized wallet must never have run in the
|
|
452
|
+
* window (our message cannot have run before it), nor, without a chain, at all.
|
|
453
|
+
*/
|
|
454
|
+
async function fromTheChain(ctx, q) {
|
|
455
|
+
const needConsumer = q.active && q.seqno > q.slot.seqno;
|
|
456
|
+
if (q.state.lastLt === 0n) {
|
|
457
|
+
// No chain at `head`: never created, or deleted with its last transaction.
|
|
458
|
+
if (q.active)
|
|
459
|
+
throw inconsistent('an active account without a transaction');
|
|
460
|
+
await codeNeverRan(ctx, q.wallet, q.head.id.seqno);
|
|
461
|
+
return { absent: true };
|
|
462
|
+
}
|
|
463
|
+
const windowStart = windowStartOf(q.slot);
|
|
464
|
+
const key = (0, reader_1.publicKeyAt)(ctx, q.wallet, api_1.PROOF, q.head.id, q.state);
|
|
465
|
+
let codeless = !q.active;
|
|
466
|
+
let consumerFound = false;
|
|
467
|
+
let reset = false;
|
|
468
|
+
let ours;
|
|
469
|
+
let first = q.state.lastLt;
|
|
470
|
+
const end = await walkChain(ctx, q.wallet, { lt: q.state.lastLt, hash: q.state.lastHash }, async (tx, hash) => {
|
|
471
|
+
first = tx.lt;
|
|
472
|
+
const t = phasesOf(tx);
|
|
473
|
+
const inbound = tx.inMessage;
|
|
474
|
+
if (ourRun(tx, t, q.wallet, q.id)) {
|
|
475
|
+
ours = hash;
|
|
476
|
+
return true;
|
|
477
|
+
}
|
|
478
|
+
if (tx.now < windowStart && (!needConsumer || consumerFound))
|
|
479
|
+
return true;
|
|
480
|
+
if (codeless) {
|
|
481
|
+
if (t.ran || t.lived || t.destruction)
|
|
482
|
+
reset = true;
|
|
483
|
+
return false;
|
|
484
|
+
}
|
|
485
|
+
if (t.destruction)
|
|
486
|
+
reset = true;
|
|
487
|
+
if (needConsumer && !consumerFound && t.consumed) {
|
|
488
|
+
const claimed = await claimedSeqno(ctx, q.wallet, inbound, key);
|
|
489
|
+
if (claimed === q.slot.seqno)
|
|
490
|
+
consumerFound = true;
|
|
491
|
+
else if (claimed !== undefined && claimed < q.slot.seqno)
|
|
492
|
+
reset = true;
|
|
493
|
+
}
|
|
494
|
+
if (t.activation) {
|
|
495
|
+
if (needConsumer && !consumerFound)
|
|
496
|
+
reset = true;
|
|
497
|
+
codeless = true;
|
|
498
|
+
}
|
|
499
|
+
return false;
|
|
500
|
+
});
|
|
501
|
+
if (ours !== undefined)
|
|
502
|
+
return { ours };
|
|
503
|
+
if (end === 'exhausted')
|
|
504
|
+
throw walkExhausted(ctx);
|
|
505
|
+
if (reset || (needConsumer && !consumerFound))
|
|
506
|
+
throw resetSuspected(ctx);
|
|
507
|
+
if (end === 'start')
|
|
508
|
+
await codeNeverRan(ctx, q.wallet, q.head.id.seqno, first);
|
|
509
|
+
return { absent: true };
|
|
510
|
+
}
|
|
511
|
+
/**
|
|
512
|
+
* Whether `tx` is our message run to the end: its inbound external message's TEP-467 hash,
|
|
513
|
+
* computed here from the authenticated body, is `id`, and it consumed its seqno.
|
|
514
|
+
*/
|
|
515
|
+
function ourRun(tx, t, wallet, id) {
|
|
516
|
+
const inbound = tx.inMessage;
|
|
517
|
+
return (t.consumed &&
|
|
518
|
+
inbound?.info.type === 'external-in' &&
|
|
519
|
+
(0, wallets_1.externalHashOf)(wallet, inbound.body) === id);
|
|
520
|
+
}
|
|
521
|
+
/**
|
|
522
|
+
* The monotone predicate "my seqno is above `seqno`" at the endpoints' own states, under the
|
|
523
|
+
* proof quorum; its key is the verdict itself and never throws.
|
|
524
|
+
*/
|
|
525
|
+
async function seqnoAbove(ctx, wallet, seqno) {
|
|
526
|
+
const above = (result) => {
|
|
527
|
+
const value = seqnoIn(result);
|
|
528
|
+
return value !== undefined && value > seqno;
|
|
529
|
+
};
|
|
530
|
+
const key = (body) => {
|
|
531
|
+
try {
|
|
532
|
+
return above((0, api_1.runResultOf)(body));
|
|
533
|
+
}
|
|
534
|
+
catch {
|
|
535
|
+
return 'malformed';
|
|
536
|
+
}
|
|
537
|
+
};
|
|
538
|
+
return above(await ctx.api.runGetMethod(wallet, 'seqno', [], { ...api_1.PROOF, quorumKey: key }));
|
|
539
|
+
}
|
|
540
|
+
/**
|
|
541
|
+
* Whether stored bytes may go out again. A wallet reset (a deletion, then a deposit,
|
|
542
|
+
* or a re-deploy from the public `StateInit` back to our seqno) makes a message that already
|
|
543
|
+
* ran and paid runnable again while it is valid, so every send of stored bytes asks first:
|
|
544
|
+
* - `send`: the wallet's seqno is already above ours under the proof quorum, so the message
|
|
545
|
+
* cannot run (no walk); or the chain shows it cannot have run: the walk reaches the
|
|
546
|
+
* earliest time it could have run (`windowStartOf`, from the recorded build time, else
|
|
547
|
+
* the widest lifetime) with no reset, or a chain start whose earlier history shows the
|
|
548
|
+
* code never ran (a wallet funded a minute ago is sent to);
|
|
549
|
+
* - `ours`: the chain holds our message run to the end: it must never be sent again.
|
|
550
|
+
* The walk starts from the freshest state an endpoint serves (the attested head trails it
|
|
551
|
+
* by 10 to 150 blocks, and a reset in that trail is exactly the danger), and must lead
|
|
552
|
+
* down to the attested state's last transaction, so a lying fresh endpoint can hide only
|
|
553
|
+
* what the attested walk could not see either. Anything else, including a deletion or a
|
|
554
|
+
* new chain since the attested head, an activation or a destruction in the window, a walk
|
|
555
|
+
* past its cap, an indexer behind the fresh block or a failed read, throws a retryable
|
|
556
|
+
* error: the guard never sends while it cannot decide, and the proof decides.
|
|
557
|
+
* Known gap: once a wallet is reset (which takes software that shares its key), anyone
|
|
558
|
+
* can replay our message from the chain's public record; no client can stop that, and the
|
|
559
|
+
* guard covers only this library's own sends.
|
|
560
|
+
*/
|
|
561
|
+
async function replayVerdict(ctx, message) {
|
|
562
|
+
const { wallet, id } = message;
|
|
563
|
+
// A seqno past ours needs no walk. A failed read is only "not known".
|
|
564
|
+
const past = await seqnoAbove(ctx, wallet, message.seqno).catch(() => false);
|
|
565
|
+
if (past)
|
|
566
|
+
return 'send';
|
|
567
|
+
const windowStart = windowStartOf(message);
|
|
568
|
+
const head = await attestedHead(ctx);
|
|
569
|
+
const attested = await stateAt(ctx, wallet, head);
|
|
570
|
+
const fresh = await ctx.api.account(wallet, api_1.MONITOR);
|
|
571
|
+
// An endpoint behind the attested head adds nothing; one past it must agree with it.
|
|
572
|
+
const top = fresh.blockSeqno > head.id.seqno ? fresh : attested;
|
|
573
|
+
if (top === fresh) {
|
|
574
|
+
if (fresh.lastLt === attested.lastLt
|
|
575
|
+
? fresh.lastHash !== attested.lastHash
|
|
576
|
+
: fresh.lastLt < attested.lastLt && fresh.lastLt !== 0n) {
|
|
577
|
+
throw inconsistent('the freshest state does not follow the attested one');
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
if (top.status === 'frozen')
|
|
581
|
+
throw undecided('the wallet state does not show its seqno');
|
|
582
|
+
// The account was deleted since the attested head: our message may have run just before.
|
|
583
|
+
if (top.lastLt === 0n && attested.lastLt !== 0n)
|
|
584
|
+
throw resetSuspected(ctx);
|
|
585
|
+
if (top.lastLt === 0n) {
|
|
586
|
+
// No chain now, nor at the attested head: never created, or deleted long ago.
|
|
587
|
+
await codeNeverRan(ctx, wallet, top.blockSeqno);
|
|
588
|
+
return 'send';
|
|
589
|
+
}
|
|
590
|
+
// The fresh part of the chain must lead to the attested state's last transaction.
|
|
591
|
+
const link = top !== attested && attested.lastLt !== 0n ? attested : undefined;
|
|
592
|
+
let linked = link === undefined || link.lastLt === top.lastLt;
|
|
593
|
+
let codeless = top.status !== 'active';
|
|
594
|
+
let reset = false;
|
|
595
|
+
let ours = false;
|
|
596
|
+
let first = top.lastLt;
|
|
597
|
+
const end = await walkChain(ctx, wallet, { lt: top.lastLt, hash: top.lastHash }, async (tx, hash) => {
|
|
598
|
+
first = tx.lt;
|
|
599
|
+
if (!linked && link !== undefined) {
|
|
600
|
+
if (tx.lt < link.lastLt || (tx.lt === link.lastLt && hash !== link.lastHash)) {
|
|
601
|
+
throw inconsistent('the freshest state does not follow the attested one');
|
|
602
|
+
}
|
|
603
|
+
linked = tx.lt === link.lastLt;
|
|
604
|
+
}
|
|
605
|
+
const t = phasesOf(tx);
|
|
606
|
+
if (ourRun(tx, t, wallet, id)) {
|
|
607
|
+
ours = true;
|
|
608
|
+
return true;
|
|
609
|
+
}
|
|
610
|
+
if (linked && tx.now < windowStart)
|
|
611
|
+
return true;
|
|
612
|
+
if (codeless) {
|
|
613
|
+
if (t.ran || t.lived || t.destruction)
|
|
614
|
+
reset = true;
|
|
615
|
+
return false;
|
|
616
|
+
}
|
|
617
|
+
if (t.destruction)
|
|
618
|
+
reset = true;
|
|
619
|
+
if (t.activation)
|
|
620
|
+
codeless = true;
|
|
621
|
+
return false;
|
|
622
|
+
});
|
|
623
|
+
if (ours)
|
|
624
|
+
return 'ours';
|
|
625
|
+
if (end === 'exhausted')
|
|
626
|
+
throw walkExhausted(ctx);
|
|
627
|
+
// Not linked at the chain's start: a new chain since the attested head, so a deletion.
|
|
628
|
+
if (reset || !linked)
|
|
629
|
+
throw resetSuspected(ctx);
|
|
630
|
+
if (end === 'start')
|
|
631
|
+
await codeNeverRan(ctx, wallet, top.blockSeqno, first);
|
|
632
|
+
return 'send';
|
|
633
|
+
}
|
|
634
|
+
/**
|
|
635
|
+
* Our indexed transaction that consumed its seqno, proven: a complete trace, whose last
|
|
636
|
+
* block the endpoints attest they hold, and the verdict, its jetton wallets confirmed at
|
|
637
|
+
* that block under the proof quorum.
|
|
638
|
+
*/
|
|
639
|
+
async function proveIncluded(ctx, tx, from) {
|
|
640
|
+
const trace = await ctx.api.trace(tx.hash, api_1.PROOF);
|
|
641
|
+
if (!trace || !trace.complete)
|
|
642
|
+
throw undecided('the message trace is not complete yet');
|
|
643
|
+
const last = (0, reader_1.traceBlock)(tx, trace);
|
|
644
|
+
if (!(await ctx.api.reachedMasterchain(last, api_1.PROOF))) {
|
|
645
|
+
throw undecided('the endpoints have not reached the trace yet');
|
|
646
|
+
}
|
|
647
|
+
const verdict = await (0, reader_1.confirmLegs)(ctx, (0, trace_1.attemptVerdict)(tx, trace), from, api_1.PROOF, last);
|
|
648
|
+
if (verdict.kind === 'pending')
|
|
649
|
+
throw undecided('the message trace is not complete yet');
|
|
650
|
+
const header = await masterchainBlock(ctx, tx.mcSeqno);
|
|
651
|
+
return {
|
|
652
|
+
included: true,
|
|
653
|
+
success: verdict.kind === 'success',
|
|
654
|
+
blockHeight: BigInt(tx.mcSeqno),
|
|
655
|
+
blockHash: header.id.rootHash,
|
|
656
|
+
txHash: tx.hash,
|
|
657
|
+
...(verdict.kind === 'failed' ? { reason: verdict.reason } : {}),
|
|
658
|
+
};
|
|
659
|
+
}
|
|
660
|
+
/**
|
|
661
|
+
* Our transaction the chain itself holds (`hash`), proven through the indexer's record of
|
|
662
|
+
* that very transaction, which must be our message and have consumed its seqno.
|
|
663
|
+
*/
|
|
664
|
+
async function proveOurs(ctx, hash, wallet, id) {
|
|
665
|
+
const record = await ctx.api.transaction(hash, api_1.PROOF);
|
|
666
|
+
if (!record)
|
|
667
|
+
throw undecided('our transaction is not indexed yet');
|
|
668
|
+
if (!(0, trace_1.isOwnAttempt)(record, wallet, id) || !(0, trace_1.consumesSeqno)(record)) {
|
|
669
|
+
throw inconsistent("the indexer's record is not the chain's transaction");
|
|
670
|
+
}
|
|
671
|
+
return proveIncluded(ctx, record, wallet);
|
|
672
|
+
}
|
|
673
|
+
const seqnoOrdering = (ordering) => ordering.kind === 'seqno' ? ordering : undefined;
|
|
674
|
+
function createTonProofs(ctx) {
|
|
675
|
+
const { api } = ctx;
|
|
676
|
+
const walletOf = (from) => ctx.codec.normalize(from).canonical;
|
|
677
|
+
return {
|
|
678
|
+
async finalizedHead() {
|
|
679
|
+
const header = await attestedHead(ctx);
|
|
680
|
+
return {
|
|
681
|
+
height: BigInt(header.id.seqno),
|
|
682
|
+
hash: header.id.rootHash,
|
|
683
|
+
timestamp: header.genUtime,
|
|
684
|
+
};
|
|
685
|
+
},
|
|
686
|
+
async includedFinal(ref, ordering, from) {
|
|
687
|
+
const wallet = walletOf(from);
|
|
688
|
+
// Only our own wallet transaction, its hash computed here from the bound body. A
|
|
689
|
+
// run that did not consume its seqno (a failed action phase) moved nothing and may
|
|
690
|
+
// run again until the message expires: only the seqno decides it.
|
|
691
|
+
const own = await (0, reader_1.findOwnAttempt)(ctx, ref, wallet, api_1.PROOF);
|
|
692
|
+
if (own && (0, trace_1.consumesSeqno)(own))
|
|
693
|
+
return proveIncluded(ctx, own, wallet);
|
|
694
|
+
const id = attemptId(ref.id);
|
|
695
|
+
if (id === undefined)
|
|
696
|
+
throw undecided('a TON attempt needs its message hash');
|
|
697
|
+
const slot = seqnoOrdering(ordering);
|
|
698
|
+
if (!slot)
|
|
699
|
+
throw undecided('a TON attempt needs its seqno ordering');
|
|
700
|
+
if (!hasLifetime(slot.validUntil))
|
|
701
|
+
throw undecided('a TON attempt needs its lifetime');
|
|
702
|
+
// Not proven under our hash: decide only from state at an attested block.
|
|
703
|
+
const head = await attestedHead(ctx);
|
|
704
|
+
const state = await stateAt(ctx, wallet, head);
|
|
705
|
+
const active = state.status === 'active';
|
|
706
|
+
// A frozen wallet, or an uninitialized one past seqno 0, shows no seqno (never 0).
|
|
707
|
+
if (!active && (state.status === 'frozen' || slot.seqno !== 0n)) {
|
|
708
|
+
throw undecided('the wallet state does not show its seqno');
|
|
709
|
+
}
|
|
710
|
+
const seqno = active ? await seqnoAt(ctx, wallet, head, state) : 0n;
|
|
711
|
+
if (seqno === undefined)
|
|
712
|
+
throw undecided('the wallet state does not show its seqno');
|
|
713
|
+
if (seqno > slot.seqno) {
|
|
714
|
+
// The indexer's consumer search: a hint that finds ours, never a "no", nor a veto
|
|
715
|
+
// either; a hint that cannot be used (a record the chain could not produce, a
|
|
716
|
+
// failed read) is logged, and the authenticated path decides.
|
|
717
|
+
let hint;
|
|
718
|
+
try {
|
|
719
|
+
hint = await consumerOf(ctx, wallet, slot.seqno, head, state);
|
|
720
|
+
}
|
|
721
|
+
catch (error) {
|
|
722
|
+
if (!(0, error_1.isCryptoAioError)(error) || !error.retryable)
|
|
723
|
+
throw error;
|
|
724
|
+
ctx.log.warn('the indexer gave no usable seqno consumer', {
|
|
725
|
+
code: 'SEQNO_CONSUMER_HINT_UNUSABLE',
|
|
726
|
+
});
|
|
727
|
+
}
|
|
728
|
+
if (hint && (0, trace_1.isOwnAttempt)(hint, wallet, id))
|
|
729
|
+
return proveIncluded(ctx, hint, wallet);
|
|
730
|
+
}
|
|
731
|
+
// Never "not included" while the message may still run: a reset of the wallet could
|
|
732
|
+
// bring its seqno back to ours.
|
|
733
|
+
if (!(await expiredAt(ctx, head, slot.validUntil))) {
|
|
734
|
+
throw undecided('the message may still be included');
|
|
735
|
+
}
|
|
736
|
+
const chain = await fromTheChain(ctx, {
|
|
737
|
+
wallet,
|
|
738
|
+
id,
|
|
739
|
+
slot,
|
|
740
|
+
head,
|
|
741
|
+
state,
|
|
742
|
+
active,
|
|
743
|
+
seqno,
|
|
744
|
+
});
|
|
745
|
+
if ('ours' in chain)
|
|
746
|
+
return proveOurs(ctx, chain.ours, wallet, id);
|
|
747
|
+
return { included: false };
|
|
748
|
+
},
|
|
749
|
+
async slotConsumed(ordering, from, level) {
|
|
750
|
+
const slot = seqnoOrdering(ordering);
|
|
751
|
+
if (!slot)
|
|
752
|
+
return false;
|
|
753
|
+
// Masterchain state is final once it exists, so TON gives no separate `latest`
|
|
754
|
+
// evidence: our own landed-but-unindexed message is never observed as `replaced`.
|
|
755
|
+
if (level === 'latest')
|
|
756
|
+
return false;
|
|
757
|
+
// "My seqno at the final state is above n", a monotone predicate.
|
|
758
|
+
return seqnoAbove(ctx, walletOf(from), slot.seqno);
|
|
759
|
+
},
|
|
760
|
+
async expired(ordering) {
|
|
761
|
+
const slot = seqnoOrdering(ordering);
|
|
762
|
+
if (!slot)
|
|
763
|
+
return false;
|
|
764
|
+
return expiredAt(ctx, await attestedHead(ctx), slot.validUntil);
|
|
765
|
+
},
|
|
766
|
+
async blockHash(height) {
|
|
767
|
+
// Every masterchain block is final once it exists: both levels read the same.
|
|
768
|
+
if (height < 0n || height > BigInt(await api.masterchainHead(api_1.MONITOR)))
|
|
769
|
+
return null;
|
|
770
|
+
return (await masterchainBlock(ctx, Number(height))).id.rootHash;
|
|
771
|
+
},
|
|
772
|
+
};
|
|
773
|
+
}
|
|
774
|
+
/** A history cursor: the next page's `end_lt`, a u64 in decimal, capped before use. */
|
|
775
|
+
function cursorLt(cursor) {
|
|
776
|
+
if (cursor === undefined)
|
|
777
|
+
return undefined;
|
|
778
|
+
if (cursor.length === 0 ||
|
|
779
|
+
cursor.length > MAX_LT_DIGITS ||
|
|
780
|
+
!/^\d+$/.test(cursor) ||
|
|
781
|
+
BigInt(cursor) > MAX_LT) {
|
|
782
|
+
throw new error_1.ValidationError('INVALID_INTENT', 'not a TON history cursor');
|
|
783
|
+
}
|
|
784
|
+
return BigInt(cursor);
|
|
785
|
+
}
|
|
786
|
+
/**
|
|
787
|
+
* An address's transactions from the indexer, newest first, decoded with jettons only for
|
|
788
|
+
* verified jetton wallets. The cursor is the next page's `end_lt`, taken from the page as
|
|
789
|
+
* the indexer served it, so rows not final yet never end the history early; a page
|
|
790
|
+
* is at most what toncenter serves.
|
|
791
|
+
*/
|
|
792
|
+
function createTonHistory(ctx) {
|
|
793
|
+
return {
|
|
794
|
+
async list(address, options) {
|
|
795
|
+
const endLt = cursorLt(options.cursor);
|
|
796
|
+
const account = ctx.codec.normalize(address).canonical;
|
|
797
|
+
const page = await ctx.api.accountTransactionsPage(account, {
|
|
798
|
+
limit: Math.min(options.limit, HISTORY_PAGE_MAX),
|
|
799
|
+
...(endLt !== undefined ? { endLt } : {}),
|
|
800
|
+
}, api_1.READ);
|
|
801
|
+
const items = [];
|
|
802
|
+
const memo = (0, reader_1.pageMemo)();
|
|
803
|
+
for (const tx of page.transactions) {
|
|
804
|
+
items.push(await (0, reader_1.decodeWithJettons)(ctx, tx, api_1.READ, memo));
|
|
805
|
+
}
|
|
806
|
+
return {
|
|
807
|
+
items,
|
|
808
|
+
...(page.next !== undefined ? { next: page.next.toString() } : {}),
|
|
809
|
+
};
|
|
810
|
+
},
|
|
811
|
+
};
|
|
812
|
+
}
|
|
813
|
+
//# sourceMappingURL=proofs.js.map
|