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,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.contradiction = exports.undecided = exports.LocationCache = exports.SCAN_DEPTH = exports.withSignal = exports.PROOF = exports.MONITOR = exports.READ = void 0;
|
|
4
|
+
exports.proofRead = proofRead;
|
|
5
|
+
exports.locate = locate;
|
|
6
|
+
/**
|
|
7
|
+
* What every Avalanche port is built from, the transport tags of the `ChainDriver` contract
|
|
8
|
+
* table, and the locator: which accepted block holds a transaction.
|
|
9
|
+
*
|
|
10
|
+
* AvalancheGo can say a transaction is accepted, never in which block. The locator asks the
|
|
11
|
+
* Data API, then checks the answer against the node's block; a transaction the indexer does
|
|
12
|
+
* not know yet (it trails the chain by seconds) is looked for in the newest `SCAN_DEPTH`
|
|
13
|
+
* blocks. Accepted blocks never change (Snowman finality), so a location is kept once found.
|
|
14
|
+
* A location found on one endpoint is only a candidate for proofs: every proof re-reads its
|
|
15
|
+
* block under the proof quorum, and a candidate the quorum contradicts is forgotten.
|
|
16
|
+
*/
|
|
17
|
+
const error_1 = require("../../core/errors/error");
|
|
18
|
+
exports.READ = { purpose: 'read', retry: 'safe' };
|
|
19
|
+
exports.MONITOR = { purpose: 'monitor', retry: 'safe' };
|
|
20
|
+
exports.PROOF = {
|
|
21
|
+
purpose: 'proof',
|
|
22
|
+
retry: 'safe',
|
|
23
|
+
quorum: 'proof',
|
|
24
|
+
};
|
|
25
|
+
const withSignal = (tags, signal) => (signal ? { ...tags, signal } : tags);
|
|
26
|
+
exports.withSignal = withSignal;
|
|
27
|
+
/** How many blocks below the head the locator reads when the indexer does not know a tx. */
|
|
28
|
+
exports.SCAN_DEPTH = 16;
|
|
29
|
+
/** Locations kept per driver (oldest dropped first). */
|
|
30
|
+
const LOCATIONS = 10_000;
|
|
31
|
+
class LocationCache {
|
|
32
|
+
#entries = new Map();
|
|
33
|
+
get(txId) {
|
|
34
|
+
return this.#entries.get(txId);
|
|
35
|
+
}
|
|
36
|
+
set(txId, location) {
|
|
37
|
+
this.#entries.set(txId, location);
|
|
38
|
+
if (this.#entries.size > LOCATIONS) {
|
|
39
|
+
this.#entries.delete(this.#entries.keys().next().value);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
forget(txId) {
|
|
43
|
+
this.#entries.delete(txId);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
exports.LocationCache = LocationCache;
|
|
47
|
+
const undecided = (reason) => new error_1.ProviderError('PROVIDER_UNAVAILABLE', reason);
|
|
48
|
+
exports.undecided = undecided;
|
|
49
|
+
/** Two reads that cannot both hold decide nothing (retryable). */
|
|
50
|
+
const contradiction = (reason) => new error_1.ProviderError('PROVIDER_INCONSISTENT', reason, { retryable: true });
|
|
51
|
+
exports.contradiction = contradiction;
|
|
52
|
+
/**
|
|
53
|
+
* On a proof path only a definitive negative proof may answer "no".
|
|
54
|
+
* Every other non-retryable provider error (a JSON-RPC error that is not a "not found" the
|
|
55
|
+
* caller already mapped, a proxy's 4xx, a 401/403) becomes a retryable
|
|
56
|
+
* `PROVIDER_UNAVAILABLE` here, so it never decides anything. Retryable errors pass as they
|
|
57
|
+
* are. The cost is liveness only.
|
|
58
|
+
*/
|
|
59
|
+
async function proofRead(read) {
|
|
60
|
+
try {
|
|
61
|
+
return await read();
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
if ((0, error_1.isCryptoAioError)(error) && error.category === 'provider' && !error.retryable) {
|
|
65
|
+
throw new error_1.ProviderError('PROVIDER_UNAVAILABLE', 'the proof read failed on this endpoint; nothing is decided', { cause: error });
|
|
66
|
+
}
|
|
67
|
+
throw error;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/** A location is a candidate, read on one endpoint: never a quorum read. */
|
|
71
|
+
const singleRead = (tags) => ({
|
|
72
|
+
purpose: tags.purpose === 'proof' ? 'monitor' : (tags.purpose ?? 'read'),
|
|
73
|
+
retry: 'safe',
|
|
74
|
+
...(tags.signal ? { signal: tags.signal } : {}),
|
|
75
|
+
});
|
|
76
|
+
/**
|
|
77
|
+
* The accepted block holding `txId`, a transaction the node has accepted: from the cache,
|
|
78
|
+
* else the indexer (checked against the node's block at its height), else the newest
|
|
79
|
+
* `SCAN_DEPTH` blocks. `undefined` when none of them names it yet, `'no-block'` for an
|
|
80
|
+
* X-Chain transaction from before the chain had blocks. Reads are single
|
|
81
|
+
* (`monitor` or `read`) reads: a location is a candidate; proofs re-read it under quorum.
|
|
82
|
+
*/
|
|
83
|
+
async function locate(ctx, txId, tags) {
|
|
84
|
+
const cached = ctx.located.get(txId);
|
|
85
|
+
if (cached)
|
|
86
|
+
return cached;
|
|
87
|
+
const read = singleRead(tags);
|
|
88
|
+
const indexed = await ctx.dataApi.locate(txId, read);
|
|
89
|
+
// An X-Chain transaction accepted before the linearization (April 2023) has no block.
|
|
90
|
+
if (indexed === 'no-block')
|
|
91
|
+
return 'no-block';
|
|
92
|
+
if (indexed !== null) {
|
|
93
|
+
const block = await ctx.node.blockAt(indexed.height, read);
|
|
94
|
+
if (block === null)
|
|
95
|
+
return undefined; // the node has not reached it yet
|
|
96
|
+
if (block.id !== indexed.hash || !block.txIds.includes(txId)) {
|
|
97
|
+
throw (0, exports.contradiction)("the indexer's block for the transaction is not the node's");
|
|
98
|
+
}
|
|
99
|
+
ctx.located.set(txId, indexed);
|
|
100
|
+
return indexed;
|
|
101
|
+
}
|
|
102
|
+
const head = await ctx.node.height(read);
|
|
103
|
+
const lowest = head - BigInt(exports.SCAN_DEPTH) + 1n;
|
|
104
|
+
for (let height = head; height >= 0n && height >= lowest; height--) {
|
|
105
|
+
const block = await ctx.node.blockAt(height, read);
|
|
106
|
+
if (block?.txIds.includes(txId)) {
|
|
107
|
+
const found = { height: block.height, hash: block.id };
|
|
108
|
+
ctx.located.set(txId, found);
|
|
109
|
+
return found;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return undefined;
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../../src/adapters/avalanche/context.ts"],"names":[],"mappings":";;;AAiFA,8BAaC;AAgBD,wBA+BC;AA7ID;;;;;;;;;;GAUG;AACH,mDAA0E;AAQ7D,QAAA,IAAI,GAAsB,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AAC7D,QAAA,OAAO,GAAsB,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AACnE,QAAA,KAAK,GAAsB;IACtC,OAAO,EAAE,OAAO;IAChB,KAAK,EAAE,MAAM;IACb,MAAM,EAAE,OAAO;CAChB,CAAC;AAEK,MAAM,UAAU,GAAG,CACxB,IAAuB,EACvB,MAAoB,EACD,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AAHjD,QAAA,UAAU,cAGuC;AAE9D,4FAA4F;AAC/E,QAAA,UAAU,GAAG,EAAE,CAAC;AAC7B,wDAAwD;AACxD,MAAM,SAAS,GAAG,MAAM,CAAC;AAEzB,MAAa,aAAa;IACf,QAAQ,GAAG,IAAI,GAAG,EAAoB,CAAC;IAEhD,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAED,GAAG,CAAC,IAAY,EAAE,QAAkB;QAClC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAClC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,GAAG,SAAS,EAAE,CAAC;YACnC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAe,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;IAED,MAAM,CAAC,IAAY;QACjB,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;CACF;AAjBD,sCAiBC;AAaM,MAAM,SAAS,GAAG,CAAC,MAAc,EAAiB,EAAE,CACzD,IAAI,qBAAa,CAAC,sBAAsB,EAAE,MAAM,CAAC,CAAC;AADvC,QAAA,SAAS,aAC8B;AAEpD,kEAAkE;AAC3D,MAAM,aAAa,GAAG,CAAC,MAAc,EAAiB,EAAE,CAC7D,IAAI,qBAAa,CAAC,uBAAuB,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAD7D,QAAA,aAAa,iBACgD;AAE1E;;;;;;GAMG;AACI,KAAK,UAAU,SAAS,CAAI,IAAsB;IACvD,IAAI,CAAC;QACH,OAAO,MAAM,IAAI,EAAE,CAAC;IACtB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,IAAA,wBAAgB,EAAC,KAAK,CAAC,IAAI,KAAK,CAAC,QAAQ,KAAK,UAAU,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;YACjF,MAAM,IAAI,qBAAa,CACrB,sBAAsB,EACtB,4DAA4D,EAC5D,EAAE,KAAK,EAAE,KAAK,EAAE,CACjB,CAAC;QACJ,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,GAAG,CAAC,IAAuB,EAAqB,EAAE,CAAC,CAAC;IAClE,OAAO,EAAE,IAAI,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,IAAI,MAAM,CAAC;IACxE,KAAK,EAAE,MAAM;IACb,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;CAChD,CAAC,CAAC;AAEH;;;;;;GAMG;AACI,KAAK,UAAU,MAAM,CAC1B,GAAqB,EACrB,IAAY,EACZ,IAAuB;IAEvB,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACrC,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAC1B,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IAC9B,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACrD,sFAAsF;IACtF,IAAI,OAAO,KAAK,UAAU;QAAE,OAAO,UAAU,CAAC;IAC9C,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACrB,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAC3D,IAAI,KAAK,KAAK,IAAI;YAAE,OAAO,SAAS,CAAC,CAAC,kCAAkC;QACxE,IAAI,KAAK,CAAC,EAAE,KAAK,OAAO,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7D,MAAM,IAAA,qBAAa,EAAC,2DAA2D,CAAC,CAAC;QACnF,CAAC;QACD,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC/B,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,IAAI,GAAG,MAAM,CAAC,kBAAU,CAAC,GAAG,EAAE,CAAC;IAC9C,KAAK,IAAI,MAAM,GAAG,IAAI,EAAE,MAAM,IAAI,EAAE,IAAI,MAAM,IAAI,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC;QACnE,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACnD,IAAI,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAChC,MAAM,KAAK,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC;YACvD,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YAC7B,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC","sourcesContent":["/**\n * What every Avalanche port is built from, the transport tags of the `ChainDriver` contract\n * table, and the locator: which accepted block holds a transaction.\n *\n * AvalancheGo can say a transaction is accepted, never in which block. The locator asks the\n * Data API, then checks the answer against the node's block; a transaction the indexer does\n * not know yet (it trails the chain by seconds) is looked for in the newest `SCAN_DEPTH`\n * blocks. Accepted blocks never change (Snowman finality), so a location is kept once found.\n * A location found on one endpoint is only a candidate for proofs: every proof re-reads its\n * block under the proof quorum, and a candidate the quorum contradicts is forgotten.\n */\nimport { ProviderError, isCryptoAioError } from '../../core/errors/error';\nimport type { Logger } from '../../core/events/logger';\nimport type { ChainInfo, NetworkInfo } from '../../core/model/chain';\nimport type { Clock } from '../../core/util/clock';\nimport type { AvalancheNode, DataApi, Location } from './api';\nimport type { AvalancheNetworkConfig } from './network';\nimport type { AvalancheCallTags } from './types';\n\nexport const READ: AvalancheCallTags = { purpose: 'read', retry: 'safe' };\nexport const MONITOR: AvalancheCallTags = { purpose: 'monitor', retry: 'safe' };\nexport const PROOF: AvalancheCallTags = {\n purpose: 'proof',\n retry: 'safe',\n quorum: 'proof',\n};\n\nexport const withSignal = (\n tags: AvalancheCallTags,\n signal?: AbortSignal,\n): AvalancheCallTags => (signal ? { ...tags, signal } : tags);\n\n/** How many blocks below the head the locator reads when the indexer does not know a tx. */\nexport const SCAN_DEPTH = 16;\n/** Locations kept per driver (oldest dropped first). */\nconst LOCATIONS = 10_000;\n\nexport class LocationCache {\n readonly #entries = new Map<string, Location>();\n\n get(txId: string): Location | undefined {\n return this.#entries.get(txId);\n }\n\n set(txId: string, location: Location): void {\n this.#entries.set(txId, location);\n if (this.#entries.size > LOCATIONS) {\n this.#entries.delete(this.#entries.keys().next().value as string);\n }\n }\n\n forget(txId: string): void {\n this.#entries.delete(txId);\n }\n}\n\nexport interface AvalancheContext {\n readonly node: AvalancheNode;\n readonly dataApi: DataApi;\n readonly chain: ChainInfo;\n readonly network: NetworkInfo;\n readonly config: AvalancheNetworkConfig;\n readonly clock: Clock;\n readonly log: Logger;\n readonly located: LocationCache;\n}\n\nexport const undecided = (reason: string): ProviderError =>\n new ProviderError('PROVIDER_UNAVAILABLE', reason);\n\n/** Two reads that cannot both hold decide nothing (retryable). */\nexport const contradiction = (reason: string): ProviderError =>\n new ProviderError('PROVIDER_INCONSISTENT', reason, { retryable: true });\n\n/**\n * On a proof path only a definitive negative proof may answer \"no\".\n * Every other non-retryable provider error (a JSON-RPC error that is not a \"not found\" the\n * caller already mapped, a proxy's 4xx, a 401/403) becomes a retryable\n * `PROVIDER_UNAVAILABLE` here, so it never decides anything. Retryable errors pass as they\n * are. The cost is liveness only.\n */\nexport async function proofRead<T>(read: () => Promise<T>): Promise<T> {\n try {\n return await read();\n } catch (error) {\n if (isCryptoAioError(error) && error.category === 'provider' && !error.retryable) {\n throw new ProviderError(\n 'PROVIDER_UNAVAILABLE',\n 'the proof read failed on this endpoint; nothing is decided',\n { cause: error },\n );\n }\n throw error;\n }\n}\n\n/** A location is a candidate, read on one endpoint: never a quorum read. */\nconst singleRead = (tags: AvalancheCallTags): AvalancheCallTags => ({\n purpose: tags.purpose === 'proof' ? 'monitor' : (tags.purpose ?? 'read'),\n retry: 'safe',\n ...(tags.signal ? { signal: tags.signal } : {}),\n});\n\n/**\n * The accepted block holding `txId`, a transaction the node has accepted: from the cache,\n * else the indexer (checked against the node's block at its height), else the newest\n * `SCAN_DEPTH` blocks. `undefined` when none of them names it yet, `'no-block'` for an\n * X-Chain transaction from before the chain had blocks. Reads are single\n * (`monitor` or `read`) reads: a location is a candidate; proofs re-read it under quorum.\n */\nexport async function locate(\n ctx: AvalancheContext,\n txId: string,\n tags: AvalancheCallTags,\n): Promise<Location | 'no-block' | undefined> {\n const cached = ctx.located.get(txId);\n if (cached) return cached;\n const read = singleRead(tags);\n const indexed = await ctx.dataApi.locate(txId, read);\n // An X-Chain transaction accepted before the linearization (April 2023) has no block.\n if (indexed === 'no-block') return 'no-block';\n if (indexed !== null) {\n const block = await ctx.node.blockAt(indexed.height, read);\n if (block === null) return undefined; // the node has not reached it yet\n if (block.id !== indexed.hash || !block.txIds.includes(txId)) {\n throw contradiction(\"the indexer's block for the transaction is not the node's\");\n }\n ctx.located.set(txId, indexed);\n return indexed;\n }\n const head = await ctx.node.height(read);\n const lowest = head - BigInt(SCAN_DEPTH) + 1n;\n for (let height = head; height >= 0n && height >= lowest; height--) {\n const block = await ctx.node.blockAt(height, read);\n if (block?.txIds.includes(txId)) {\n const found = { height: block.height, hash: block.id };\n ctx.located.set(txId, found);\n return found;\n }\n }\n return undefined;\n}\n"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An Avalanche transaction as the core reads it, from its signed bytes.
|
|
3
|
+
* - Transfers: each plain AVAX output of the transaction's own outputs (its base outputs,
|
|
4
|
+
* on this chain) to one address, unlocked, threshold 1: `out:<index>`, the output's index
|
|
5
|
+
* in its UTXO id. The senders are the addresses the signatures recover to.
|
|
6
|
+
* - `decoding: 'complete'` only for a BaseTx or ImportTx whose every output is such a
|
|
7
|
+
* transfer. An export (value leaves for another chain), a staking or subnet transaction,
|
|
8
|
+
* a reward, another asset, a locked or multi-owner output, or a type this SDK cannot read
|
|
9
|
+
* is `partial`; bytes that do not parse are `none`.
|
|
10
|
+
* - `details.signers`: the addresses that signed it, whatever it did.
|
|
11
|
+
* - The fee is the AVAX the transaction burns. A memo that is UTF-8 text becomes the
|
|
12
|
+
* transfers' memo; the raw memo is in `details.memo` (hex).
|
|
13
|
+
*/
|
|
14
|
+
import type { DriverTransaction, DriverTxObservation } from '../../core/driver/types';
|
|
15
|
+
import type { AvalancheNetworkConfig } from './network';
|
|
16
|
+
export declare function decodeTransaction(bytes: Uint8Array, config: AvalancheNetworkConfig, observation: DriverTxObservation): DriverTransaction;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.decodeTransaction = decodeTransaction;
|
|
4
|
+
const bytes_1 = require("../../core/util/bytes");
|
|
5
|
+
const address_1 = require("./address");
|
|
6
|
+
const cb58_1 = require("./cb58");
|
|
7
|
+
const codec_1 = require("./codec");
|
|
8
|
+
const sdk_1 = require("./sdk");
|
|
9
|
+
const COMPLETE_TYPES = new Set([
|
|
10
|
+
'avm.BaseTx',
|
|
11
|
+
'pvm.BaseTx',
|
|
12
|
+
'avm.ImportTx',
|
|
13
|
+
'pvm.ImportTx',
|
|
14
|
+
]);
|
|
15
|
+
const utf8 = new TextDecoder('utf-8', { fatal: true });
|
|
16
|
+
function memoText(memo) {
|
|
17
|
+
if (memo.length === 0)
|
|
18
|
+
return undefined;
|
|
19
|
+
try {
|
|
20
|
+
return utf8.decode(memo);
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/** The AVAX `tx` burns, or `undefined` when the SDK cannot say. */
|
|
27
|
+
function burnedAvax(tx, config) {
|
|
28
|
+
try {
|
|
29
|
+
const burned = sdk_1.avalanche.utils
|
|
30
|
+
.getBurnedAmountByTx(tx, (0, codec_1.sdkContext)(config))
|
|
31
|
+
.get(config.avaxAssetId);
|
|
32
|
+
return burned !== undefined && burned >= 0n ? burned : undefined;
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function decodeTransaction(bytes, config, observation) {
|
|
39
|
+
const raw = { encoding: 'hex', data: (0, bytes_1.toHex)(bytes) };
|
|
40
|
+
let parsed;
|
|
41
|
+
try {
|
|
42
|
+
parsed = (0, codec_1.parseSignedTx)(bytes, config);
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
// A transaction type this SDK version cannot read: known only by its id.
|
|
46
|
+
return {
|
|
47
|
+
id: (0, cb58_1.idOf)(bytes),
|
|
48
|
+
observation,
|
|
49
|
+
transfers: [],
|
|
50
|
+
decoding: 'none',
|
|
51
|
+
raw,
|
|
52
|
+
details: { type: 'unknown' },
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
const { tx } = parsed;
|
|
56
|
+
const base = tx.baseTx;
|
|
57
|
+
const from = (0, codec_1.signersOf)(parsed).map((address) => (0, address_1.formatAddress)(address, config));
|
|
58
|
+
const memoBytes = base?.memo.bytes ?? new Uint8Array();
|
|
59
|
+
const memo = memoText(memoBytes);
|
|
60
|
+
const transfers = [];
|
|
61
|
+
let complete = COMPLETE_TYPES.has(tx._type) && base !== undefined;
|
|
62
|
+
base?.outputs.forEach((output, index) => {
|
|
63
|
+
const owners = output.output._type === sdk_1.TYPES.transferOutput
|
|
64
|
+
? output.output.outputOwners
|
|
65
|
+
: undefined;
|
|
66
|
+
if (output.assetId.toString() !== config.avaxAssetId ||
|
|
67
|
+
owners === undefined ||
|
|
68
|
+
owners.locktime.value() !== 0n ||
|
|
69
|
+
owners.threshold.value() !== 1 ||
|
|
70
|
+
owners.addrs.length !== 1) {
|
|
71
|
+
complete = false;
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
transfers.push({
|
|
75
|
+
locator: `out:${index}`,
|
|
76
|
+
from,
|
|
77
|
+
to: (0, address_1.formatAddress)(owners.addrs[0]?.toBytes(), config),
|
|
78
|
+
asset: 'native',
|
|
79
|
+
amount: output.amount(),
|
|
80
|
+
source: 'native',
|
|
81
|
+
...(memo !== undefined ? { memo } : {}),
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
const fee = burnedAvax(tx, config);
|
|
85
|
+
return {
|
|
86
|
+
id: parsed.id,
|
|
87
|
+
observation,
|
|
88
|
+
...(fee !== undefined && fee > 0n
|
|
89
|
+
? { fee: [{ asset: 'native', amount: fee }] }
|
|
90
|
+
: {}),
|
|
91
|
+
transfers,
|
|
92
|
+
decoding: complete ? 'complete' : 'partial',
|
|
93
|
+
raw,
|
|
94
|
+
details: {
|
|
95
|
+
type: tx._type,
|
|
96
|
+
signers: from,
|
|
97
|
+
...(memoBytes.length > 0 ? { memo: (0, bytes_1.toHex)(memoBytes) } : {}),
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=decode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decode.js","sourceRoot":"","sources":["../../../src/adapters/avalanche/decode.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * An Avalanche transaction as the core reads it, from its signed bytes.\n * - Transfers: each plain AVAX output of the transaction's own outputs (its base outputs,\n * on this chain) to one address, unlocked, threshold 1: `out:<index>`, the output's index\n * in its UTXO id. The senders are the addresses the signatures recover to.\n * - `decoding: 'complete'` only for a BaseTx or ImportTx whose every output is such a\n * transfer. An export (value leaves for another chain), a staking or subnet transaction,\n * a reward, another asset, a locked or multi-owner output, or a type this SDK cannot read\n * is `partial`; bytes that do not parse are `none`.\n * - `details.signers`: the addresses that signed it, whatever it did.\n * - The fee is the AVAX the transaction burns. A memo that is UTF-8 text becomes the\n * transfers' memo; the raw memo is in `details.memo` (hex).\n */\nimport type {\n DriverTransaction,\n DriverTransfer,\n DriverTxObservation,\n} from '../../core/driver/types';\nimport { toHex } from '../../core/util/bytes';\nimport { formatAddress } from './address';\nimport { idOf } from './cb58';\nimport { parseSignedTx, sdkContext, signersOf } from './codec';\nimport type { AvalancheNetworkConfig } from './network';\nimport { TYPES, avalanche, type SdkTransferOutput } from './sdk';\n\nconst COMPLETE_TYPES = new Set([\n 'avm.BaseTx',\n 'pvm.BaseTx',\n 'avm.ImportTx',\n 'pvm.ImportTx',\n]);\n\nconst utf8 = new TextDecoder('utf-8', { fatal: true });\n\nfunction memoText(memo: Uint8Array): string | undefined {\n if (memo.length === 0) return undefined;\n try {\n return utf8.decode(memo);\n } catch {\n return undefined;\n }\n}\n\n/** The AVAX `tx` burns, or `undefined` when the SDK cannot say. */\nfunction burnedAvax(\n tx: Parameters<typeof avalanche.utils.getBurnedAmountByTx>[0],\n config: AvalancheNetworkConfig,\n): bigint | undefined {\n try {\n const burned = avalanche.utils\n .getBurnedAmountByTx(tx, sdkContext(config))\n .get(config.avaxAssetId);\n return burned !== undefined && burned >= 0n ? burned : undefined;\n } catch {\n return undefined;\n }\n}\n\nexport function decodeTransaction(\n bytes: Uint8Array,\n config: AvalancheNetworkConfig,\n observation: DriverTxObservation,\n): DriverTransaction {\n const raw = { encoding: 'hex' as const, data: toHex(bytes) };\n let parsed: ReturnType<typeof parseSignedTx>;\n try {\n parsed = parseSignedTx(bytes, config);\n } catch {\n // A transaction type this SDK version cannot read: known only by its id.\n return {\n id: idOf(bytes),\n observation,\n transfers: [],\n decoding: 'none',\n raw,\n details: { type: 'unknown' },\n };\n }\n const { tx } = parsed;\n const base = tx.baseTx;\n const from = signersOf(parsed).map((address) => formatAddress(address, config));\n const memoBytes = base?.memo.bytes ?? new Uint8Array();\n const memo = memoText(memoBytes);\n const transfers: DriverTransfer[] = [];\n let complete = COMPLETE_TYPES.has(tx._type) && base !== undefined;\n base?.outputs.forEach((output, index) => {\n const owners =\n output.output._type === TYPES.transferOutput\n ? (output.output as SdkTransferOutput).outputOwners\n : undefined;\n if (\n output.assetId.toString() !== config.avaxAssetId ||\n owners === undefined ||\n owners.locktime.value() !== 0n ||\n owners.threshold.value() !== 1 ||\n owners.addrs.length !== 1\n ) {\n complete = false;\n return;\n }\n transfers.push({\n locator: `out:${index}`,\n from,\n to: formatAddress(owners.addrs[0]?.toBytes() as Uint8Array, config),\n asset: 'native',\n amount: output.amount(),\n source: 'native',\n ...(memo !== undefined ? { memo } : {}),\n });\n });\n const fee = burnedAvax(tx, config);\n return {\n id: parsed.id,\n observation,\n ...(fee !== undefined && fee > 0n\n ? { fee: [{ asset: 'native' as const, amount: fee }] }\n : {}),\n transfers,\n decoding: complete ? 'complete' : 'partial',\n raw,\n details: {\n type: tx._type,\n signers: from,\n ...(memoBytes.length > 0 ? { memo: toHex(memoBytes) } : {}),\n },\n };\n}\n"]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Avalanche driver factory: validated network config, endpoint probes on both
|
|
3
|
+
* transports, and the ports. Loaded only by the manifest's `load()`, with
|
|
4
|
+
* `@avalabs/avalanchejs`.
|
|
5
|
+
*/
|
|
6
|
+
import type { DriverFactory } from '../../core/driver/types';
|
|
7
|
+
import { type AvalancheSdk, type SdkContext } from './sdk';
|
|
8
|
+
export interface AvalancheNativeClient {
|
|
9
|
+
/**
|
|
10
|
+
* The `@avalabs/avalanchejs` module. Its type names the members this library uses; cast
|
|
11
|
+
* it to reach the rest of the SDK.
|
|
12
|
+
*/
|
|
13
|
+
readonly avalanche: AvalancheSdk;
|
|
14
|
+
/**
|
|
15
|
+
* avalanchejs's `Context` for this network and chain (network id, HRP, AVAX asset id,
|
|
16
|
+
* this chain's id). Its fee fields are zero: read the fees from the chain.
|
|
17
|
+
*/
|
|
18
|
+
readonly context: SdkContext;
|
|
19
|
+
/** A JSON-RPC call (e.g. `avm.getTxFee`) to the handle's node endpoints, through the transport. */
|
|
20
|
+
rpc<T = unknown>(method: string, params?: unknown): Promise<T>;
|
|
21
|
+
}
|
|
22
|
+
export declare const avalancheDriverFactory: DriverFactory;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.avalancheDriverFactory = void 0;
|
|
4
|
+
const error_1 = require("../../core/errors/error");
|
|
5
|
+
const api_1 = require("./api");
|
|
6
|
+
const builder_1 = require("./builder");
|
|
7
|
+
const codec_1 = require("./codec");
|
|
8
|
+
const context_1 = require("./context");
|
|
9
|
+
const network_1 = require("./network");
|
|
10
|
+
const proofs_1 = require("./proofs");
|
|
11
|
+
const reader_1 = require("./reader");
|
|
12
|
+
const sdk_1 = require("./sdk");
|
|
13
|
+
function nodeProbes(config) {
|
|
14
|
+
const prefix = config.vm === 'avm' ? 'avm' : 'platform';
|
|
15
|
+
return {
|
|
16
|
+
identity: async (call) => (0, api_1.parseBlock)(await call.rpc(`${prefix}.getBlockByHeight`, { height: '0', encoding: 'json' })).id,
|
|
17
|
+
expectedIdentity: config.genesisBlockId,
|
|
18
|
+
height: async (call) => (0, api_1.parseHeight)((await call.rpc(`${prefix}.getHeight`, {}))
|
|
19
|
+
?.height),
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function indexerProbes(config) {
|
|
23
|
+
return {
|
|
24
|
+
identity: async (call) => api_1.DataApi.blockZero(await call.http({ method: 'GET', path: '/blocks/0', route: '/blocks/:id' })),
|
|
25
|
+
expectedIdentity: config.genesisBlockId,
|
|
26
|
+
height: async (call) => api_1.DataApi.latestHeight(await call.http({
|
|
27
|
+
method: 'GET',
|
|
28
|
+
path: '/blocks',
|
|
29
|
+
query: { pageSize: '1' },
|
|
30
|
+
route: '/blocks',
|
|
31
|
+
})),
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
exports.avalancheDriverFactory = {
|
|
35
|
+
async create(ctx) {
|
|
36
|
+
const config = (0, network_1.avalancheNetworkConfig)(ctx.chain, ctx.network, ctx.options);
|
|
37
|
+
if (!ctx.indexer) {
|
|
38
|
+
throw new error_1.ConfigError('CONFIG_INVALID', 'the Avalanche driver requires an indexer provider (the Avalanche Data API)');
|
|
39
|
+
}
|
|
40
|
+
// Probes on both transports, once, before any traffic: without them an endpoint's
|
|
41
|
+
// identity is never checked, and an endpoint of another network is never disabled.
|
|
42
|
+
ctx.transport.setProbes(nodeProbes(config));
|
|
43
|
+
ctx.indexer.setProbes(indexerProbes(config));
|
|
44
|
+
const avax = {
|
|
45
|
+
node: new api_1.AvalancheNode(ctx.transport, config.vm),
|
|
46
|
+
dataApi: new api_1.DataApi(ctx.indexer),
|
|
47
|
+
chain: ctx.chain,
|
|
48
|
+
network: ctx.network,
|
|
49
|
+
config,
|
|
50
|
+
clock: ctx.clock,
|
|
51
|
+
log: ctx.log,
|
|
52
|
+
located: new context_1.LocationCache(),
|
|
53
|
+
};
|
|
54
|
+
return {
|
|
55
|
+
ordering: 'inputs',
|
|
56
|
+
capabilities: config.capabilities,
|
|
57
|
+
address: (0, reader_1.addressCodec)(avax),
|
|
58
|
+
reader: (0, reader_1.chainReader)(avax),
|
|
59
|
+
builder: (0, builder_1.avalancheBuilder)(avax),
|
|
60
|
+
broadcaster: (0, builder_1.avalancheBroadcaster)(avax),
|
|
61
|
+
proofs: (0, proofs_1.proofSource)(avax),
|
|
62
|
+
blocks: (0, proofs_1.blockSource)(avax),
|
|
63
|
+
history: (0, reader_1.addressHistory)(avax),
|
|
64
|
+
ext: {
|
|
65
|
+
avalanche: {
|
|
66
|
+
listUnspent: (address) => (0, reader_1.listUnspent)(avax, address),
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
limits: () => ({ maxOutputs: builder_1.MAX_OUTPUTS }),
|
|
70
|
+
createNativeClient: () => {
|
|
71
|
+
const client = {
|
|
72
|
+
avalanche: sdk_1.avalanche,
|
|
73
|
+
context: (0, codec_1.sdkContext)(config),
|
|
74
|
+
rpc: (method, params) => ctx.transport.rpc(method, params ?? {}, context_1.READ),
|
|
75
|
+
};
|
|
76
|
+
return { client };
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
//# sourceMappingURL=driver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"driver.js","sourceRoot":"","sources":["../../../src/adapters/avalanche/driver.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The Avalanche driver factory: validated network config, endpoint probes on both\n * transports, and the ports. Loaded only by the manifest's `load()`, with\n * `@avalabs/avalanchejs`.\n */\nimport type { ChainDriver, DriverContext, DriverFactory } from '../../core/driver/types';\nimport { ConfigError } from '../../core/errors/error';\nimport type { EndpointCall, HealthProbes } from '../../core/transport/types';\nimport { AvalancheNode, DataApi, parseBlock, parseHeight } from './api';\nimport { avalancheBroadcaster, avalancheBuilder, MAX_OUTPUTS } from './builder';\nimport { sdkContext } from './codec';\nimport { LocationCache, READ, type AvalancheContext } from './context';\nimport { avalancheNetworkConfig, type AvalancheNetworkConfig } from './network';\nimport { blockSource, proofSource } from './proofs';\nimport { addressCodec, addressHistory, chainReader, listUnspent } from './reader';\nimport { avalanche, type AvalancheSdk, type SdkContext } from './sdk';\nimport type { AvalancheExt } from './types';\n\nexport interface AvalancheNativeClient {\n /**\n * The `@avalabs/avalanchejs` module. Its type names the members this library uses; cast\n * it to reach the rest of the SDK.\n */\n readonly avalanche: AvalancheSdk;\n /**\n * avalanchejs's `Context` for this network and chain (network id, HRP, AVAX asset id,\n * this chain's id). Its fee fields are zero: read the fees from the chain.\n */\n readonly context: SdkContext;\n /** A JSON-RPC call (e.g. `avm.getTxFee`) to the handle's node endpoints, through the transport. */\n rpc<T = unknown>(method: string, params?: unknown): Promise<T>;\n}\n\nfunction nodeProbes(config: AvalancheNetworkConfig): HealthProbes {\n const prefix = config.vm === 'avm' ? 'avm' : 'platform';\n return {\n identity: async (call: EndpointCall) =>\n parseBlock(\n await call.rpc(`${prefix}.getBlockByHeight`, { height: '0', encoding: 'json' }),\n ).id,\n expectedIdentity: config.genesisBlockId,\n height: async (call: EndpointCall) =>\n parseHeight(\n ((await call.rpc(`${prefix}.getHeight`, {})) as { height?: unknown } | null)\n ?.height,\n ),\n };\n}\n\nfunction indexerProbes(config: AvalancheNetworkConfig): HealthProbes {\n return {\n identity: async (call: EndpointCall) =>\n DataApi.blockZero(\n await call.http({ method: 'GET', path: '/blocks/0', route: '/blocks/:id' }),\n ),\n expectedIdentity: config.genesisBlockId,\n height: async (call: EndpointCall) =>\n DataApi.latestHeight(\n await call.http({\n method: 'GET',\n path: '/blocks',\n query: { pageSize: '1' },\n route: '/blocks',\n }),\n ),\n };\n}\n\nexport const avalancheDriverFactory: DriverFactory = {\n async create(ctx: DriverContext): Promise<ChainDriver> {\n const config = avalancheNetworkConfig(ctx.chain, ctx.network, ctx.options);\n if (!ctx.indexer) {\n throw new ConfigError(\n 'CONFIG_INVALID',\n 'the Avalanche driver requires an indexer provider (the Avalanche Data API)',\n );\n }\n // Probes on both transports, once, before any traffic: without them an endpoint's\n // identity is never checked, and an endpoint of another network is never disabled.\n ctx.transport.setProbes(nodeProbes(config));\n ctx.indexer.setProbes(indexerProbes(config));\n const avax: AvalancheContext = {\n node: new AvalancheNode(ctx.transport, config.vm),\n dataApi: new DataApi(ctx.indexer),\n chain: ctx.chain,\n network: ctx.network,\n config,\n clock: ctx.clock,\n log: ctx.log,\n located: new LocationCache(),\n };\n return {\n ordering: 'inputs',\n capabilities: config.capabilities,\n address: addressCodec(avax),\n reader: chainReader(avax),\n builder: avalancheBuilder(avax),\n broadcaster: avalancheBroadcaster(avax),\n proofs: proofSource(avax),\n blocks: blockSource(avax),\n history: addressHistory(avax),\n ext: {\n avalanche: {\n listUnspent: (address: string) => listUnspent(avax, address),\n },\n } satisfies AvalancheExt,\n limits: () => ({ maxOutputs: MAX_OUTPUTS }),\n createNativeClient: () => {\n const client: AvalancheNativeClient = {\n avalanche,\n context: sdkContext(config),\n rpc: <T>(method: string, params?: unknown) =>\n ctx.transport.rpc<T>(method, params ?? {}, READ),\n };\n return { client };\n },\n };\n },\n};\n"]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Broadcast classification (pure). AvalancheGo answers a refused `issueTx` with a JSON-RPC
|
|
3
|
+
* error (-32000) whose message is its Go error chain, e.g. `couldn't issue tx: failed
|
|
4
|
+
* verification: failed to read consumed UTXO …: not found` (P-Chain) or `failed to get
|
|
5
|
+
* utxo …: not found` (X-Chain); the texts below are AvalancheGo's (`vms/txs/mempool`,
|
|
6
|
+
* `vms/components/avax`, `vms/platformvm/utxo`, `vms/secp256k1fx`). A node answers a
|
|
7
|
+
* duplicate with the id, as a success; the text is still recognized here.
|
|
8
|
+
*
|
|
9
|
+
* A node's rejection is a claim: a lone endpoint can claim one and relay the bytes
|
|
10
|
+
* anyway, and a terminal `rejected` would free the inputs for a retry that pays twice.
|
|
11
|
+
* Every transaction this driver builds is checked before it is signed and its signature
|
|
12
|
+
* verified by the core, so no answer here is `rejected`: each is a `refused`
|
|
13
|
+
* (state-dependent, never terminal) with a code, and the core first looks up the
|
|
14
|
+
* Attempt's own id. Reasons are fixed texts: the node's carry ids and amounts, which a
|
|
15
|
+
* stored reason must never hold.
|
|
16
|
+
*/
|
|
17
|
+
import type { BroadcastResult } from '../../core/driver/types';
|
|
18
|
+
export declare function classifyIssueError(message: string): BroadcastResult;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.classifyIssueError = classifyIssueError;
|
|
4
|
+
/** Only a message's head is read, so an oversized node text costs a bounded scan. */
|
|
5
|
+
const MAX_MESSAGE = 1_024;
|
|
6
|
+
const RULES = [
|
|
7
|
+
[/\bduplicate tx\b/, { kind: 'already-known' }],
|
|
8
|
+
[
|
|
9
|
+
/\binsufficient (?:unlocked )?funds\b/,
|
|
10
|
+
{
|
|
11
|
+
kind: 'refused',
|
|
12
|
+
code: 'FEE_TOO_LOW',
|
|
13
|
+
reason: 'the transaction burns less than the chain charges now',
|
|
14
|
+
},
|
|
15
|
+
],
|
|
16
|
+
[
|
|
17
|
+
/\bfailed to (?:get|read consumed) utxo\b/i,
|
|
18
|
+
{
|
|
19
|
+
kind: 'refused',
|
|
20
|
+
code: 'TX_REFUSED',
|
|
21
|
+
reason: 'an input is already spent, or not known to the node yet',
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
[
|
|
25
|
+
/\btx conflicts with other tx\b/,
|
|
26
|
+
{
|
|
27
|
+
kind: 'refused',
|
|
28
|
+
code: 'TX_REFUSED',
|
|
29
|
+
reason: 'it conflicts with a transaction in the mempool',
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
[
|
|
33
|
+
/\bmempool is full\b/,
|
|
34
|
+
{ kind: 'refused', code: 'TX_REFUSED', reason: 'the node mempool is full' },
|
|
35
|
+
],
|
|
36
|
+
[
|
|
37
|
+
/\btx too large\b/,
|
|
38
|
+
{
|
|
39
|
+
kind: 'refused',
|
|
40
|
+
code: 'TX_REFUSED',
|
|
41
|
+
reason: 'the transaction is larger than the mempool takes',
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
[
|
|
45
|
+
/\boutput is time locked\b/,
|
|
46
|
+
{ kind: 'refused', code: 'TX_REFUSED', reason: 'an input is still time locked' },
|
|
47
|
+
],
|
|
48
|
+
];
|
|
49
|
+
const DEFAULT = {
|
|
50
|
+
kind: 'refused',
|
|
51
|
+
code: 'TX_REFUSED',
|
|
52
|
+
reason: 'the node refused the transaction',
|
|
53
|
+
};
|
|
54
|
+
function classifyIssueError(message) {
|
|
55
|
+
const head = message.slice(0, MAX_MESSAGE);
|
|
56
|
+
for (const [pattern, result] of RULES)
|
|
57
|
+
if (pattern.test(head))
|
|
58
|
+
return result;
|
|
59
|
+
return DEFAULT;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/adapters/avalanche/errors.ts"],"names":[],"mappings":";;AAuEA,gDAIC;AAzDD,qFAAqF;AACrF,MAAM,WAAW,GAAG,KAAK,CAAC;AAE1B,MAAM,KAAK,GAAoD;IAC7D,CAAC,kBAAkB,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC;IAC/C;QACE,sCAAsC;QACtC;YACE,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,aAAa;YACnB,MAAM,EAAE,uDAAuD;SAChE;KACF;IACD;QACE,2CAA2C;QAC3C;YACE,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,YAAY;YAClB,MAAM,EAAE,yDAAyD;SAClE;KACF;IACD;QACE,gCAAgC;QAChC;YACE,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,YAAY;YAClB,MAAM,EAAE,gDAAgD;SACzD;KACF;IACD;QACE,qBAAqB;QACrB,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,0BAA0B,EAAE;KAC5E;IACD;QACE,kBAAkB;QAClB;YACE,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,YAAY;YAClB,MAAM,EAAE,kDAAkD;SAC3D;KACF;IACD;QACE,2BAA2B;QAC3B,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,+BAA+B,EAAE;KACjF;CACF,CAAC;AAEF,MAAM,OAAO,GAAoB;IAC/B,IAAI,EAAE,SAAS;IACf,IAAI,EAAE,YAAY;IAClB,MAAM,EAAE,kCAAkC;CAC3C,CAAC;AAEF,SAAgB,kBAAkB,CAAC,OAAe;IAChD,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;IAC3C,KAAK,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,KAAK;QAAE,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO,MAAM,CAAC;IAC7E,OAAO,OAAO,CAAC;AACjB,CAAC","sourcesContent":["/**\n * Broadcast classification (pure). AvalancheGo answers a refused `issueTx` with a JSON-RPC\n * error (-32000) whose message is its Go error chain, e.g. `couldn't issue tx: failed\n * verification: failed to read consumed UTXO …: not found` (P-Chain) or `failed to get\n * utxo …: not found` (X-Chain); the texts below are AvalancheGo's (`vms/txs/mempool`,\n * `vms/components/avax`, `vms/platformvm/utxo`, `vms/secp256k1fx`). A node answers a\n * duplicate with the id, as a success; the text is still recognized here.\n *\n * A node's rejection is a claim: a lone endpoint can claim one and relay the bytes\n * anyway, and a terminal `rejected` would free the inputs for a retry that pays twice.\n * Every transaction this driver builds is checked before it is signed and its signature\n * verified by the core, so no answer here is `rejected`: each is a `refused`\n * (state-dependent, never terminal) with a code, and the core first looks up the\n * Attempt's own id. Reasons are fixed texts: the node's carry ids and amounts, which a\n * stored reason must never hold.\n */\nimport type { BroadcastResult } from '../../core/driver/types';\n\n/** Only a message's head is read, so an oversized node text costs a bounded scan. */\nconst MAX_MESSAGE = 1_024;\n\nconst RULES: readonly (readonly [RegExp, BroadcastResult])[] = [\n [/\\bduplicate tx\\b/, { kind: 'already-known' }],\n [\n /\\binsufficient (?:unlocked )?funds\\b/,\n {\n kind: 'refused',\n code: 'FEE_TOO_LOW',\n reason: 'the transaction burns less than the chain charges now',\n },\n ],\n [\n /\\bfailed to (?:get|read consumed) utxo\\b/i,\n {\n kind: 'refused',\n code: 'TX_REFUSED',\n reason: 'an input is already spent, or not known to the node yet',\n },\n ],\n [\n /\\btx conflicts with other tx\\b/,\n {\n kind: 'refused',\n code: 'TX_REFUSED',\n reason: 'it conflicts with a transaction in the mempool',\n },\n ],\n [\n /\\bmempool is full\\b/,\n { kind: 'refused', code: 'TX_REFUSED', reason: 'the node mempool is full' },\n ],\n [\n /\\btx too large\\b/,\n {\n kind: 'refused',\n code: 'TX_REFUSED',\n reason: 'the transaction is larger than the mempool takes',\n },\n ],\n [\n /\\boutput is time locked\\b/,\n { kind: 'refused', code: 'TX_REFUSED', reason: 'an input is still time locked' },\n ],\n];\n\nconst DEFAULT: BroadcastResult = {\n kind: 'refused',\n code: 'TX_REFUSED',\n reason: 'the node refused the transaction',\n};\n\nexport function classifyIssueError(message: string): BroadcastResult {\n const head = message.slice(0, MAX_MESSAGE);\n for (const [pattern, result] of RULES) if (pattern.test(head)) return result;\n return DEFAULT;\n}\n"]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type FeeOverride, type FeeSpeed } from '../../core/model/fee';
|
|
2
|
+
import type { FeeWeights } from './api';
|
|
3
|
+
import { type FeePlan } from './codec';
|
|
4
|
+
import { type AvalancheContext } from './context';
|
|
5
|
+
/** Each speed's margin over the endpoint's gas price, in basis points. */
|
|
6
|
+
export declare const SPEED_MARGIN_BPS: Readonly<Record<FeeSpeed, bigint>>;
|
|
7
|
+
export interface FeeConfigCache {
|
|
8
|
+
value?: {
|
|
9
|
+
readonly weights: FeeWeights;
|
|
10
|
+
readonly minPrice: bigint;
|
|
11
|
+
};
|
|
12
|
+
until?: number;
|
|
13
|
+
}
|
|
14
|
+
/** The fee plan of `fee` on this chain, from the endpoints' current fee data. */
|
|
15
|
+
export declare function feePlanOf(ctx: AvalancheContext, fee: FeeSpeed | FeeOverride, cache: FeeConfigCache, signal?: AbortSignal): Promise<FeePlan>;
|
|
16
|
+
/**
|
|
17
|
+
* The fee plan a stored estimate fixed (`details`), checked: it is our own plain data,
|
|
18
|
+
* read back from the caller's store, which keeps only plain values (`bigint` included).
|
|
19
|
+
*/
|
|
20
|
+
export declare function storedPlan(details: Readonly<Record<string, unknown>>, model: 'static' | 'dynamic'): {
|
|
21
|
+
readonly txFee?: bigint;
|
|
22
|
+
readonly gasPrice?: bigint;
|
|
23
|
+
};
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SPEED_MARGIN_BPS = void 0;
|
|
4
|
+
exports.feePlanOf = feePlanOf;
|
|
5
|
+
exports.storedPlan = storedPlan;
|
|
6
|
+
/**
|
|
7
|
+
* Fee plans. The X-Chain burns a fixed fee per transaction (`txFee`, 0.001 AVAX
|
|
8
|
+
* on mainnet and Fuji), read under the proof quorum so one endpoint cannot raise it, and
|
|
9
|
+
* every speed pays it. Since Etna the P-Chain prices gas: a transaction's fee is its gas
|
|
10
|
+
* (complexity weighed by the network's weights) times the gas price. The price an endpoint
|
|
11
|
+
* reports moves with load (it can double in about 30 s at full load), so a speed pays it
|
|
12
|
+
* times a margin, library policy: slow 1.1×, normal 1.5×, fast 2× (rounded up). Above
|
|
13
|
+
* `options.maxGasPrice` an endpoint's price decides nothing (retryable), and no fee is ever
|
|
14
|
+
* above `options.maxFee`. The weights only change with network upgrades: they are read under
|
|
15
|
+
* the proof quorum and kept for ten minutes.
|
|
16
|
+
*/
|
|
17
|
+
const error_1 = require("../../core/errors/error");
|
|
18
|
+
const fee_1 = require("../../core/model/fee");
|
|
19
|
+
const codec_1 = require("./codec");
|
|
20
|
+
const context_1 = require("./context");
|
|
21
|
+
/** Each speed's margin over the endpoint's gas price, in basis points. */
|
|
22
|
+
exports.SPEED_MARGIN_BPS = Object.freeze({
|
|
23
|
+
slow: 11000n,
|
|
24
|
+
normal: 15000n,
|
|
25
|
+
fast: 20000n,
|
|
26
|
+
});
|
|
27
|
+
const WEIGHTS_TTL_MS = 600_000;
|
|
28
|
+
const override = (message) => new error_1.ValidationError('INVALID_INTENT', message);
|
|
29
|
+
/** A gas price from `{ gasPrice }`: a bigint or a decimal integer string, nAVAX per gas. */
|
|
30
|
+
function gasPriceOf(fee) {
|
|
31
|
+
const keys = Object.keys(fee);
|
|
32
|
+
if (keys.length !== 1 || keys[0] !== 'gasPrice') {
|
|
33
|
+
throw override('a P-Chain fee is a speed or { gasPrice } (nAVAX per unit of gas)');
|
|
34
|
+
}
|
|
35
|
+
const value = fee.gasPrice;
|
|
36
|
+
if (typeof value === 'bigint')
|
|
37
|
+
return value;
|
|
38
|
+
if (typeof value === 'string' && /^[1-9][0-9]{0,18}$/.test(value))
|
|
39
|
+
return BigInt(value);
|
|
40
|
+
throw override('gasPrice must be a positive integer (bigint or decimal string)');
|
|
41
|
+
}
|
|
42
|
+
async function feeConfigOf(ctx, cache, signal) {
|
|
43
|
+
const now = ctx.clock.now();
|
|
44
|
+
if (cache.value && cache.until !== undefined && now < cache.until)
|
|
45
|
+
return cache.value;
|
|
46
|
+
const value = await ctx.node.feeConfig({
|
|
47
|
+
...(0, context_1.withSignal)(context_1.READ, signal),
|
|
48
|
+
quorum: 'proof',
|
|
49
|
+
});
|
|
50
|
+
cache.value = value;
|
|
51
|
+
cache.until = now + WEIGHTS_TTL_MS;
|
|
52
|
+
return value;
|
|
53
|
+
}
|
|
54
|
+
/** The fee plan of `fee` on this chain, from the endpoints' current fee data. */
|
|
55
|
+
async function feePlanOf(ctx, fee, cache, signal) {
|
|
56
|
+
const { config, node } = ctx;
|
|
57
|
+
if (config.vm === 'avm') {
|
|
58
|
+
if (!(0, fee_1.isFeeSpeed)(fee)) {
|
|
59
|
+
throw override("the X-Chain fee is fixed; use 'slow', 'normal' or 'fast'");
|
|
60
|
+
}
|
|
61
|
+
const txFee = await node.txFee({ ...(0, context_1.withSignal)(context_1.READ, signal), quorum: 'proof' });
|
|
62
|
+
(0, codec_1.assertSaneFee)(txFee, config);
|
|
63
|
+
return { model: 'static', txFee };
|
|
64
|
+
}
|
|
65
|
+
if (!(0, fee_1.isFeeSpeed)(fee) && (fee === null || typeof fee !== 'object')) {
|
|
66
|
+
throw override('fee must be a speed or { gasPrice }');
|
|
67
|
+
}
|
|
68
|
+
const [state, { weights, minPrice }] = await Promise.all([
|
|
69
|
+
node.feeState((0, context_1.withSignal)(context_1.READ, signal)),
|
|
70
|
+
feeConfigOf(ctx, cache, signal),
|
|
71
|
+
]);
|
|
72
|
+
if (state.price < 1n || state.price > config.maxGasPrice) {
|
|
73
|
+
throw (0, context_1.undecided)("the endpoint's P-Chain gas price is outside 1..options.maxGasPrice");
|
|
74
|
+
}
|
|
75
|
+
let price;
|
|
76
|
+
if ((0, fee_1.isFeeSpeed)(fee)) {
|
|
77
|
+
const margin = exports.SPEED_MARGIN_BPS[fee];
|
|
78
|
+
price = (state.price * margin + 9999n) / 10000n;
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
price = gasPriceOf(fee);
|
|
82
|
+
if (price < minPrice || price < 1n) {
|
|
83
|
+
throw override("gasPrice is below the P-Chain's minimum gas price");
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (price > config.maxGasPrice) {
|
|
87
|
+
throw override('the gas price exceeds the configured maximum (options.maxGasPrice)');
|
|
88
|
+
}
|
|
89
|
+
return { model: 'dynamic', price, state, weights };
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* The fee plan a stored estimate fixed (`details`), checked: it is our own plain data,
|
|
93
|
+
* read back from the caller's store, which keeps only plain values (`bigint` included).
|
|
94
|
+
*/
|
|
95
|
+
function storedPlan(details, model) {
|
|
96
|
+
if (details.model !== model) {
|
|
97
|
+
throw override('the fee is not an estimate of this chain');
|
|
98
|
+
}
|
|
99
|
+
const value = model === 'static' ? details.txFee : details.gasPrice;
|
|
100
|
+
if (typeof value !== 'bigint' || value < (model === 'static' ? 0n : 1n)) {
|
|
101
|
+
throw override('the fee is not an estimate of this chain');
|
|
102
|
+
}
|
|
103
|
+
return model === 'static' ? { txFee: value } : { gasPrice: value };
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=fees.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fees.js","sourceRoot":"","sources":["../../../src/adapters/avalanche/fees.ts"],"names":[],"mappings":";;;AA+DA,8BAuCC;AAMD,gCAYC;AAxHD;;;;;;;;;;GAUG;AACH,mDAA0D;AAC1D,8CAAmF;AAEnF,mCAAsD;AACtD,uCAA+E;AAE/E,0EAA0E;AAC7D,QAAA,gBAAgB,GAAuC,MAAM,CAAC,MAAM,CAAC;IAChF,IAAI,EAAE,MAAO;IACb,MAAM,EAAE,MAAO;IACf,IAAI,EAAE,MAAO;CACd,CAAC,CAAC;AAEH,MAAM,cAAc,GAAG,OAAO,CAAC;AAO/B,MAAM,QAAQ,GAAG,CAAC,OAAe,EAAmB,EAAE,CACpD,IAAI,uBAAe,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;AAEjD,4FAA4F;AAC5F,SAAS,UAAU,CAAC,GAAgB;IAClC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC9B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,UAAU,EAAE,CAAC;QAChD,MAAM,QAAQ,CAAC,kEAAkE,CAAC,CAAC;IACrF,CAAC;IACD,MAAM,KAAK,GAAG,GAAG,CAAC,QAAQ,CAAC;IAC3B,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,oBAAoB,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACxF,MAAM,QAAQ,CAAC,gEAAgE,CAAC,CAAC;AACnF,CAAC;AAED,KAAK,UAAU,WAAW,CACxB,GAAqB,EACrB,KAAqB,EACrB,MAAoB;IAEpB,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;IAC5B,IAAI,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,IAAI,GAAG,GAAG,KAAK,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC,KAAK,CAAC;IACtF,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC;QACrC,GAAG,IAAA,oBAAU,EAAC,cAAI,EAAE,MAAM,CAAC;QAC3B,MAAM,EAAE,OAAO;KAChB,CAAC,CAAC;IACH,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC;IACpB,KAAK,CAAC,KAAK,GAAG,GAAG,GAAG,cAAc,CAAC;IACnC,OAAO,KAAK,CAAC;AACf,CAAC;AAED,iFAAiF;AAC1E,KAAK,UAAU,SAAS,CAC7B,GAAqB,EACrB,GAA2B,EAC3B,KAAqB,EACrB,MAAoB;IAEpB,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,CAAC;IAC7B,IAAI,MAAM,CAAC,EAAE,KAAK,KAAK,EAAE,CAAC;QACxB,IAAI,CAAC,IAAA,gBAAU,EAAC,GAAG,CAAC,EAAE,CAAC;YACrB,MAAM,QAAQ,CAAC,0DAA0D,CAAC,CAAC;QAC7E,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,IAAA,oBAAU,EAAC,cAAI,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;QACjF,IAAA,qBAAa,EAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAC7B,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IACpC,CAAC;IACD,IAAI,CAAC,IAAA,gBAAU,EAAC,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ,CAAC,EAAE,CAAC;QAClE,MAAM,QAAQ,CAAC,qCAAqC,CAAC,CAAC;IACxD,CAAC;IACD,MAAM,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACvD,IAAI,CAAC,QAAQ,CAAC,IAAA,oBAAU,EAAC,cAAI,EAAE,MAAM,CAAC,CAAC;QACvC,WAAW,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC;KAChC,CAAC,CAAC;IACH,IAAI,KAAK,CAAC,KAAK,GAAG,EAAE,IAAI,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;QACzD,MAAM,IAAA,mBAAS,EAAC,oEAAoE,CAAC,CAAC;IACxF,CAAC;IACD,IAAI,KAAa,CAAC;IAClB,IAAI,IAAA,gBAAU,EAAC,GAAG,CAAC,EAAE,CAAC;QACpB,MAAM,MAAM,GAAG,wBAAgB,CAAC,GAAG,CAAC,CAAC;QACrC,KAAK,GAAG,CAAC,KAAK,CAAC,KAAK,GAAG,MAAM,GAAG,KAAM,CAAC,GAAG,MAAO,CAAC;IACpD,CAAC;SAAM,CAAC;QACN,KAAK,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;QACxB,IAAI,KAAK,GAAG,QAAQ,IAAI,KAAK,GAAG,EAAE,EAAE,CAAC;YACnC,MAAM,QAAQ,CAAC,mDAAmD,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;IACD,IAAI,KAAK,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;QAC/B,MAAM,QAAQ,CAAC,oEAAoE,CAAC,CAAC;IACvF,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AACrD,CAAC;AAED;;;GAGG;AACH,SAAgB,UAAU,CACxB,OAA0C,EAC1C,KAA2B;IAE3B,IAAI,OAAO,CAAC,KAAK,KAAK,KAAK,EAAE,CAAC;QAC5B,MAAM,QAAQ,CAAC,0CAA0C,CAAC,CAAC;IAC7D,CAAC;IACD,MAAM,KAAK,GAAG,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;IACpE,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,GAAG,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;QACxE,MAAM,QAAQ,CAAC,0CAA0C,CAAC,CAAC;IAC7D,CAAC;IACD,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;AACrE,CAAC","sourcesContent":["/**\n * Fee plans. The X-Chain burns a fixed fee per transaction (`txFee`, 0.001 AVAX\n * on mainnet and Fuji), read under the proof quorum so one endpoint cannot raise it, and\n * every speed pays it. Since Etna the P-Chain prices gas: a transaction's fee is its gas\n * (complexity weighed by the network's weights) times the gas price. The price an endpoint\n * reports moves with load (it can double in about 30 s at full load), so a speed pays it\n * times a margin, library policy: slow 1.1×, normal 1.5×, fast 2× (rounded up). Above\n * `options.maxGasPrice` an endpoint's price decides nothing (retryable), and no fee is ever\n * above `options.maxFee`. The weights only change with network upgrades: they are read under\n * the proof quorum and kept for ten minutes.\n */\nimport { ValidationError } from '../../core/errors/error';\nimport { isFeeSpeed, type FeeOverride, type FeeSpeed } from '../../core/model/fee';\nimport type { FeeWeights } from './api';\nimport { assertSaneFee, type FeePlan } from './codec';\nimport { READ, undecided, withSignal, type AvalancheContext } from './context';\n\n/** Each speed's margin over the endpoint's gas price, in basis points. */\nexport const SPEED_MARGIN_BPS: Readonly<Record<FeeSpeed, bigint>> = Object.freeze({\n slow: 11_000n,\n normal: 15_000n,\n fast: 20_000n,\n});\n\nconst WEIGHTS_TTL_MS = 600_000;\n\nexport interface FeeConfigCache {\n value?: { readonly weights: FeeWeights; readonly minPrice: bigint };\n until?: number;\n}\n\nconst override = (message: string): ValidationError =>\n new ValidationError('INVALID_INTENT', message);\n\n/** A gas price from `{ gasPrice }`: a bigint or a decimal integer string, nAVAX per gas. */\nfunction gasPriceOf(fee: FeeOverride): bigint {\n const keys = Object.keys(fee);\n if (keys.length !== 1 || keys[0] !== 'gasPrice') {\n throw override('a P-Chain fee is a speed or { gasPrice } (nAVAX per unit of gas)');\n }\n const value = fee.gasPrice;\n if (typeof value === 'bigint') return value;\n if (typeof value === 'string' && /^[1-9][0-9]{0,18}$/.test(value)) return BigInt(value);\n throw override('gasPrice must be a positive integer (bigint or decimal string)');\n}\n\nasync function feeConfigOf(\n ctx: AvalancheContext,\n cache: FeeConfigCache,\n signal?: AbortSignal,\n): Promise<{ readonly weights: FeeWeights; readonly minPrice: bigint }> {\n const now = ctx.clock.now();\n if (cache.value && cache.until !== undefined && now < cache.until) return cache.value;\n const value = await ctx.node.feeConfig({\n ...withSignal(READ, signal),\n quorum: 'proof',\n });\n cache.value = value;\n cache.until = now + WEIGHTS_TTL_MS;\n return value;\n}\n\n/** The fee plan of `fee` on this chain, from the endpoints' current fee data. */\nexport async function feePlanOf(\n ctx: AvalancheContext,\n fee: FeeSpeed | FeeOverride,\n cache: FeeConfigCache,\n signal?: AbortSignal,\n): Promise<FeePlan> {\n const { config, node } = ctx;\n if (config.vm === 'avm') {\n if (!isFeeSpeed(fee)) {\n throw override(\"the X-Chain fee is fixed; use 'slow', 'normal' or 'fast'\");\n }\n const txFee = await node.txFee({ ...withSignal(READ, signal), quorum: 'proof' });\n assertSaneFee(txFee, config);\n return { model: 'static', txFee };\n }\n if (!isFeeSpeed(fee) && (fee === null || typeof fee !== 'object')) {\n throw override('fee must be a speed or { gasPrice }');\n }\n const [state, { weights, minPrice }] = await Promise.all([\n node.feeState(withSignal(READ, signal)),\n feeConfigOf(ctx, cache, signal),\n ]);\n if (state.price < 1n || state.price > config.maxGasPrice) {\n throw undecided(\"the endpoint's P-Chain gas price is outside 1..options.maxGasPrice\");\n }\n let price: bigint;\n if (isFeeSpeed(fee)) {\n const margin = SPEED_MARGIN_BPS[fee];\n price = (state.price * margin + 9_999n) / 10_000n;\n } else {\n price = gasPriceOf(fee);\n if (price < minPrice || price < 1n) {\n throw override(\"gasPrice is below the P-Chain's minimum gas price\");\n }\n }\n if (price > config.maxGasPrice) {\n throw override('the gas price exceeds the configured maximum (options.maxGasPrice)');\n }\n return { model: 'dynamic', price, state, weights };\n}\n\n/**\n * The fee plan a stored estimate fixed (`details`), checked: it is our own plain data,\n * read back from the caller's store, which keeps only plain values (`bigint` included).\n */\nexport function storedPlan(\n details: Readonly<Record<string, unknown>>,\n model: 'static' | 'dynamic',\n): { readonly txFee?: bigint; readonly gasPrice?: bigint } {\n if (details.model !== model) {\n throw override('the fee is not an estimate of this chain');\n }\n const value = model === 'static' ? details.txFee : details.gasPrice;\n if (typeof value !== 'bigint' || value < (model === 'static' ? 0n : 1n)) {\n throw override('the fee is not an estimate of this chain');\n }\n return model === 'static' ? { txFee: value } : { gasPrice: value };\n}\n"]}
|