crypto-aio 0.0.2 → 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/lib-types.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/adapters/ton/types.js +3 -0
- 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/core/model/transaction.js +3 -0
- 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 -44
- 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 -2
- package/dist/libs/eth/contract.js +0 -7
- package/dist/libs/eth/contract.js.map +0 -1
- package/dist/libs/eth/index.d.ts +0 -20
- package/dist/libs/eth/index.js +0 -62
- package/dist/libs/eth/index.js.map +0 -1
- package/dist/libs/eth/transact.d.ts +0 -2
- package/dist/libs/eth/transact.js +0 -7
- package/dist/libs/eth/transact.js.map +0 -1
- package/dist/libs/index.d.ts +0 -1
- package/dist/libs/index.js +0 -18
- package/dist/libs/index.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 -4
- package/dist/tool/index.js +0 -21
- 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 -4
- package/dist/tool/options.js +0 -28
- package/dist/tool/options.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/index.d.ts +0 -3
- package/dist/type/index.js +0 -20
- package/dist/type/index.js.map +0 -1
- package/dist/type/lib-types.d.ts +0 -7
- package/dist/type/lib-types.js.map +0 -1
|
@@ -0,0 +1,701 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FIRST_SEND_MS = exports.CHAIN_TIME_TOLERANCE = exports.REQUEST_ID = void 0;
|
|
4
|
+
exports.createTonBuilder = createTonBuilder;
|
|
5
|
+
exports.createTonBroadcaster = createTonBroadcaster;
|
|
6
|
+
/**
|
|
7
|
+
* TON transfers: fees, funds, the unsigned external request, its assembly, and the
|
|
8
|
+
* broadcaster. Builds use `read` tags, except the sender's jetton wallet, which the proof
|
|
9
|
+
* quorum attests; sending uses `broadcast` / `ambiguous-on-failure` with the caller's
|
|
10
|
+
* fanout and signal.
|
|
11
|
+
*
|
|
12
|
+
* The fund-safety rules this module keeps:
|
|
13
|
+
* - One output per transfer. The verdict answers `failed` for a partly delivered batch, and
|
|
14
|
+
* a failed Operation may be sent again whole, paying twice the outputs that moved; so a
|
|
15
|
+
* TON transfer carries exactly one message, and TON offers no `batch-transfer`.
|
|
16
|
+
* - The built request is decoded again before it is handed out for signing, and must say
|
|
17
|
+
* exactly what the intent says: the one message's destination, value and bounce flag, or
|
|
18
|
+
* the jetton transfer's jetton wallet, recipient, amount and forward amount; the memo; the
|
|
19
|
+
* seqno and lifetime; the wallet (`assertBuilt`).
|
|
20
|
+
* - An emulation that ran nothing is no estimate: every request this builder makes runs the
|
|
21
|
+
* wallet code (deployed, or deployed by its `StateInit`) and sends one message, so a gas
|
|
22
|
+
* fee or a forward fee of 0 is never an `expected` draft that `checkFunds` would trust.
|
|
23
|
+
* tonlib buys the emulated gas with the balance, so a sender whose balance is below what
|
|
24
|
+
* the transfer must at least send is answered `INSUFFICIENT_FUNDS`; any other such
|
|
25
|
+
* emulation is a retryable `PROVIDER_INCONSISTENT`.
|
|
26
|
+
* - A node-suggested fee is bounded by the network's `maxNetworkFee` (the economic ceiling).
|
|
27
|
+
* - A frozen wallet, or an undeployed one at an allocated seqno past 0, is refused from its
|
|
28
|
+
* state before anything is built.
|
|
29
|
+
*/
|
|
30
|
+
const core_1 = require("@ton/core");
|
|
31
|
+
const ton_1 = require("@ton/ton");
|
|
32
|
+
const error_1 = require("../../core/errors/error");
|
|
33
|
+
const asset_1 = require("../../core/model/asset");
|
|
34
|
+
const api_1 = require("./api");
|
|
35
|
+
const errors_1 = require("./errors");
|
|
36
|
+
const fees_1 = require("./fees");
|
|
37
|
+
const messages_1 = require("./messages");
|
|
38
|
+
const network_1 = require("./network");
|
|
39
|
+
Object.defineProperty(exports, "CHAIN_TIME_TOLERANCE", { enumerable: true, get: function () { return network_1.CHAIN_TIME_TOLERANCE; } });
|
|
40
|
+
const proofs_1 = require("./proofs");
|
|
41
|
+
const wallets_1 = require("./wallets");
|
|
42
|
+
const reader_1 = require("./reader");
|
|
43
|
+
/** The id of the one signing request (1 × ed25519 over the signing cell hash). */
|
|
44
|
+
exports.REQUEST_ID = 'wallet';
|
|
45
|
+
/**
|
|
46
|
+
* How long after `assemble` a first send may skip the replay guard, in milliseconds. A
|
|
47
|
+
* normal transfer sends milliseconds after `assemble`. A first send that comes later (a
|
|
48
|
+
* slow store, a paused process) may follow another process's send of the same bytes
|
|
49
|
+
* through a shared store, and a wallet reset in between would make an unguarded late send
|
|
50
|
+
* pay twice, so it is guarded like a resend. The bound stays well below any sane
|
|
51
|
+
* `lifecycle.leaseMs`; a slower first send only costs one guard.
|
|
52
|
+
*/
|
|
53
|
+
exports.FIRST_SEND_MS = 2_000;
|
|
54
|
+
/** Whether a first send `age` ms after `assemble` may skip the guard (never below 0). */
|
|
55
|
+
const soonAfter = (age) => age >= 0 && age < exports.FIRST_SEND_MS;
|
|
56
|
+
const hex = (bytes) => Buffer.from(bytes).toString('hex');
|
|
57
|
+
const inconsistent = (reason) => new error_1.ProviderError('PROVIDER_INCONSISTENT', reason, { retryable: true });
|
|
58
|
+
/**
|
|
59
|
+
* The funds path's answer when the balance is below what the transfer must at least send
|
|
60
|
+
* (`required`: a lower bound, before gas), as the engine reports a failed funds check.
|
|
61
|
+
*/
|
|
62
|
+
const insufficient = (required, available) => new error_1.ChainError('INSUFFICIENT_FUNDS', 'insufficient funds for this transfer', {
|
|
63
|
+
details: { required: required.toString(), available: available.toString() },
|
|
64
|
+
});
|
|
65
|
+
/**
|
|
66
|
+
* The recipient's bounce flag: the variant is `{ bounceable }` only, and a raw address
|
|
67
|
+
* without one is bounceable. Any other variant did not come from the TON codec, and the
|
|
68
|
+
* driver never guesses what it meant.
|
|
69
|
+
*/
|
|
70
|
+
function bounceOf(output) {
|
|
71
|
+
const variant = output.variant;
|
|
72
|
+
if (variant === undefined)
|
|
73
|
+
return true;
|
|
74
|
+
const keys = Object.keys(variant);
|
|
75
|
+
const flag = Object.hasOwn(variant, 'bounceable') ? variant.bounceable : undefined;
|
|
76
|
+
if (keys.length !== 1 || typeof flag !== 'boolean') {
|
|
77
|
+
throw new error_1.ValidationError('INVALID_INTENT', `a TON recipient's variant holds only its bounce flag`);
|
|
78
|
+
}
|
|
79
|
+
return flag;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* The checks every builder method runs before any codec, signing or I/O work:
|
|
83
|
+
* the wallet identity derives exactly `from`, the intent is one output with a memo that
|
|
84
|
+
* fits, and the fee is TON's.
|
|
85
|
+
*/
|
|
86
|
+
function planOf(ctx, intent, build) {
|
|
87
|
+
const identity = (0, wallets_1.resolveIdentity)(build.wallet, ctx.config.globalId);
|
|
88
|
+
const key = build.keys.find((k) => k.scheme === 'ed25519');
|
|
89
|
+
if (!key)
|
|
90
|
+
throw new error_1.ConfigError('CONFIG_INVALID', 'the TON wallet has no ed25519 key');
|
|
91
|
+
if ((0, wallets_1.walletAddress)(identity, key.publicKey) !== build.from ||
|
|
92
|
+
intent.from !== build.from) {
|
|
93
|
+
throw new error_1.ConfigError('CONFIG_INVALID', 'the TON wallet identity does not derive the sending address');
|
|
94
|
+
}
|
|
95
|
+
if (intent.outputs.length > 1) {
|
|
96
|
+
throw new error_1.UnsupportedCapabilityError('UNSUPPORTED_CAPABILITY', 'a TON transfer carries exactly one output (no batch transfers)');
|
|
97
|
+
}
|
|
98
|
+
const [first] = intent.outputs;
|
|
99
|
+
if (!first)
|
|
100
|
+
throw new error_1.ValidationError('INVALID_INTENT', 'a TON transfer needs an output');
|
|
101
|
+
if (intent.memo !== undefined && (0, messages_1.memoBytes)(intent.memo) > messages_1.MAX_MEMO_BYTES) {
|
|
102
|
+
throw new error_1.ValidationError('INVALID_INTENT', `a TON memo is at most ${messages_1.MAX_MEMO_BYTES} bytes`);
|
|
103
|
+
}
|
|
104
|
+
(0, messages_1.sdkAddress)(first.to); // INVALID_ADDRESS unless raw
|
|
105
|
+
const output = { to: first.to, amount: first.amount, bounce: bounceOf(first) };
|
|
106
|
+
const asset = intent.asset;
|
|
107
|
+
let jetton;
|
|
108
|
+
if (asset !== 'native') {
|
|
109
|
+
const master = (0, reader_1.jettonMaster)(ctx, asset);
|
|
110
|
+
jetton = { master, asset: { standard: 'jetton', contract: master } };
|
|
111
|
+
}
|
|
112
|
+
const request = (0, fees_1.feeRequest)(intent.fee, jetton !== undefined);
|
|
113
|
+
const attached = jetton ? (request.attached ?? ctx.config.jettonAttached) : undefined;
|
|
114
|
+
// The attached value pays the recipient's notification and more: at or below the forward
|
|
115
|
+
// amount the jetton wallet cannot run the transfer.
|
|
116
|
+
if (attached !== undefined && attached <= ctx.config.jettonForwardAmount) {
|
|
117
|
+
throw new error_1.ValidationError('INVALID_INTENT', `'attached' must exceed the network's jetton forward amount`);
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
identity,
|
|
121
|
+
key,
|
|
122
|
+
output,
|
|
123
|
+
...(jetton ? { jetton } : {}),
|
|
124
|
+
request,
|
|
125
|
+
...(attached !== undefined ? { attached } : {}),
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
/** The allocated seqno (a uint32, never wrapped); a build never runs without one. */
|
|
129
|
+
function seqnoOf(build) {
|
|
130
|
+
const ordering = build.ordering;
|
|
131
|
+
if (ordering?.kind !== 'seqno' || ordering.seqno > 0xffffffffn || ordering.seqno < 0n) {
|
|
132
|
+
throw new error_1.ValidationError('INVALID_INTENT', 'a TON transfer needs its allocated seqno');
|
|
133
|
+
}
|
|
134
|
+
return Number(ordering.seqno);
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* The fee draft `build` and `checkFunds` are given, read strictly as a stored record:
|
|
138
|
+
* TON's, and made for this transfer's attached value (none for native coin).
|
|
139
|
+
*/
|
|
140
|
+
function feeOf(fee, plan) {
|
|
141
|
+
const details = (0, fees_1.tonFeeDetails)(fee.details);
|
|
142
|
+
if (fee.kind !== 'ton' || details.attached !== plan.attached) {
|
|
143
|
+
throw new error_1.ValidationError('INVALID_INTENT', 'the fee estimate was not made for this TON transfer');
|
|
144
|
+
}
|
|
145
|
+
return details;
|
|
146
|
+
}
|
|
147
|
+
/** The wallet's state; a frozen wallet runs no message, its deploy `StateInit` included. */
|
|
148
|
+
async function walletState(ctx, from) {
|
|
149
|
+
const state = await ctx.api.account(from, api_1.READ);
|
|
150
|
+
if (state.status === 'frozen') {
|
|
151
|
+
throw new error_1.ChainError('TX_REFUSED', 'the wallet account is frozen');
|
|
152
|
+
}
|
|
153
|
+
return state;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* An undeployed wallet only runs a request at seqno 0 (its `StateInit`'s). At a later
|
|
157
|
+
* allocated seqno the state lags, or the wallet was deleted, and its `StateInit` would
|
|
158
|
+
* restart it at 0: either way nothing is built, and a later read decides.
|
|
159
|
+
*/
|
|
160
|
+
function assertDeployable(state, seqno) {
|
|
161
|
+
if (state.status === 'uninitialized' && seqno !== 0) {
|
|
162
|
+
throw inconsistent('the wallet is not deployed at the allocated seqno');
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* The endpoint's chain time, when it is within the tolerance of the local clock: one bad
|
|
167
|
+
* read must not set a lifetime the core then waits out.
|
|
168
|
+
*/
|
|
169
|
+
function chainTime(ctx, state) {
|
|
170
|
+
if (Math.abs(state.syncUtime - ctx.clock.now() / 1000) > network_1.CHAIN_TIME_TOLERANCE) {
|
|
171
|
+
throw inconsistent('the endpoint reports a chain time far from the local clock');
|
|
172
|
+
}
|
|
173
|
+
return state.syncUtime;
|
|
174
|
+
}
|
|
175
|
+
/** The one message, and for jettons the sender's jetton wallet it goes to. */
|
|
176
|
+
async function messageOf(ctx, intent, plan, from, queryId) {
|
|
177
|
+
const { output } = plan;
|
|
178
|
+
const memo = intent.memo !== undefined ? { memo: intent.memo } : {};
|
|
179
|
+
if (!plan.jetton || plan.attached === undefined) {
|
|
180
|
+
return {
|
|
181
|
+
message: (0, messages_1.nativeMessage)({
|
|
182
|
+
to: output.to,
|
|
183
|
+
value: output.amount,
|
|
184
|
+
bounce: output.bounce,
|
|
185
|
+
...memo,
|
|
186
|
+
}),
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
// The jetton wallet is the one the intent's master names for our wallet, as
|
|
190
|
+
// the proof quorum attests it (cached only so). The verdict's legs carry no master, so
|
|
191
|
+
// this is what binds a transfer to the intended jetton.
|
|
192
|
+
const jettonWallet = await (0, reader_1.jettonWalletAddress)(ctx, plan.jetton.master, from, api_1.PROOF);
|
|
193
|
+
return {
|
|
194
|
+
jettonWallet,
|
|
195
|
+
message: (0, messages_1.jettonMessage)({
|
|
196
|
+
jettonWallet,
|
|
197
|
+
attached: plan.attached,
|
|
198
|
+
queryId,
|
|
199
|
+
amount: output.amount,
|
|
200
|
+
destination: output.to,
|
|
201
|
+
responseDestination: from,
|
|
202
|
+
forwardAmount: ctx.config.jettonForwardAmount,
|
|
203
|
+
...memo,
|
|
204
|
+
}),
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
const malformedConfig = () => new error_1.ProviderError('PROVIDER_UNAVAILABLE', 'malformed message prices in the config', {
|
|
208
|
+
retryable: true,
|
|
209
|
+
});
|
|
210
|
+
/**
|
|
211
|
+
* The config's forward fee of `message`: param 25, or 24 when the masterchain is
|
|
212
|
+
* involved (transaction.cpp prices a message by the source's or the destination's chain).
|
|
213
|
+
* The cell goes through the capped `cellFromBoc`; an answer that does not parse is the
|
|
214
|
+
* endpoint's fault, retryable, never a bare SDK error.
|
|
215
|
+
*/
|
|
216
|
+
async function configForwardFee(ctx, from, message) {
|
|
217
|
+
const masterchain = from.startsWith('-1:') ||
|
|
218
|
+
(message.info.type === 'internal' && message.info.dest.workChain === -1);
|
|
219
|
+
const cell = (0, messages_1.cellFromBoc)(await ctx.api.configParam(masterchain ? 24 : 25, api_1.READ));
|
|
220
|
+
if (!cell)
|
|
221
|
+
throw malformedConfig();
|
|
222
|
+
try {
|
|
223
|
+
const prices = (0, ton_1.configParseMsgPrices)(cell.beginParse());
|
|
224
|
+
const stored = (0, core_1.beginCell)().store((0, core_1.storeMessageRelaxed)(message)).endCell();
|
|
225
|
+
const { fees, remaining } = (0, ton_1.computeMessageForwardFees)(prices, stored);
|
|
226
|
+
return fees + remaining;
|
|
227
|
+
}
|
|
228
|
+
catch {
|
|
229
|
+
throw malformedConfig();
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
/** `gas_prices#dd` and `gas_prices_ext#de` (block.tlb): gas prices without a flat part. */
|
|
233
|
+
const GAS_PRICES_TAGS = new Set([0xdd, 0xde]);
|
|
234
|
+
/**
|
|
235
|
+
* The least gas fee a wallet run pays, `flat_gas_price` of
|
|
236
|
+
* config param 21 (basechain) or 20 (masterchain), by the sender's workchain, which prices
|
|
237
|
+
* the account's own compute phase. It is the price of the first `flat_gas_limit` gas units,
|
|
238
|
+
* which every run that computes pays in full (transaction.cpp `gas_fee`); never
|
|
239
|
+
* `flat_gas_limit × flat_gas_price`, a units error about 100 times too high. A config
|
|
240
|
+
* without the flat part (`gas_prices`, `gas_prices_ext`) gives no floor; one that does not
|
|
241
|
+
* parse is the endpoint's fault, retryable. One endpoint's answer: the caller holds it to
|
|
242
|
+
* the ceiling before trusting it.
|
|
243
|
+
*/
|
|
244
|
+
async function configGasFloor(ctx, from) {
|
|
245
|
+
const malformed = () => new error_1.ProviderError('PROVIDER_UNAVAILABLE', 'malformed gas prices in the config', {
|
|
246
|
+
retryable: true,
|
|
247
|
+
});
|
|
248
|
+
const cell = (0, messages_1.cellFromBoc)(await ctx.api.configParam(from.startsWith('-1:') ? 20 : 21, api_1.READ));
|
|
249
|
+
if (!cell)
|
|
250
|
+
throw malformed();
|
|
251
|
+
try {
|
|
252
|
+
const slice = cell.beginParse();
|
|
253
|
+
if (GAS_PRICES_TAGS.has(slice.preloadUint(8)))
|
|
254
|
+
return 0n;
|
|
255
|
+
return (0, ton_1.configParseGasLimitsPrices)(slice).flatGasPrice;
|
|
256
|
+
}
|
|
257
|
+
catch {
|
|
258
|
+
throw malformed();
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
/** The external message's body (the wallet request) as a base64 BOC. */
|
|
262
|
+
const bodyOf = (external) => (0, core_1.loadMessage)(external.beginParse()).body.toBoc().toString('base64');
|
|
263
|
+
/**
|
|
264
|
+
* The recipient binding: the unsigned external message, decoded again, says exactly what
|
|
265
|
+
* the intent says. It goes to `from`, deploys exactly when asked, carries our wallet's
|
|
266
|
+
* request at `seqno` until `validUntil`, and sends one message with `SEND_MODE` exactly
|
|
267
|
+
* (never +128, which sends the whole balance, nor +32), no extra currencies and no
|
|
268
|
+
* `StateInit`: native coin to the recipient with its value, bounce flag and memo; or a
|
|
269
|
+
* jetton `transfer` to the attested jetton wallet with the attached value, bounceable, naming
|
|
270
|
+
* the recipient, the amount, `from` for the excess, no custom payload, the network's forward
|
|
271
|
+
* amount, the memo and the seqno as query id. Anything else is never handed out for signing
|
|
272
|
+
* (`INVALID_INTENT`, fixed text).
|
|
273
|
+
*/
|
|
274
|
+
function assertBuilt(ctx, intent, plan, unsigned, expected) {
|
|
275
|
+
const refuse = () => {
|
|
276
|
+
throw new error_1.ValidationError('INVALID_INTENT', 'the built TON message does not match the intent');
|
|
277
|
+
};
|
|
278
|
+
let external;
|
|
279
|
+
try {
|
|
280
|
+
external = (0, core_1.loadMessage)(unsigned.beginParse());
|
|
281
|
+
}
|
|
282
|
+
catch {
|
|
283
|
+
return refuse();
|
|
284
|
+
}
|
|
285
|
+
if (external.info.type !== 'external-in' ||
|
|
286
|
+
external.info.dest.toRawString() !== expected.from ||
|
|
287
|
+
Boolean(external.init) !== expected.deploy) {
|
|
288
|
+
refuse();
|
|
289
|
+
}
|
|
290
|
+
const request = (0, messages_1.decodeWalletRequest)(external.body);
|
|
291
|
+
if (request?.auth !== 'external' ||
|
|
292
|
+
request.seqno !== expected.seqno ||
|
|
293
|
+
request.validUntil !== expected.validUntil ||
|
|
294
|
+
request.walletId !== (0, wallets_1.walletIdOf)(plan.identity, plan.key.publicKey) ||
|
|
295
|
+
request.messages.length !== 1 ||
|
|
296
|
+
request.modes.length !== 1 ||
|
|
297
|
+
request.modes[0] !== wallets_1.SEND_MODE) {
|
|
298
|
+
return refuse();
|
|
299
|
+
}
|
|
300
|
+
const message = request.messages[0];
|
|
301
|
+
const facts = (0, messages_1.messageFacts)(message);
|
|
302
|
+
if (!facts ||
|
|
303
|
+
message.info.type !== 'internal' ||
|
|
304
|
+
(message.info.value.other?.size ?? 0) > 0 ||
|
|
305
|
+
message.init) {
|
|
306
|
+
return refuse();
|
|
307
|
+
}
|
|
308
|
+
const { output } = plan;
|
|
309
|
+
if (!plan.jetton) {
|
|
310
|
+
const memo = intent.memo !== undefined
|
|
311
|
+
? (0, messages_1.decodeComment)(facts.body) === intent.memo
|
|
312
|
+
: facts.body.bits.length === 0 && facts.body.refs.length === 0;
|
|
313
|
+
if (facts.to !== output.to ||
|
|
314
|
+
facts.value !== output.amount ||
|
|
315
|
+
message.info.bounce !== output.bounce ||
|
|
316
|
+
!memo) {
|
|
317
|
+
refuse();
|
|
318
|
+
}
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
const transfer = (0, messages_1.decodeJettonTransfer)(facts.body);
|
|
322
|
+
if (facts.to !== expected.jettonWallet ||
|
|
323
|
+
facts.value !== plan.attached ||
|
|
324
|
+
!message.info.bounce ||
|
|
325
|
+
transfer?.destination !== output.to ||
|
|
326
|
+
transfer.amount !== output.amount ||
|
|
327
|
+
transfer.queryId !== BigInt(expected.seqno) ||
|
|
328
|
+
transfer.responseDestination !== expected.from ||
|
|
329
|
+
transfer.customPayload ||
|
|
330
|
+
transfer.forwardAmount !== ctx.config.jettonForwardAmount ||
|
|
331
|
+
transfer.comment !== intent.memo) {
|
|
332
|
+
refuse();
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
function createTonBuilder(ctx) {
|
|
336
|
+
const { api, config } = ctx;
|
|
337
|
+
return {
|
|
338
|
+
async estimateFee(intent, build) {
|
|
339
|
+
const plan = planOf(ctx, intent, build);
|
|
340
|
+
const state = await walletState(ctx, build.from);
|
|
341
|
+
const now = chainTime(ctx, state);
|
|
342
|
+
const deploy = state.status === 'uninitialized';
|
|
343
|
+
// The engine allocates the seqno; an estimate outside it (`Blockchain.estimateFee`)
|
|
344
|
+
// runs at the wallet's live one, read at the state's own block, since the
|
|
345
|
+
// wallet code refuses any other and the emulation would then run nothing.
|
|
346
|
+
const seqno = build.ordering !== undefined
|
|
347
|
+
? seqnoOf(build)
|
|
348
|
+
: deploy
|
|
349
|
+
? 0
|
|
350
|
+
: Number(await (0, reader_1.walletSeqno)(ctx, build.from, api_1.READ));
|
|
351
|
+
assertDeployable(state, seqno);
|
|
352
|
+
const { message } = await messageOf(ctx, intent, plan, build.from, BigInt(seqno));
|
|
353
|
+
const unsigned = await (0, wallets_1.unsignedRequest)(plan.identity, plan.key.publicKey, {
|
|
354
|
+
seqno,
|
|
355
|
+
validUntil: now + config.validForSeconds,
|
|
356
|
+
messages: [message],
|
|
357
|
+
deploy: false,
|
|
358
|
+
});
|
|
359
|
+
const init = deploy
|
|
360
|
+
? (0, wallets_1.walletStateInit)(plan.identity, plan.key.publicKey)
|
|
361
|
+
: undefined;
|
|
362
|
+
const emulated = await api.estimateFee({
|
|
363
|
+
address: build.from,
|
|
364
|
+
body: bodyOf(unsigned.message),
|
|
365
|
+
...(init?.code && init.data
|
|
366
|
+
? {
|
|
367
|
+
initCode: init.code.toBoc().toString('base64'),
|
|
368
|
+
initData: init.data.toBoc().toString('base64'),
|
|
369
|
+
}
|
|
370
|
+
: {}),
|
|
371
|
+
}, api_1.READ);
|
|
372
|
+
// The forward fee counts once. The emulation's follows the real action list; the
|
|
373
|
+
// config's formula is its floor, so an endpoint that reports less cannot shrink it.
|
|
374
|
+
const computed = await configForwardFee(ctx, build.from, message);
|
|
375
|
+
// The economic ceiling by the sender's workchain. The config's forward fee
|
|
376
|
+
// comes from one endpoint too, so it is held to the ceiling before anything trusts it:
|
|
377
|
+
// an inflated param 25 must never turn an empty emulation into a definitive shortfall.
|
|
378
|
+
const ceiling = build.from.startsWith('-1:')
|
|
379
|
+
? config.maxNetworkFee.masterchain
|
|
380
|
+
: config.maxNetworkFee.basechain;
|
|
381
|
+
if (computed > ceiling) {
|
|
382
|
+
throw inconsistent("the endpoint's config prices a forward fee above the policy maximum");
|
|
383
|
+
}
|
|
384
|
+
// The wallet runs (deployed, or by its `StateInit`) and sends one
|
|
385
|
+
// message, so an emulation without gas or without a forward fee ran nothing.
|
|
386
|
+
if (emulated.gasFee === 0n || emulated.forwardFee === 0n) {
|
|
387
|
+
// tonlib buys the emulated gas with the balance (`compute_gas_limits`), so
|
|
388
|
+
// a sender that cannot pay emulates to nothing too. Below what the transfer must at
|
|
389
|
+
// least pay (the amount, or the jetton attached value, plus the config's forward
|
|
390
|
+
// fee and the wallet run's flat gas price) that is the answer; otherwise
|
|
391
|
+
// the endpoint's view lags, or it refused the request (another seqno), and a later
|
|
392
|
+
// read decides. The gas floor comes from one endpoint too, so it is held to the
|
|
393
|
+
// ceiling first.
|
|
394
|
+
const gas = await configGasFloor(ctx, build.from);
|
|
395
|
+
if (computed + gas > ceiling) {
|
|
396
|
+
throw inconsistent("the endpoint's config prices gas above the policy maximum");
|
|
397
|
+
}
|
|
398
|
+
const minimum = (plan.attached ?? plan.output.amount) + computed + gas;
|
|
399
|
+
if (state.balance < minimum)
|
|
400
|
+
throw insufficient(minimum, state.balance);
|
|
401
|
+
throw inconsistent("the endpoint's emulation did not run the transfer");
|
|
402
|
+
}
|
|
403
|
+
const details = {
|
|
404
|
+
importFee: emulated.importFee,
|
|
405
|
+
gasFee: emulated.gasFee,
|
|
406
|
+
storageFee: emulated.storageFee,
|
|
407
|
+
...(emulated.forwardFee >= computed
|
|
408
|
+
? { forwardFee: emulated.forwardFee, forwardFeeSource: 'emulated' }
|
|
409
|
+
: { forwardFee: computed, forwardFeeSource: 'computed' }),
|
|
410
|
+
deploy,
|
|
411
|
+
...(plan.attached !== undefined
|
|
412
|
+
? { attached: plan.attached, forwardAmount: config.jettonForwardAmount }
|
|
413
|
+
: {}),
|
|
414
|
+
};
|
|
415
|
+
if ((0, fees_1.networkFee)(details) > ceiling) {
|
|
416
|
+
throw inconsistent('the endpoint suggests a fee above the policy maximum');
|
|
417
|
+
}
|
|
418
|
+
return (0, fees_1.tonFeeDraft)({
|
|
419
|
+
speed: plan.request.speed,
|
|
420
|
+
details,
|
|
421
|
+
...(plan.jetton ? { jettonOutputs: 1 } : {}),
|
|
422
|
+
payer: build.from,
|
|
423
|
+
});
|
|
424
|
+
},
|
|
425
|
+
async checkFunds(intent, fee, build) {
|
|
426
|
+
const plan = planOf(ctx, intent, build);
|
|
427
|
+
const details = feeOf(fee, plan);
|
|
428
|
+
const charges = (0, fees_1.networkFee)(details) + (details.attached ?? 0n);
|
|
429
|
+
const available = (await walletState(ctx, build.from)).balance;
|
|
430
|
+
const required = charges + (plan.jetton ? 0n : plan.output.amount);
|
|
431
|
+
if (available < required) {
|
|
432
|
+
return { ok: false, asset: 'native', required, available };
|
|
433
|
+
}
|
|
434
|
+
if (plan.jetton) {
|
|
435
|
+
const wanted = plan.output.amount;
|
|
436
|
+
const held = await (0, reader_1.jettonBalance)(ctx, plan.jetton.master, build.from, api_1.READ);
|
|
437
|
+
if (held < wanted) {
|
|
438
|
+
return {
|
|
439
|
+
ok: false,
|
|
440
|
+
asset: plan.jetton.asset,
|
|
441
|
+
required: wanted,
|
|
442
|
+
available: held,
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
return { ok: true };
|
|
447
|
+
},
|
|
448
|
+
async build(intent, fee, build) {
|
|
449
|
+
const plan = planOf(ctx, intent, build);
|
|
450
|
+
const seqno = seqnoOf(build);
|
|
451
|
+
feeOf(fee, plan);
|
|
452
|
+
const state = await walletState(ctx, build.from);
|
|
453
|
+
// The lifetime runs from the endpoint's chain time, bounded by the local clock; the
|
|
454
|
+
// proof checks expiry against attested chain time, never a node's clock.
|
|
455
|
+
const now = chainTime(ctx, state);
|
|
456
|
+
const validUntil = now + config.validForSeconds;
|
|
457
|
+
// When the message may first run, for the proof's window: the chain time, but
|
|
458
|
+
// never later than the local clock (an endpoint ahead of it sets only the lifetime).
|
|
459
|
+
const validFrom = Math.min(now, Math.floor(ctx.clock.now() / 1000));
|
|
460
|
+
const ordering = {
|
|
461
|
+
kind: 'seqno',
|
|
462
|
+
seqno: BigInt(seqno),
|
|
463
|
+
validUntil,
|
|
464
|
+
validFrom,
|
|
465
|
+
};
|
|
466
|
+
assertDeployable(state, seqno);
|
|
467
|
+
const deploy = state.status === 'uninitialized';
|
|
468
|
+
const { message, jettonWallet } = await messageOf(ctx, intent, plan, build.from, BigInt(seqno));
|
|
469
|
+
const unsigned = await (0, wallets_1.unsignedRequest)(plan.identity, plan.key.publicKey, {
|
|
470
|
+
seqno,
|
|
471
|
+
validUntil,
|
|
472
|
+
messages: [message],
|
|
473
|
+
deploy,
|
|
474
|
+
});
|
|
475
|
+
assertBuilt(ctx, intent, plan, unsigned.message, {
|
|
476
|
+
from: build.from,
|
|
477
|
+
deploy,
|
|
478
|
+
seqno,
|
|
479
|
+
validUntil,
|
|
480
|
+
...(jettonWallet !== undefined ? { jettonWallet } : {}),
|
|
481
|
+
});
|
|
482
|
+
const request = {
|
|
483
|
+
id: exports.REQUEST_ID,
|
|
484
|
+
scheme: 'ed25519',
|
|
485
|
+
payload: unsigned.digest,
|
|
486
|
+
payloadKind: 'message',
|
|
487
|
+
publicKey: plan.key.publicKey,
|
|
488
|
+
...(plan.key.keyRef ? { keyRef: plan.key.keyRef } : {}),
|
|
489
|
+
};
|
|
490
|
+
return {
|
|
491
|
+
payload: {
|
|
492
|
+
encoding: 'base64',
|
|
493
|
+
data: unsigned.message.toBoc().toString('base64'),
|
|
494
|
+
},
|
|
495
|
+
signingRequests: [request],
|
|
496
|
+
ordering,
|
|
497
|
+
fee,
|
|
498
|
+
summary: {
|
|
499
|
+
asset: (0, asset_1.assetId)(ctx.chain.id, ctx.network.id, plan.jetton?.asset ?? 'native'),
|
|
500
|
+
outputs: [{ to: plan.output.to, amount: plan.output.amount.toString() }],
|
|
501
|
+
...(intent.memo !== undefined ? { memo: intent.memo } : {}),
|
|
502
|
+
},
|
|
503
|
+
};
|
|
504
|
+
},
|
|
505
|
+
async assemble(unsigned, signatures) {
|
|
506
|
+
const request = unsigned.signingRequests[0];
|
|
507
|
+
const signature = signatures.find((s) => s.requestId === request?.id);
|
|
508
|
+
if (!request || !signature || signature.bytes.length !== 64) {
|
|
509
|
+
throw new error_1.SigningError('SIGNING_FAILED', 'the wallet signature is missing');
|
|
510
|
+
}
|
|
511
|
+
const payload = unsigned.payload.encoding === 'base64'
|
|
512
|
+
? (0, messages_1.cellFromBoc)(unsigned.payload.data)
|
|
513
|
+
: null;
|
|
514
|
+
if (!payload) {
|
|
515
|
+
throw new error_1.SigningError('SIGNING_FAILED', 'the unsigned TON payload does not parse');
|
|
516
|
+
}
|
|
517
|
+
// The signature goes only where the rest of the request hashes to its digest.
|
|
518
|
+
const signed = (0, wallets_1.signedRequest)(payload, request.payload, signature.bytes);
|
|
519
|
+
const validFrom = boundOrdering(unsigned.ordering, signed, request.publicKey, ctx.config.globalId);
|
|
520
|
+
const id = hex((0, wallets_1.normalizedHash)(signed));
|
|
521
|
+
// Assembled here and not sent yet, for the replay guard. A repeat keeps the record
|
|
522
|
+
// as it is, so it never makes sent bytes look unsent.
|
|
523
|
+
if (!ctx.assembled.has(id)) {
|
|
524
|
+
const record = {
|
|
525
|
+
validFrom,
|
|
526
|
+
assembledAt: ctx.clock.now(),
|
|
527
|
+
sent: false,
|
|
528
|
+
};
|
|
529
|
+
(0, reader_1.keep)(ctx.assembled, id, record, reader_1.ASSEMBLED_MEMO);
|
|
530
|
+
}
|
|
531
|
+
return {
|
|
532
|
+
raw: { encoding: 'base64', data: signed.toBoc().toString('base64') },
|
|
533
|
+
ref: { id, idKind: 'message-hash', canonical: false },
|
|
534
|
+
};
|
|
535
|
+
},
|
|
536
|
+
};
|
|
537
|
+
}
|
|
538
|
+
/**
|
|
539
|
+
* The proofs and the replay guard read the Attempt's stored ordering, never the bytes, so
|
|
540
|
+
* it must be the signed request's own (the Tron and Solana builders bind theirs the same
|
|
541
|
+
* way): a `seqno` ordering with the request's seqno and `valid_until`, a well-formed
|
|
542
|
+
* recorded start, and a request whose signature verifies under the signing key and whose
|
|
543
|
+
* wallet id that key derives into the message's destination. An ordering changed on its
|
|
544
|
+
* way through a store would otherwise move the proof's window. Returns the recorded
|
|
545
|
+
* start.
|
|
546
|
+
*/
|
|
547
|
+
function boundOrdering(ordering, signed, publicKey, globalId) {
|
|
548
|
+
const refuse = () => new error_1.SigningError('SIGNING_FAILED', "the Attempt's ordering does not match the signed TON request");
|
|
549
|
+
let external;
|
|
550
|
+
try {
|
|
551
|
+
external = (0, core_1.loadMessage)(signed.beginParse());
|
|
552
|
+
}
|
|
553
|
+
catch {
|
|
554
|
+
throw refuse();
|
|
555
|
+
}
|
|
556
|
+
const slot = ordering;
|
|
557
|
+
const request = external.info.type === 'external-in' ? (0, messages_1.decodeWalletRequest)(external.body) : null;
|
|
558
|
+
if (external.info.type !== 'external-in' ||
|
|
559
|
+
request === null ||
|
|
560
|
+
slot?.kind !== 'seqno' ||
|
|
561
|
+
typeof slot.seqno !== 'bigint' ||
|
|
562
|
+
slot.seqno !== BigInt(request.seqno) ||
|
|
563
|
+
slot.validUntil !== request.validUntil ||
|
|
564
|
+
!(0, wallets_1.requestIsOwn)(external.info.dest.toRawString(), external.body, publicKey, globalId)) {
|
|
565
|
+
throw refuse();
|
|
566
|
+
}
|
|
567
|
+
const validFrom = (0, network_1.recordedValidFrom)({ ...slot, validUntil: request.validUntil });
|
|
568
|
+
if (validFrom === undefined)
|
|
569
|
+
throw refuse();
|
|
570
|
+
return validFrom;
|
|
571
|
+
}
|
|
572
|
+
const MALFORMED = Object.freeze({
|
|
573
|
+
kind: 'rejected',
|
|
574
|
+
reason: 'malformed message',
|
|
575
|
+
});
|
|
576
|
+
const ALREADY_KNOWN = Object.freeze({ kind: 'already-known' });
|
|
577
|
+
/**
|
|
578
|
+
* Raw bytes as the broadcaster reads them (through the capped `cellFromBoc`: a bare
|
|
579
|
+
* broadcast's bytes are anyone's): their TEP-467 hash, and, when their body carries a
|
|
580
|
+
* wallet request's signed header, what the replay guard needs. Null when they are no
|
|
581
|
+
* external message.
|
|
582
|
+
*/
|
|
583
|
+
function storedOf(data) {
|
|
584
|
+
const cell = (0, messages_1.cellFromBoc)(data);
|
|
585
|
+
if (!cell)
|
|
586
|
+
return null;
|
|
587
|
+
try {
|
|
588
|
+
const external = (0, core_1.loadMessage)(cell.beginParse());
|
|
589
|
+
if (external.info.type !== 'external-in')
|
|
590
|
+
return null;
|
|
591
|
+
const id = hex((0, wallets_1.normalizedHash)(cell));
|
|
592
|
+
const header = (0, messages_1.requestHeaderOf)(external.body);
|
|
593
|
+
if (!header)
|
|
594
|
+
return { id };
|
|
595
|
+
return {
|
|
596
|
+
id,
|
|
597
|
+
message: {
|
|
598
|
+
wallet: external.info.dest.toRawString(),
|
|
599
|
+
id,
|
|
600
|
+
seqno: BigInt(header.seqno),
|
|
601
|
+
validUntil: header.validUntil,
|
|
602
|
+
},
|
|
603
|
+
};
|
|
604
|
+
}
|
|
605
|
+
catch {
|
|
606
|
+
return null;
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
/**
|
|
610
|
+
* The replay guard's answer for stored bytes (`replayVerdict`). One that cannot decide
|
|
611
|
+
* never sends: its reason is logged by code, and the send fails with a retryable error,
|
|
612
|
+
* which the engine records as ambiguous (the monitor and the proof go on), never as a
|
|
613
|
+
* refusal: a non-retryable `TX_REFUSED` would invite a caller's retry with a new seqno.
|
|
614
|
+
*/
|
|
615
|
+
async function guarded(ctx, message) {
|
|
616
|
+
try {
|
|
617
|
+
return await (0, proofs_1.replayVerdict)(ctx, message);
|
|
618
|
+
}
|
|
619
|
+
catch (error) {
|
|
620
|
+
ctx.log.warn('stored bytes were not sent again: they may already have run', {
|
|
621
|
+
code: 'RESEND_WITHHELD',
|
|
622
|
+
});
|
|
623
|
+
throw new error_1.ProviderError('PROVIDER_UNAVAILABLE', 'not sent: the replay guard could not rule out an earlier run of this message', { retryable: true, ...((0, error_1.isCryptoAioError)(error) ? { cause: error } : {}) });
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
/** The node's own error text inside a v2 error body (`{ ok: false, error }`), if any. */
|
|
627
|
+
function nodeText(body) {
|
|
628
|
+
if (typeof body !== 'string')
|
|
629
|
+
return undefined;
|
|
630
|
+
try {
|
|
631
|
+
const parsed = JSON.parse(body);
|
|
632
|
+
if (parsed !== null && typeof parsed === 'object') {
|
|
633
|
+
const text = parsed.error;
|
|
634
|
+
if (typeof text === 'string')
|
|
635
|
+
return text;
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
catch {
|
|
639
|
+
// Not JSON, or cut by the transport: the body itself is the text.
|
|
640
|
+
}
|
|
641
|
+
return body;
|
|
642
|
+
}
|
|
643
|
+
function createTonBroadcaster(ctx) {
|
|
644
|
+
return {
|
|
645
|
+
async broadcast(signed, options = {}) {
|
|
646
|
+
// Bytes that are no external message can never be valid anywhere: `rejected`, from
|
|
647
|
+
// our own parse, is the only rejection, never a node's text: toncenter's refusals
|
|
648
|
+
// are unstructured, and a lying endpoint could claim one for bytes it then relays.
|
|
649
|
+
if (signed.raw.encoding !== 'base64')
|
|
650
|
+
return MALFORMED;
|
|
651
|
+
const stored = storedOf(signed.raw.data);
|
|
652
|
+
if (stored === null)
|
|
653
|
+
return MALFORMED;
|
|
654
|
+
const expected = stored.id;
|
|
655
|
+
// Bytes this driver assembled and never sent cannot have run anywhere, so a first
|
|
656
|
+
// send goes out at once, within FIRST_SEND_MS of `assemble` (later, another process
|
|
657
|
+
// sharing the store may have sent them). Every other send of stored bytes (a
|
|
658
|
+
// resend, a dropped rebroadcast, recovery, a caller's same-key retry, bytes from
|
|
659
|
+
// another process or a bare broadcast) asks the chain first: already run means
|
|
660
|
+
// never again. Resending the same bytes is not idempotent on TON: a wallet deleted
|
|
661
|
+
// and re-deployed from its `StateInit` counts its seqno from 0 again, so a message
|
|
662
|
+
// that already ran can run, and pay, twice.
|
|
663
|
+
const record = ctx.assembled.get(expected);
|
|
664
|
+
const first = record?.sent === false && soonAfter(ctx.clock.now() - record.assembledAt);
|
|
665
|
+
if (stored.message !== undefined && !first) {
|
|
666
|
+
const verdict = await guarded(ctx, {
|
|
667
|
+
...stored.message,
|
|
668
|
+
...(record ? { validFrom: record.validFrom } : {}),
|
|
669
|
+
});
|
|
670
|
+
if (verdict === 'ours')
|
|
671
|
+
return ALREADY_KNOWN;
|
|
672
|
+
}
|
|
673
|
+
if (record)
|
|
674
|
+
record.sent = true;
|
|
675
|
+
try {
|
|
676
|
+
const sent = await ctx.api.send(signed.raw.data, {
|
|
677
|
+
...api_1.BROADCAST,
|
|
678
|
+
...(options.fanout !== undefined ? { fanout: options.fanout } : {}),
|
|
679
|
+
...(options.signal ? { signal: options.signal } : {}),
|
|
680
|
+
});
|
|
681
|
+
if (sent.hashNorm !== expected) {
|
|
682
|
+
ctx.log.warn('the node reports another normalized message hash', {
|
|
683
|
+
code: 'MESSAGE_HASH_MISMATCH',
|
|
684
|
+
});
|
|
685
|
+
}
|
|
686
|
+
return { kind: 'accepted' };
|
|
687
|
+
}
|
|
688
|
+
catch (error) {
|
|
689
|
+
// Only a definitive 4xx answer is classified, and the classifier itself throws a
|
|
690
|
+
// retryable, ambiguous error for a "not now" answer. A
|
|
691
|
+
// 429, 408, 5xx (toncenter's refusals), a timeout or any answer after an attempt
|
|
692
|
+
// that may have been delivered goes back unchanged: the ambiguous path.
|
|
693
|
+
if ((0, error_1.isCryptoAioError)(error, 'RPC_ERROR') && !error.ambiguous) {
|
|
694
|
+
return (0, errors_1.classifyBroadcastError)(nodeText(error.details?.body) ?? error.message);
|
|
695
|
+
}
|
|
696
|
+
throw error;
|
|
697
|
+
}
|
|
698
|
+
},
|
|
699
|
+
};
|
|
700
|
+
}
|
|
701
|
+
//# sourceMappingURL=builder.js.map
|