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 @@
|
|
|
1
|
+
{"version":3,"file":"proofs.js","sourceRoot":"","sources":["../../../src/adapters/solana/proofs.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Proofs and block scanning. Each fact is attested at its own height with a monotone\n * predicate, never at a height one endpoint proposes. \"My finalized height is past H\" is\n * a quorum read of `getBlockHeight({ commitment: 'finalized' })` keyed on `height > H`;\n * the block at a height is a quorum read of `getBlock(slot, { commitment: 'finalized' })`\n * keyed on its consensus fields, so an endpoint that has not finalized it answers nothing\n * and decides nothing.\n *\n * The expiry height itself is never taken on trust: the build read it from one endpoint,\n * and a height reported too low would prove an Attempt expired while it can still land,\n * so `rebuild` would pay twice. A verdict rests on the height the quorum attests for the\n * transaction's blockhash: when the finalized block at the slot the build recorded\n * carries it, that block's height plus `BLOCKHASH_VALIDITY` is the last valid height,\n * whatever was recorded; otherwise the finalized block at the recorded height minus\n * `BLOCKHASH_VALIDITY` must carry it, which confirms the recorded height without the\n * slot. Neither decides nothing.\n *\n * A transaction is proven absent only by reading every block of its window\n * under finality: each block certifies its own height and its parent's hash, from the\n * blockhash's own block to the window's last, so a lagging, pruned, snapshot-jumped or\n * long-term-storage-gapped backend behind a load-balanced URL can only answer \"not\n * available\" (decides nothing), never a short window.\n *\n * Only a definitive negative proof answers \"no\". Every other RPC error\n * on these paths decides nothing (`undecided`: a retryable `PROVIDER_UNAVAILABLE`).\n *\n * Tags: every read a verdict rests on carries the contract table's proof tags (`ChainDriver`\n * in the core's `driver/types.ts`: purpose `proof`, quorum `'proof'`), with two deliberate\n * exceptions, both single-endpoint `monitor` reads of hints the quorum then re-attests: the\n * finalized height behind `finalizedHead` (the one unanchored head), and the\n * height-to-slot lookups of `HeightIndex` (`attestedBlock`). A wrong hint names a block the\n * quorum does not attest at that height, so it only ever decides nothing.\n */\nimport type { BlockSource, DriverBlock, ProofSource } from '../../core/driver/types';\nimport { ProviderError } from '../../core/errors/error';\nimport type { OrderingData } from '../../core/model/ordering';\nimport {\n decodeTransaction,\n isVote,\n parseTransaction,\n tokenTransfersLanded,\n touches,\n} from './decode';\nimport { decodeBase58, isSignature } from './keys';\nimport { blockAtHeight, type SolanaContext } from './reader';\nimport {\n BLOCK_FIELDS,\n MONITOR,\n PROOF,\n blockHeader,\n call,\n headerOptions,\n gone,\n inconsistent,\n isGone,\n isNotAvailable,\n isSkipped,\n malformed,\n notYet,\n parsedOptions,\n pick,\n u64,\n undecided,\n type BlockHeader,\n} from './rpc';\nimport type { Commitment, SolanaExpiryOrdering } from './types';\n\n/**\n * A blockhash is valid for this many blocks after its own: agave's `MAX_PROCESSING_AGE`\n * (v4.3.0: `runtime/src/bank.rs` sets every bank's `max_processing_age` to it, and\n * `get_blockhash_last_valid_block_height` answers `block_height + max_processing_age −\n * age`, so the newest blockhash's last valid height is its block's height plus 150).\n */\nexport const BLOCKHASH_VALIDITY = 150n;\n\n/**\n * The heights that can hold a transaction whose blockhash gives `lastValidBlockHeight`:\n * from the block after the blockhash's own, through `lastValidBlockHeight + 1`. agave checks\n * a blockhash's age against the including block's PARENT, so the block after\n * `lastValidBlockHeight` still accepts it.\n */\nexport function windowOf(lastValidHeight: bigint): {\n readonly first: bigint;\n readonly end: bigint;\n} {\n const first =\n lastValidHeight >= BLOCKHASH_VALIDITY - 1n\n ? lastValidHeight - BLOCKHASH_VALIDITY + 1n\n : 0n;\n return { first, end: lastValidHeight + 1n };\n}\n\n/** Signatures proven absent from their finalized windows, kept per driver. */\nconst ABSENT_MEMO = 1_024;\n/**\n * Window proofs in progress, kept per driver with the same bound: each window's\n * attested frame, and how far each signature's read of it got.\n */\nconst WINDOW_MEMO = 1_024;\n/** Attested last valid heights by blockhash (immutable chain data), kept per driver. */\nconst ANCHOR_MEMO = 1_024;\n\n/** Library policy: an unanchored head trails one endpoint's view by this peer skew. */\nexport const PEER_SKEW = 2n;\n\n/** Drops a bounded memo's oldest entry once it holds more than `size`. */\nfunction trim(memo: Set<string> | Map<string, unknown>, size: number): void {\n if (memo.size > size) memo.delete(memo.keys().next().value as string);\n}\n\nasync function finalizedHeight(ctx: SolanaContext): Promise<bigint> {\n return u64(\n await call(ctx.transport, 'getBlockHeight', [{ commitment: 'finalized' }], MONITOR),\n 'getBlockHeight',\n );\n}\n\n/**\n * Whether every quorum endpoint has finalized a block above `height`: the monotone\n * predicate \"my finalized height > height\". Endpoints that disagree throw a\n * retryable `PROVIDER_INCONSISTENT` (decides nothing); all saying no is `false`.\n */\nasync function finalizedPast(ctx: SolanaContext, height: bigint): Promise<boolean> {\n const past = (result: unknown): boolean => {\n if (typeof result === 'bigint') return result > height;\n if (typeof result === 'number' && Number.isSafeInteger(result))\n return BigInt(result) > height;\n throw malformed('getBlockHeight');\n };\n const result = await call(\n ctx.transport,\n 'getBlockHeight',\n [{ commitment: 'finalized' }],\n { ...PROOF, quorumKey: past },\n );\n return past(result);\n}\n\n/** What a build recorded with the height: one endpoint's word until attested. */\ninterface Recorded {\n readonly lastValidHeight: bigint;\n readonly blockhash: string;\n /** Absent when not recorded, or not a slot a request can name exactly. */\n readonly slot?: bigint;\n}\n\n/** Our own expiry ordering's recorded height, or `undefined` for any other ordering. */\nconst lastValidOf = (ordering: OrderingData): bigint | undefined =>\n ordering.kind === 'expiry' ? ordering.lastValidHeight : undefined;\n\n/** The blockhash an expiry ordering names, if any (the key of the attested heights). */\nconst blockhashOf = (ordering: OrderingData): string | undefined => {\n const { blockhash } = ordering as Partial<SolanaExpiryOrdering>;\n return typeof blockhash === 'string' ? blockhash : undefined;\n};\n\n/**\n * The blockhash and slot a build recorded with the height (`SolanaExpiryOrdering`). An\n * ordering without a blockhash can never be attested: it decides nothing. A missing or\n * ill-typed slot only leaves the slot-free check.\n */\nfunction recordedOf(ordering: OrderingData, lastValidHeight: bigint): Recorded {\n const { blockhash, blockhashSlot: slot } = ordering as Partial<SolanaExpiryOrdering>;\n if (decodeBase58(blockhash, 32) === null) {\n throw new ProviderError(\n 'PROVIDER_UNAVAILABLE',\n 'the expiry ordering does not name the blockhash its height belongs to',\n );\n }\n const exact =\n typeof slot === 'bigint' && slot >= 0n && slot <= BigInt(Number.MAX_SAFE_INTEGER);\n return { lastValidHeight, blockhash: blockhash as string, ...(exact ? { slot } : {}) };\n}\n\nconst BLOCKHASH_BLOCK = \"the block of the transaction's blockhash\";\nconst LIE =\n 'the recorded expiry height disagrees with its blockhash; using the attested one';\n\n/**\n * The height of the finalized block at `slot` when it carries `blockhash`, or\n * `null` when the slot does not anchor it (another block there, a skipped or pruned slot,\n * no finalized block yet). The quorum key is the block's height and whether its hash\n * matches, so the height adopted is every endpoint's, never the first answer's. Only a\n * hash match yields a height; a disagreement or any other error decides nothing.\n */\nasync function heightAtSlot(\n ctx: SolanaContext,\n blockhash: string,\n slot: bigint,\n): Promise<bigint | null> {\n const key = (result: unknown) => {\n if (result === null) return null;\n const header = blockHeader(result);\n return {\n height: header.blockHeight.toString(),\n matches: header.blockhash === blockhash,\n };\n };\n let result: unknown;\n try {\n result = await call(\n ctx.transport,\n 'getBlock',\n [Number(slot), headerOptions('finalized')],\n { ...PROOF, quorumKey: key },\n );\n } catch (error) {\n if (isNotAvailable(error)) return null;\n throw undecided(error, BLOCKHASH_BLOCK);\n }\n if (result === null) return null;\n const header = blockHeader(result);\n return header.blockhash === blockhash ? header.blockHeight : null;\n}\n\n/**\n * The last valid height the quorum attests for a recorded expiry. agave answers\n * `getLatestBlockhash` from one bank (its slot, its last blockhash, and that blockhash's\n * last valid height: `block_height + MAX_PROCESSING_AGE`), so an honest record anchors at\n * its slot. When it does, the attested block's height plus `BLOCKHASH_VALIDITY` is the\n * answer, and a recorded height that disagrees is a build-time lie: logged (fixed text) and\n * ignored. When the slot does not anchor the blockhash, the block at the recorded height\n * minus `BLOCKHASH_VALIDITY` must carry it, which confirms the recorded height. Only a\n * lie in both the slot and the height is never attested: it decides nothing, for good, so\n * such an Operation stays unresolved but is never paid twice.\n */\nasync function attestLastValid(ctx: SolanaContext, recorded: Recorded): Promise<bigint> {\n const at =\n recorded.slot === undefined\n ? null\n : await heightAtSlot(ctx, recorded.blockhash, recorded.slot);\n if (at !== null) {\n const last = at + BLOCKHASH_VALIDITY;\n if (last !== recorded.lastValidHeight) ctx.log.warn(LIE);\n return last;\n }\n const height = recorded.lastValidHeight - BLOCKHASH_VALIDITY;\n const block = height < 0n ? null : await attestedBlock(ctx, height, 'finalized');\n if (!block) throw notYet(BLOCKHASH_BLOCK);\n if (block.header.blockhash !== recorded.blockhash) {\n throw inconsistent(\n 'neither the recorded slot nor the recorded height holds the blockhash',\n );\n }\n return recorded.lastValidHeight;\n}\n\n/**\n * The block at `height` as the quorum serves it at `commitment`, or `null` when an endpoint\n * cannot show it there yet. The slot of a height comes from one endpoint's block list; the\n * quorum then attests the block itself and its height, so a wrong slot only ever decides\n * nothing. Callers use it only for heights the quorum already holds as final (deep window\n * starts, heights at or below an attested finalized height) or for `'latest'` checks where\n * `null` decides nothing.\n */\nasync function attestedBlock(\n ctx: SolanaContext,\n height: bigint,\n commitment: Commitment,\n): Promise<{ readonly slot: bigint; readonly header: BlockHeader } | null> {\n const slot = await ctx.heights.slotAt(height, commitment, MONITOR);\n if (slot === null) return null;\n let result: unknown;\n try {\n result = await call(\n ctx.transport,\n 'getBlock',\n [Number(slot), headerOptions(commitment)],\n PROOF,\n );\n } catch (error) {\n if (isSkipped(error)) {\n // The slot came from a list that named a slot with no block.\n ctx.heights.forget();\n throw inconsistent(`slot ${slot} holds no block`);\n }\n if (isNotAvailable(error)) return null;\n throw undecided(error, `the block at height ${height}`);\n }\n if (result === null) return null;\n const header = blockHeader(result);\n if (header.blockHeight !== height) {\n ctx.heights.forget();\n throw inconsistent(`the block at slot ${slot} is not at height ${height}`);\n }\n return { slot, header };\n}\n\n/** The window a verdict reads: an attested last valid height, and its blockhash. */\ninterface Anchor {\n readonly lastValidHeight: bigint;\n readonly blockhash: string;\n}\n\n/**\n * A window's frame, attested under the proof quorum: the finalized slot of each of its\n * heights, and the hash of its last block. Finalized blocks never change, so it is kept.\n */\ninterface WindowFrame {\n readonly slots: readonly bigint[];\n readonly lastHash: string;\n}\n\n/**\n * How far one signature's read of a window got: the blocks before `next` are finalized,\n * attested, chained from the blockhash's own block to `parent`, and without the signature.\n * Immutable chain facts too; the signature lists themselves are never kept (a mainnet block\n * holds thousands).\n */\ninterface WindowCursor {\n readonly next: number;\n readonly parent: string;\n}\n\n/**\n * What a window proof keeps between passes, so a pass that fails part way (a\n * rate limit, an endpoint that is behind) resumes where it stopped instead of starting over.\n * Over the `public` preset a pass gets only a few `getBlock` reads, so without this the\n * proof never completed. Keyed by window (`<last valid height>:<blockhash>`) and by\n * `<signature>:<window>`, each bounded like the absence memo.\n */\ninterface WindowMemo {\n readonly frames: Map<string, WindowFrame>;\n readonly cursors: Map<string, WindowCursor>;\n}\n\n/** The frame of `anchor`'s window, attested once and then kept. */\nasync function windowFrame(\n ctx: SolanaContext,\n anchor: Anchor,\n memo: WindowMemo,\n key: string,\n): Promise<WindowFrame> {\n const kept = memo.frames.get(key);\n if (kept) return kept;\n const { first, end } = windowOf(anchor.lastValidHeight);\n const top = await attestedBlock(ctx, end, 'finalized');\n const bottom = await attestedBlock(ctx, first, 'finalized');\n if (!top || !bottom) throw notYet('the transaction window');\n const listKey = (result: unknown): unknown => {\n if (!Array.isArray(result)) throw malformed('getBlocks');\n return result.map(String);\n };\n let listed: unknown;\n try {\n listed = await call(\n ctx.transport,\n 'getBlocks',\n [\n Number(bottom.slot),\n Number(top.slot),\n { commitment: 'finalized', minContextSlot: Number(top.slot) },\n ],\n { ...PROOF, quorumKey: listKey },\n );\n } catch (error) {\n if (isNotAvailable(error)) throw notYet('every block of the window');\n throw undecided(error, 'every block of the window');\n }\n if (!Array.isArray(listed) || BigInt(listed.length) !== end - first + 1n) {\n throw notYet('every block of the window');\n }\n const frame: WindowFrame = {\n slots: listed.map((value) => u64(value, 'getBlocks slot')),\n lastHash: top.header.blockhash,\n };\n memo.frames.set(key, frame);\n trim(memo.frames, WINDOW_MEMO);\n return frame;\n}\n\n/**\n * Whether `signature` is in none of the finalized blocks of its window.\n * The window's first and last blocks are attested by height; `getBlocks` must list exactly\n * one slot per height between them; every block is read whole (its signatures) under the\n * proof quorum and must sit at the next height with the previous block as its parent, the\n * first one on the attested blockhash's own block. A gap, a pruned block or a lagging\n * backend answers \"not available\" and decides nothing. `false` means a block holds the\n * transaction. Progress is kept between passes (`WindowMemo`): a resumed pass reads on from\n * the last verified block, chained to its hash; a chain that does not hold drops what was\n * kept for the window, so the next pass starts over.\n */\nasync function absentFromWindow(\n ctx: SolanaContext,\n signature: string,\n anchor: Anchor,\n memo: WindowMemo,\n): Promise<boolean> {\n const { first } = windowOf(anchor.lastValidHeight);\n const window = `${anchor.lastValidHeight}:${anchor.blockhash}`;\n const frame = await windowFrame(ctx, anchor, memo, window);\n const key = `${signature}:${window}`;\n const holds = (result: unknown): boolean | null => {\n const list = (result as { signatures?: unknown } | null)?.signatures;\n return Array.isArray(list) ? list.includes(signature) : null;\n };\n const blockKey = (result: unknown): unknown => ({\n ...(pick(result, BLOCK_FIELDS) as object),\n holds: holds(result),\n });\n const brokenChain = (reason: string) => {\n memo.frames.delete(window);\n memo.cursors.delete(key);\n return inconsistent(reason);\n };\n // The window hangs off the blockhash's own block, which the anchor attested.\n let { next, parent } = memo.cursors.get(key) ?? { next: 0, parent: anchor.blockhash };\n for (; next < frame.slots.length; next++) {\n let block: unknown;\n try {\n block = await call(\n ctx.transport,\n 'getBlock',\n [\n Number(frame.slots[next]),\n { ...headerOptions('finalized'), transactionDetails: 'signatures' },\n ],\n { ...PROOF, quorumKey: blockKey },\n );\n } catch (error) {\n if (isNotAvailable(error)) throw notYet('a block of the window');\n throw undecided(error, 'a block of the window');\n }\n const found = holds(block);\n if (found === null) throw notYet('a block of the window');\n const header = blockHeader(block);\n if (\n header.blockHeight !== first + BigInt(next) ||\n header.previousBlockhash !== parent\n ) {\n throw brokenChain('the window is not one chain of blocks');\n }\n if (found) {\n memo.cursors.delete(key);\n return false;\n }\n parent = header.blockhash;\n memo.cursors.set(key, { next: next + 1, parent });\n trim(memo.cursors, WINDOW_MEMO);\n }\n if (parent !== frame.lastHash) {\n throw brokenChain('the window does not end at its attested block');\n }\n memo.cursors.delete(key);\n return true;\n}\n\n/** The quorum's finalized transaction (`null`: every endpoint agrees it has none). */\nasync function finalTransaction(ctx: SolanaContext, signature: string): Promise<unknown> {\n try {\n return await call(\n ctx.transport,\n 'getTransaction',\n [signature, parsedOptions('finalized')],\n PROOF,\n );\n } catch (error) {\n if (isNotAvailable(error)) throw notYet('the transaction history');\n throw undecided(error, 'the transaction history');\n }\n}\n\n/** Whatever a proof method meets, no RPC error is ever a verdict. */\nfunction guarded<A extends unknown[], R>(\n method: (...args: A) => Promise<R>,\n): (...args: A) => Promise<R> {\n return async (...args) => {\n try {\n return await method(...args);\n } catch (error) {\n throw undecided(error, 'the proof');\n }\n };\n}\n\nexport function createSolanaProofs(ctx: SolanaContext): ProofSource {\n const absent = new Set<string>();\n const windows: WindowMemo = { frames: new Map(), cursors: new Map() };\n /** Attested last valid heights by blockhash: a blockhash names one block, for good. */\n const anchors = new Map<string, bigint>();\n const known = (ordering: OrderingData): bigint | undefined => {\n const blockhash = blockhashOf(ordering);\n return blockhash === undefined ? undefined : anchors.get(blockhash);\n };\n /** The attested last valid height of `ordering`, remembered once attested. */\n const attested = async (ordering: OrderingData, recorded: bigint): Promise<Anchor> => {\n const record = recordedOf(ordering, recorded);\n let last = anchors.get(record.blockhash);\n if (last === undefined) {\n last = await attestLastValid(ctx, record);\n anchors.set(record.blockhash, last);\n trim(anchors, ANCHOR_MEMO);\n }\n return { lastValidHeight: last, blockhash: record.blockhash };\n };\n /**\n * While the recorded height has not passed, the last valid height the recorded\n * slot alone attests (no height fallback), remembered as `attested` remembers it. A build\n * that raised the recorded height would otherwise wait for that height, possibly for\n * ever, although the real window has passed. `undefined` (not yet) when no slot was\n * recorded, the slot does not hold the blockhash, or it cannot be read.\n */\n const attestedAtSlot = async (\n ordering: OrderingData,\n recorded: bigint,\n ): Promise<bigint | undefined> => {\n let record: Recorded;\n let at: bigint | null;\n try {\n record = recordedOf(ordering, recorded);\n if (record.slot === undefined) return undefined;\n at = await heightAtSlot(ctx, record.blockhash, record.slot);\n } catch {\n return undefined;\n }\n if (at === null) return undefined;\n const last = at + BLOCKHASH_VALIDITY;\n if (last !== recorded) ctx.log.warn(LIE);\n anchors.set(record.blockhash, last);\n trim(anchors, ANCHOR_MEMO);\n return last;\n };\n /**\n * A finalized `getTransaction` answer, read under that method's quorum key, is the only\n * verdict input (never a block's entry): the transaction asked for, in the finalized\n * block at its slot, with the landing guard applied.\n */\n const included = async (result: unknown, signature: string, from: string) => {\n const parsed = parseTransaction(result, signature);\n if (parsed.slot === undefined) throw malformed('getTransaction');\n let header: BlockHeader | null;\n try {\n const block = await call(\n ctx.transport,\n 'getBlock',\n [Number(parsed.slot), headerOptions('finalized')],\n PROOF,\n );\n header = block === null ? null : blockHeader(block);\n } catch (error) {\n if (!isNotAvailable(error)) throw undecided(error, 'the block of the transaction');\n header = null;\n }\n if (!header) throw notYet('the block of the transaction');\n // Our own token transfers count only when the balances show them. The reasons are\n // `observe`'s fixed texts, so the proven failure keeps the observed one.\n const reason =\n parsed.err !== null\n ? 'transaction failed'\n : tokenTransfersLanded(parsed, from)\n ? undefined\n : 'token transfer failed';\n return {\n included: true as const,\n success: reason === undefined,\n blockHeight: header.blockHeight,\n blockHash: header.blockhash,\n txHash: signature,\n ...(reason !== undefined ? { reason } : {}),\n };\n };\n\n const proofs: ProofSource = {\n async finalizedHead() {\n // The one unanchored head: one endpoint's view, trailed by a peer skew.\n const seen = await finalizedHeight(ctx);\n const height = seen > PEER_SKEW ? seen - PEER_SKEW : 0n;\n const block = await attestedBlock(ctx, height, 'finalized');\n if (!block) throw notYet('the finalized head');\n return {\n height,\n hash: block.header.blockhash,\n ...(block.header.blockTime !== undefined\n ? { timestamp: block.header.blockTime }\n : {}),\n };\n },\n\n async includedFinal(ref, ordering, from) {\n // A malformed signature can never be on chain.\n if (!isSignature(ref.id)) return { included: false };\n const found = await finalTransaction(ctx, ref.id);\n if (found !== null) return included(found, ref.id, from);\n // An index that shows nothing proves nothing; only the window can. Behind one URL,\n // `getTransaction` may reach a backend that lags, was pruned or jumped to a\n // snapshot, and agave ignores its `minContextSlot`.\n const recorded = lastValidOf(ordering);\n if (recorded === undefined) throw notYet('proof that the transaction is absent');\n const remembered = known(ordering);\n if (remembered !== undefined && absent.has(`${ref.id}:${remembered}`)) {\n return { included: false };\n }\n // The window's last block (lastValidBlockHeight + 1) is final everywhere, at the\n // attested height. An early \"no\" at the recorded one only delays, unless the\n // recorded slot attests another height: its predicate is asked below.\n const pastWindow = () => notYet('finality past the transaction window');\n if (remembered === undefined && !(await finalizedPast(ctx, recorded))) {\n const bySlot = await attestedAtSlot(ordering, recorded);\n if (bySlot === undefined || bySlot === recorded) throw pastWindow();\n }\n const anchor = await attested(ordering, recorded);\n const last = anchor.lastValidHeight;\n if (last !== recorded || remembered !== undefined) {\n if (!(await finalizedPast(ctx, last))) throw pastWindow();\n }\n const key = `${ref.id}:${last}`;\n if (!absent.has(key)) {\n if (!(await absentFromWindow(ctx, ref.id, anchor, windows))) {\n throw inconsistent(\n 'a block of the window holds a transaction its index does not show',\n );\n }\n absent.add(key);\n trim(absent, ABSENT_MEMO);\n }\n return { included: false };\n },\n\n // Expiry ordering has no slot that another transaction could consume.\n slotConsumed: async () => false,\n\n async expired(ordering) {\n const recorded = lastValidOf(ordering);\n // \"Not expired\" is the safe answer: it never declares a transaction dead.\n if (recorded === undefined) return false;\n const remembered = known(ordering);\n if (remembered !== undefined) return finalizedPast(ctx, remembered);\n // An early \"no\" at the recorded height only delays, unless the recorded slot attests\n // another height: then that height's own predicate answers.\n if (!(await finalizedPast(ctx, recorded))) {\n const bySlot = await attestedAtSlot(ordering, recorded);\n return bySlot !== undefined && bySlot !== recorded && finalizedPast(ctx, bySlot);\n }\n // \"Expired\" rests on the attested height, and its own predicate read.\n const { lastValidHeight } = await attested(ordering, recorded);\n return lastValidHeight === recorded || finalizedPast(ctx, lastValidHeight);\n },\n\n async blockHash(height, level) {\n // Null above the finalized height decides nothing; so does any endpoint that has\n // not finalized `height` yet (the attested read answers nothing there).\n if (level === 'finalized' && !(await finalizedPast(ctx, height - 1n))) return null;\n const block = await attestedBlock(\n ctx,\n height,\n level === 'finalized' ? 'finalized' : 'confirmed',\n );\n return block?.header.blockhash ?? null;\n },\n };\n return {\n finalizedHead: guarded(proofs.finalizedHead),\n includedFinal: guarded(proofs.includedFinal),\n slotConsumed: guarded(proofs.slotConsumed),\n expired: guarded(proofs.expired),\n blockHash: guarded(proofs.blockHash),\n };\n}\n\nconst changed = (height: bigint) =>\n inconsistent(`block ${height} changed while scanning`);\n\nexport function createSolanaBlocks(ctx: SolanaContext): BlockSource {\n return {\n header: async (height) => (await blockAtHeight(ctx, height, MONITOR))?.block ?? null,\n\n async transactions(block: DriverBlock, filter) {\n const slot = await ctx.heights.slotAt(block.height, 'confirmed', MONITOR);\n if (slot === null) throw changed(block.height);\n let result: unknown;\n try {\n result = await call(\n ctx.transport,\n 'getBlock',\n [\n Number(slot),\n { ...parsedOptions('confirmed'), transactionDetails: 'full', rewards: false },\n ],\n MONITOR,\n );\n } catch (error) {\n if (isGone(error)) throw gone(`the block at height ${block.height}`);\n // A slot the index named holds no block: drop the cache it came from.\n if (isSkipped(error)) ctx.heights.forget();\n if (isNotAvailable(error)) throw changed(block.height);\n // Any other node error decides nothing; the scan retries.\n throw undecided(error, `the block at height ${block.height}`);\n }\n const full = result as { blockhash?: unknown; transactions?: unknown } | null;\n if (!full || full.blockhash !== block.hash) throw changed(block.height);\n if (!Array.isArray(full.transactions)) throw malformed('getBlock');\n const wanted = filter?.addresses?.length ? new Set(filter.addresses) : undefined;\n const place = {\n height: block.height,\n hash: block.hash,\n ...(block.timestamp !== undefined ? { blockTime: block.timestamp } : {}),\n };\n // All or nothing: a transaction that does not parse makes the whole block retry\n // (retryable), never a block read short.\n return full.transactions.flatMap((entry) => {\n const parsed = parseTransaction(entry);\n if (isVote(parsed)) return [];\n const decoded = decodeTransaction(parsed, place);\n return !wanted || touches(decoded, parsed, wanted) ? [decoded] : [];\n });\n },\n };\n}\n"]}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Solana addresses, reads and the `ext.solana` API. Every call carries the tags of the
|
|
3
|
+
* `ChainDriver` contract table: `read` for point queries, `monitor` for heights and
|
|
4
|
+
* observations. Heads are read at `confirmed`, finality at `finalized`.
|
|
5
|
+
*/
|
|
6
|
+
import type { AddressCodec, ChainReader, DriverBlock } from '../../core/driver/types';
|
|
7
|
+
import type { Logger } from '../../core/events/logger';
|
|
8
|
+
import type { AssetRef } from '../../core/model/asset';
|
|
9
|
+
import type { ChainInfo, NetworkInfo } from '../../core/model/chain';
|
|
10
|
+
import type { Transport } from '../../core/transport/types';
|
|
11
|
+
import { type ParsedTransaction } from './decode';
|
|
12
|
+
import type { HeightIndex } from './heights';
|
|
13
|
+
import type { SolanaNetworkConfig } from './network';
|
|
14
|
+
import { type BlockHeader } from './rpc';
|
|
15
|
+
import type { SolanaCallTags, SolanaCodec, SolanaExt, SolanaTokenAccount } from './types';
|
|
16
|
+
/** What every Solana port is built from. */
|
|
17
|
+
export interface SolanaContext {
|
|
18
|
+
readonly transport: Transport;
|
|
19
|
+
readonly codec: SolanaCodec;
|
|
20
|
+
readonly chain: ChainInfo;
|
|
21
|
+
readonly network: NetworkInfo;
|
|
22
|
+
readonly config: SolanaNetworkConfig;
|
|
23
|
+
readonly heights: HeightIndex;
|
|
24
|
+
readonly log: Logger;
|
|
25
|
+
/** The next build variant (`fees.ts`, `variantCounter`). */
|
|
26
|
+
readonly nextVariant: () => number;
|
|
27
|
+
}
|
|
28
|
+
export interface AccountInfo {
|
|
29
|
+
readonly owner: string;
|
|
30
|
+
readonly executable: boolean;
|
|
31
|
+
readonly data: Uint8Array;
|
|
32
|
+
}
|
|
33
|
+
/** `getAccountInfo` (base64) at `confirmed`; `null` when the account does not exist. */
|
|
34
|
+
export declare function accountInfo(ctx: SolanaContext, address: string, tags: SolanaCallTags): Promise<AccountInfo | null>;
|
|
35
|
+
/** The mint of an `spl` asset ref; any other standard is not a Solana token. */
|
|
36
|
+
export declare function mintOf(asset: AssetRef): string;
|
|
37
|
+
/**
|
|
38
|
+
* A classic Token mint's decimals: a missing mint, an account of another
|
|
39
|
+
* program or data that does not parse is the token's own `ASSET_RESOLUTION`; a Token-2022
|
|
40
|
+
* mint is `UNSUPPORTED_CAPABILITY`. A definitive node error is made retryable;
|
|
41
|
+
* `PROVIDER_MISCONFIGURED` and retryable errors propagate unchanged. Under a quorum (the
|
|
42
|
+
* token metadata the core caches), endpoints must agree on the verdict: a lagging one that
|
|
43
|
+
* has no mint yet, or one with other decimals, decides nothing (`PROVIDER_INCONSISTENT`).
|
|
44
|
+
*/
|
|
45
|
+
export declare function mintDecimals(ctx: SolanaContext, mint: string, tags: SolanaCallTags): Promise<number>;
|
|
46
|
+
export declare function createSolanaAddressCodec(): AddressCodec;
|
|
47
|
+
/**
|
|
48
|
+
* The block at dense `height` (`confirmed`), checked against the height it claims; `null`
|
|
49
|
+
* while the endpoint has no block there. A contradicting answer is a retryable
|
|
50
|
+
* `PROVIDER_INCONSISTENT`, and the cached slot it came from is dropped.
|
|
51
|
+
*/
|
|
52
|
+
export declare function blockAtHeight(ctx: SolanaContext, height: bigint, tags: SolanaCallTags): Promise<{
|
|
53
|
+
readonly slot: bigint;
|
|
54
|
+
readonly block: DriverBlock;
|
|
55
|
+
} | null>;
|
|
56
|
+
/**
|
|
57
|
+
* Reads a transaction at `confirmed`, with its block's height and hash. The answer must be
|
|
58
|
+
* the transaction asked for: another one decides nothing (a retryable "not yet"), never
|
|
59
|
+
* reads as ours.
|
|
60
|
+
*/
|
|
61
|
+
export declare function readTransaction(ctx: SolanaContext, signature: string, tags: SolanaCallTags): Promise<{
|
|
62
|
+
readonly parsed: ParsedTransaction;
|
|
63
|
+
readonly header: BlockHeader;
|
|
64
|
+
} | null>;
|
|
65
|
+
/**
|
|
66
|
+
* Token metadata is read under the proof quorum, stricter than
|
|
67
|
+
* the contract table's minimum: the core caches a token's decimals and "no such token" for
|
|
68
|
+
* the container's life, so one lagging or wrong endpoint must not mis-scale every amount
|
|
69
|
+
* until a restart. `mintDecimals` compares the mint's verdict only. The builder reads the
|
|
70
|
+
* decimals it signs into `transferChecked` the same way, so a lagging
|
|
71
|
+
* endpoint without the mint decides nothing instead of refusing the transfer.
|
|
72
|
+
*/
|
|
73
|
+
export declare const METADATA: SolanaCallTags;
|
|
74
|
+
export declare function createSolanaReader(ctx: SolanaContext): ChainReader;
|
|
75
|
+
/**
|
|
76
|
+
* The classic token accounts of `owner`, optionally for one mint. The answer is filtered to
|
|
77
|
+
* what was asked (lookups by id): an account of another owner or mint, as a node that
|
|
78
|
+
* drops a filter would list it, is none of the owner's. Token-2022 accounts are skipped
|
|
79
|
+
* (unsupported). An account listed twice is malformed, never a doubled balance.
|
|
80
|
+
*/
|
|
81
|
+
export declare function tokenAccountsOf(ctx: SolanaContext, owner: string, mint: string | undefined, tags: SolanaCallTags): Promise<SolanaTokenAccount[]>;
|
|
82
|
+
export declare function createSolanaExt(ctx: SolanaContext): SolanaExt;
|
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.METADATA = void 0;
|
|
4
|
+
exports.accountInfo = accountInfo;
|
|
5
|
+
exports.mintOf = mintOf;
|
|
6
|
+
exports.mintDecimals = mintDecimals;
|
|
7
|
+
exports.createSolanaAddressCodec = createSolanaAddressCodec;
|
|
8
|
+
exports.blockAtHeight = blockAtHeight;
|
|
9
|
+
exports.readTransaction = readTransaction;
|
|
10
|
+
exports.createSolanaReader = createSolanaReader;
|
|
11
|
+
exports.tokenAccountsOf = tokenAccountsOf;
|
|
12
|
+
exports.createSolanaExt = createSolanaExt;
|
|
13
|
+
const error_1 = require("../../core/errors/error");
|
|
14
|
+
const decode_1 = require("./decode");
|
|
15
|
+
const keys_1 = require("./keys");
|
|
16
|
+
const programs_1 = require("./programs");
|
|
17
|
+
const rpc_1 = require("./rpc");
|
|
18
|
+
/**
|
|
19
|
+
* Account data in agave's `base64` encoding, refused unless it is canonical: Node decodes
|
|
20
|
+
* leniently (a stray character is skipped, `AB==` reads as `AA==`), so the bytes must
|
|
21
|
+
* encode back to the same text. The check is linear, which matters: accounts hold up to
|
|
22
|
+
* 10 MiB, and a repeated-group regex overflows the stack on a few MiB.
|
|
23
|
+
*/
|
|
24
|
+
function base64Data(value, what) {
|
|
25
|
+
if (!Array.isArray(value) ||
|
|
26
|
+
value.length !== 2 ||
|
|
27
|
+
value[1] !== 'base64' ||
|
|
28
|
+
typeof value[0] !== 'string' ||
|
|
29
|
+
value[0].length % 4 !== 0) {
|
|
30
|
+
throw (0, rpc_1.malformed)(what);
|
|
31
|
+
}
|
|
32
|
+
const bytes = Buffer.from(value[0], 'base64');
|
|
33
|
+
if (bytes.toString('base64') !== value[0])
|
|
34
|
+
throw (0, rpc_1.malformed)(what);
|
|
35
|
+
return new Uint8Array(bytes);
|
|
36
|
+
}
|
|
37
|
+
/** A `getAccountInfo` answer (base64): the account, or `null` when it does not exist. */
|
|
38
|
+
function parseAccount(result) {
|
|
39
|
+
const value = (0, rpc_1.contextValue)(result, 'getAccountInfo');
|
|
40
|
+
if (value === null)
|
|
41
|
+
return null;
|
|
42
|
+
const account = (0, rpc_1.record)(value);
|
|
43
|
+
if (!account || !(0, keys_1.isAddress)(account.owner) || typeof account.executable !== 'boolean') {
|
|
44
|
+
throw (0, rpc_1.malformed)('getAccountInfo');
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
owner: account.owner,
|
|
48
|
+
executable: account.executable,
|
|
49
|
+
data: base64Data(account.data, 'getAccountInfo'),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/** `getAccountInfo` (base64) at `confirmed`; `null` when the account does not exist. */
|
|
53
|
+
async function accountInfo(ctx, address, tags) {
|
|
54
|
+
return parseAccount(await (0, rpc_1.call)(ctx.transport, 'getAccountInfo', [address, { encoding: 'base64', commitment: 'confirmed' }], tags));
|
|
55
|
+
}
|
|
56
|
+
const assetError = (reason) => new error_1.ValidationError('ASSET_RESOLUTION', reason);
|
|
57
|
+
/** The mint of an `spl` asset ref; any other standard is not a Solana token. */
|
|
58
|
+
function mintOf(asset) {
|
|
59
|
+
if (asset === 'native' || asset.standard !== 'spl') {
|
|
60
|
+
throw assetError(`Solana tokens use the 'spl' standard`);
|
|
61
|
+
}
|
|
62
|
+
if (!(0, keys_1.isAddress)(asset.contract))
|
|
63
|
+
throw assetError('not a Solana mint address');
|
|
64
|
+
return asset.contract;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* The verdict of a mint account, by its owning program first: a classic mint and a
|
|
68
|
+
* Token-2022 one cannot be told apart by their size.
|
|
69
|
+
*/
|
|
70
|
+
function mintVerdict(info) {
|
|
71
|
+
if (!info)
|
|
72
|
+
return { refused: 'missing' };
|
|
73
|
+
if (info.owner === programs_1.TOKEN_2022_PROGRAM)
|
|
74
|
+
return { refused: 'token-2022' };
|
|
75
|
+
if (info.owner !== programs_1.TOKEN_PROGRAM)
|
|
76
|
+
return { refused: 'other-program' };
|
|
77
|
+
const decoded = (0, programs_1.decodeMint)(info.data);
|
|
78
|
+
return decoded ? { decimals: decoded.decimals } : { refused: 'unparsable' };
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* A mint read's quorum key, verdict fields only: the verdict itself, never the
|
|
82
|
+
* context slot, the lamports or the supply, on which honest endpoints differ. A malformed
|
|
83
|
+
* answer keys as such, so it never agrees with a verdict.
|
|
84
|
+
*/
|
|
85
|
+
function mintKey(result) {
|
|
86
|
+
try {
|
|
87
|
+
return mintVerdict(parseAccount(result));
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
return 'malformed';
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* A classic Token mint's decimals: a missing mint, an account of another
|
|
95
|
+
* program or data that does not parse is the token's own `ASSET_RESOLUTION`; a Token-2022
|
|
96
|
+
* mint is `UNSUPPORTED_CAPABILITY`. A definitive node error is made retryable;
|
|
97
|
+
* `PROVIDER_MISCONFIGURED` and retryable errors propagate unchanged. Under a quorum (the
|
|
98
|
+
* token metadata the core caches), endpoints must agree on the verdict: a lagging one that
|
|
99
|
+
* has no mint yet, or one with other decimals, decides nothing (`PROVIDER_INCONSISTENT`).
|
|
100
|
+
*/
|
|
101
|
+
async function mintDecimals(ctx, mint, tags) {
|
|
102
|
+
let info;
|
|
103
|
+
try {
|
|
104
|
+
info = await accountInfo(ctx, mint, { ...tags, quorumKey: mintKey });
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
if ((0, error_1.isCryptoAioError)(error, 'RPC_ERROR') && !error.retryable) {
|
|
108
|
+
throw (0, error_1.withContext)(error, {}, { retryable: true });
|
|
109
|
+
}
|
|
110
|
+
throw error;
|
|
111
|
+
}
|
|
112
|
+
const verdict = mintVerdict(info);
|
|
113
|
+
if ('decimals' in verdict)
|
|
114
|
+
return verdict.decimals;
|
|
115
|
+
switch (verdict.refused) {
|
|
116
|
+
case 'missing':
|
|
117
|
+
throw assetError('no mint at this address');
|
|
118
|
+
case 'token-2022':
|
|
119
|
+
throw new error_1.UnsupportedCapabilityError('UNSUPPORTED_CAPABILITY', 'Token-2022 mints are not supported');
|
|
120
|
+
case 'other-program':
|
|
121
|
+
throw assetError('not an SPL token mint');
|
|
122
|
+
case 'unparsable':
|
|
123
|
+
throw assetError('the mint does not parse');
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
function createSolanaAddressCodec() {
|
|
127
|
+
return {
|
|
128
|
+
validate: (value) => (0, keys_1.isAddress)(value),
|
|
129
|
+
normalize: (value) => {
|
|
130
|
+
if (!(0, keys_1.isAddress)(value)) {
|
|
131
|
+
throw new error_1.ValidationError('INVALID_ADDRESS', 'not a Solana address');
|
|
132
|
+
}
|
|
133
|
+
return { canonical: value, display: value };
|
|
134
|
+
},
|
|
135
|
+
fromPublicKey: (publicKey) => {
|
|
136
|
+
const canonical = (0, keys_1.addressFromPublicKey)(publicKey);
|
|
137
|
+
return { canonical, display: canonical };
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
function driverBlock(height, header) {
|
|
142
|
+
return {
|
|
143
|
+
height,
|
|
144
|
+
hash: header.blockhash,
|
|
145
|
+
parentHash: header.previousBlockhash,
|
|
146
|
+
...(header.blockTime !== undefined ? { timestamp: header.blockTime } : {}),
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* The block at dense `height` (`confirmed`), checked against the height it claims; `null`
|
|
151
|
+
* while the endpoint has no block there. A contradicting answer is a retryable
|
|
152
|
+
* `PROVIDER_INCONSISTENT`, and the cached slot it came from is dropped.
|
|
153
|
+
*/
|
|
154
|
+
async function blockAtHeight(ctx, height, tags) {
|
|
155
|
+
const slot = await ctx.heights.slotAt(height, 'confirmed', tags);
|
|
156
|
+
if (slot === null)
|
|
157
|
+
return null;
|
|
158
|
+
const header = await ctx.heights.header(slot, 'confirmed', tags);
|
|
159
|
+
if (!header)
|
|
160
|
+
return null;
|
|
161
|
+
if (header.blockHeight !== height) {
|
|
162
|
+
ctx.heights.forget();
|
|
163
|
+
throw (0, rpc_1.inconsistent)(`the block at slot ${slot} is not at height ${height}`);
|
|
164
|
+
}
|
|
165
|
+
return { slot, block: driverBlock(height, header) };
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Reads a transaction at `confirmed`, with its block's height and hash. The answer must be
|
|
169
|
+
* the transaction asked for: another one decides nothing (a retryable "not yet"), never
|
|
170
|
+
* reads as ours.
|
|
171
|
+
*/
|
|
172
|
+
async function readTransaction(ctx, signature, tags) {
|
|
173
|
+
const result = await (0, rpc_1.call)(ctx.transport, 'getTransaction', [signature, (0, rpc_1.parsedOptions)('confirmed')], tags);
|
|
174
|
+
if (result === null)
|
|
175
|
+
return null;
|
|
176
|
+
const parsed = (0, decode_1.parseTransaction)(result, signature);
|
|
177
|
+
if (parsed.slot === undefined)
|
|
178
|
+
throw (0, rpc_1.malformed)('getTransaction');
|
|
179
|
+
const header = await ctx.heights.header(parsed.slot, 'confirmed', tags);
|
|
180
|
+
if (!header)
|
|
181
|
+
throw (0, rpc_1.notYet)('the block of the transaction');
|
|
182
|
+
return { parsed, header };
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Token metadata is read under the proof quorum, stricter than
|
|
186
|
+
* the contract table's minimum: the core caches a token's decimals and "no such token" for
|
|
187
|
+
* the container's life, so one lagging or wrong endpoint must not mis-scale every amount
|
|
188
|
+
* until a restart. `mintDecimals` compares the mint's verdict only. The builder reads the
|
|
189
|
+
* decimals it signs into `transferChecked` the same way, so a lagging
|
|
190
|
+
* endpoint without the mint decides nothing instead of refusing the transfer.
|
|
191
|
+
*/
|
|
192
|
+
exports.METADATA = Object.freeze({ ...rpc_1.READ, quorum: 'proof' });
|
|
193
|
+
function createSolanaReader(ctx) {
|
|
194
|
+
const height = async (commitment) => (0, rpc_1.u64)(await (0, rpc_1.call)(ctx.transport, 'getBlockHeight', [{ commitment }], rpc_1.MONITOR), 'getBlockHeight');
|
|
195
|
+
return {
|
|
196
|
+
getBalance: async (address, asset) => {
|
|
197
|
+
if (asset === 'native') {
|
|
198
|
+
return (0, rpc_1.u64)((0, rpc_1.contextValue)(await (0, rpc_1.call)(ctx.transport, 'getBalance', [address, { commitment: 'confirmed' }], rpc_1.READ), 'getBalance'), 'balance');
|
|
199
|
+
}
|
|
200
|
+
const mint = mintOf(asset);
|
|
201
|
+
const accounts = await tokenAccountsOf(ctx, address, mint, rpc_1.READ);
|
|
202
|
+
return accounts.reduce((sum, account) => sum + account.amount, 0n);
|
|
203
|
+
},
|
|
204
|
+
getBlockHeight: () => height('confirmed'),
|
|
205
|
+
getFinalizedHeight: () => height('finalized'),
|
|
206
|
+
getBlock: async (ref) => {
|
|
207
|
+
if (typeof ref !== 'bigint') {
|
|
208
|
+
throw new error_1.UnsupportedCapabilityError('UNSUPPORTED_CAPABILITY', 'Solana has no block lookup by hash; pass a block height');
|
|
209
|
+
}
|
|
210
|
+
return (await blockAtHeight(ctx, ref, rpc_1.READ))?.block ?? null;
|
|
211
|
+
},
|
|
212
|
+
getTransaction: async (id) => {
|
|
213
|
+
if (!(0, keys_1.isSignature)(id))
|
|
214
|
+
return null;
|
|
215
|
+
const found = await readTransaction(ctx, id, rpc_1.READ);
|
|
216
|
+
if (!found)
|
|
217
|
+
return null;
|
|
218
|
+
return (0, decode_1.decodeTransaction)(found.parsed, {
|
|
219
|
+
height: found.header.blockHeight,
|
|
220
|
+
hash: found.header.blockhash,
|
|
221
|
+
...(found.parsed.blockTime !== undefined
|
|
222
|
+
? { blockTime: found.parsed.blockTime }
|
|
223
|
+
: {}),
|
|
224
|
+
});
|
|
225
|
+
},
|
|
226
|
+
observe: async (ref, ordering, from) => {
|
|
227
|
+
if (!(0, keys_1.isSignature)(ref.id))
|
|
228
|
+
return { seen: 'none' };
|
|
229
|
+
const found = await readTransaction(ctx, ref.id, rpc_1.MONITOR);
|
|
230
|
+
if (!found)
|
|
231
|
+
return { seen: 'none' };
|
|
232
|
+
const { parsed, header } = found;
|
|
233
|
+
let success = parsed.err === null;
|
|
234
|
+
let reason = success ? undefined : 'transaction failed';
|
|
235
|
+
// The phantom-success guard applies to our own Attempts only. This is
|
|
236
|
+
// one endpoint's `confirmed` view, so the core records it as observed evidence,
|
|
237
|
+
// never terminal: a verdict reads the finalized transaction under the proof quorum's
|
|
238
|
+
// key (`proofs.ts`). A node that drops the token instruction makes the transfer look
|
|
239
|
+
// native here, which that verdict catches.
|
|
240
|
+
if (success && ordering !== undefined && from !== undefined) {
|
|
241
|
+
if (!(0, decode_1.tokenTransfersLanded)(parsed, from)) {
|
|
242
|
+
success = false;
|
|
243
|
+
reason = 'token transfer failed';
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
return {
|
|
247
|
+
seen: 'block',
|
|
248
|
+
txHash: parsed.signature,
|
|
249
|
+
blockHeight: header.blockHeight,
|
|
250
|
+
blockHash: header.blockhash,
|
|
251
|
+
success,
|
|
252
|
+
...(reason !== undefined ? { reason } : {}),
|
|
253
|
+
};
|
|
254
|
+
},
|
|
255
|
+
getTokenMetadata: async (ref) => {
|
|
256
|
+
const mint = mintOf(ref);
|
|
257
|
+
const decimals = await mintDecimals(ctx, mint, exports.METADATA);
|
|
258
|
+
// SPL mints carry no symbol on chain: a registered token has its own; any other
|
|
259
|
+
// shows the first characters of its mint (display only).
|
|
260
|
+
return { symbol: mint.slice(0, 8), decimals };
|
|
261
|
+
},
|
|
262
|
+
normalizeTokenRef: (ref) => ({ standard: 'spl', contract: mintOf(ref) }),
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* The classic token accounts of `owner`, optionally for one mint. The answer is filtered to
|
|
267
|
+
* what was asked (lookups by id): an account of another owner or mint, as a node that
|
|
268
|
+
* drops a filter would list it, is none of the owner's. Token-2022 accounts are skipped
|
|
269
|
+
* (unsupported). An account listed twice is malformed, never a doubled balance.
|
|
270
|
+
*/
|
|
271
|
+
async function tokenAccountsOf(ctx, owner, mint, tags) {
|
|
272
|
+
const value = (0, rpc_1.contextValue)(await (0, rpc_1.call)(ctx.transport, 'getTokenAccountsByOwner', [
|
|
273
|
+
owner,
|
|
274
|
+
mint !== undefined ? { mint } : { programId: programs_1.TOKEN_PROGRAM },
|
|
275
|
+
{ encoding: 'base64', commitment: 'confirmed' },
|
|
276
|
+
], tags), 'getTokenAccountsByOwner');
|
|
277
|
+
if (!Array.isArray(value))
|
|
278
|
+
throw (0, rpc_1.malformed)('getTokenAccountsByOwner');
|
|
279
|
+
const accounts = [];
|
|
280
|
+
const listed = new Set();
|
|
281
|
+
for (const entry of value) {
|
|
282
|
+
const item = (0, rpc_1.record)(entry);
|
|
283
|
+
const account = (0, rpc_1.record)(item?.account);
|
|
284
|
+
if (!item ||
|
|
285
|
+
!account ||
|
|
286
|
+
!(0, keys_1.isAddress)(item.pubkey) ||
|
|
287
|
+
listed.has(item.pubkey) ||
|
|
288
|
+
!(0, keys_1.isAddress)(account.owner)) {
|
|
289
|
+
throw (0, rpc_1.malformed)('getTokenAccountsByOwner');
|
|
290
|
+
}
|
|
291
|
+
listed.add(item.pubkey);
|
|
292
|
+
if (account.owner !== programs_1.TOKEN_PROGRAM)
|
|
293
|
+
continue; // Token-2022 is unsupported.
|
|
294
|
+
const decoded = (0, programs_1.decodeTokenAccount)(base64Data(account.data, 'getTokenAccountsByOwner'));
|
|
295
|
+
if (!decoded)
|
|
296
|
+
throw (0, rpc_1.malformed)('getTokenAccountsByOwner');
|
|
297
|
+
const accountMint = (0, keys_1.encodeBase58)(decoded.mint);
|
|
298
|
+
if ((0, keys_1.encodeBase58)(decoded.owner) !== owner)
|
|
299
|
+
continue;
|
|
300
|
+
if (mint !== undefined && accountMint !== mint)
|
|
301
|
+
continue;
|
|
302
|
+
accounts.push({
|
|
303
|
+
address: item.pubkey,
|
|
304
|
+
mint: accountMint,
|
|
305
|
+
amount: decoded.amount,
|
|
306
|
+
frozen: decoded.frozen,
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
return accounts;
|
|
310
|
+
}
|
|
311
|
+
function createSolanaExt(ctx) {
|
|
312
|
+
return {
|
|
313
|
+
solana: {
|
|
314
|
+
getTokenAccounts: async (owner, mint) => {
|
|
315
|
+
if (!(0, keys_1.isAddress)(owner)) {
|
|
316
|
+
throw new error_1.ValidationError('INVALID_ADDRESS', 'not a Solana address');
|
|
317
|
+
}
|
|
318
|
+
if (mint !== undefined && (0, keys_1.decodeBase58)(mint, 32) === null) {
|
|
319
|
+
throw new error_1.ValidationError('INVALID_ADDRESS', 'not a Solana mint address');
|
|
320
|
+
}
|
|
321
|
+
return tokenAccountsOf(ctx, owner, mint, rpc_1.READ);
|
|
322
|
+
},
|
|
323
|
+
},
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
//# sourceMappingURL=reader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reader.js","sourceRoot":"","sources":["../../../src/adapters/solana/reader.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Solana addresses, reads and the `ext.solana` API. Every call carries the tags of the\n * `ChainDriver` contract table: `read` for point queries, `monitor` for heights and\n * observations. Heads are read at `confirmed`, finality at `finalized`.\n */\nimport type {\n AddressCodec,\n ChainReader,\n DriverBlock,\n DriverTxObservation,\n} from '../../core/driver/types';\nimport {\n UnsupportedCapabilityError,\n ValidationError,\n isCryptoAioError,\n withContext,\n} from '../../core/errors/error';\nimport type { Logger } from '../../core/events/logger';\nimport type { AssetMetadata, AssetRef, TokenRef } from '../../core/model/asset';\nimport type { ChainInfo, NetworkInfo } from '../../core/model/chain';\nimport type { Transport } from '../../core/transport/types';\nimport {\n decodeTransaction,\n parseTransaction,\n tokenTransfersLanded,\n type ParsedTransaction,\n} from './decode';\nimport type { HeightIndex } from './heights';\nimport {\n addressFromPublicKey,\n decodeBase58,\n encodeBase58,\n isAddress,\n isSignature,\n} from './keys';\nimport type { SolanaNetworkConfig } from './network';\nimport {\n TOKEN_2022_PROGRAM,\n TOKEN_PROGRAM,\n decodeMint,\n decodeTokenAccount,\n} from './programs';\nimport {\n MONITOR,\n READ,\n call,\n contextValue,\n inconsistent,\n malformed,\n notYet,\n parsedOptions,\n record,\n u64,\n type BlockHeader,\n} from './rpc';\nimport type { SolanaCallTags, SolanaCodec, SolanaExt, SolanaTokenAccount } from './types';\n\n/** What every Solana port is built from. */\nexport interface SolanaContext {\n readonly transport: Transport;\n readonly codec: SolanaCodec;\n readonly chain: ChainInfo;\n readonly network: NetworkInfo;\n readonly config: SolanaNetworkConfig;\n readonly heights: HeightIndex;\n readonly log: Logger;\n /** The next build variant (`fees.ts`, `variantCounter`). */\n readonly nextVariant: () => number;\n}\n\nexport interface AccountInfo {\n readonly owner: string;\n readonly executable: boolean;\n readonly data: Uint8Array;\n}\n\n/**\n * Account data in agave's `base64` encoding, refused unless it is canonical: Node decodes\n * leniently (a stray character is skipped, `AB==` reads as `AA==`), so the bytes must\n * encode back to the same text. The check is linear, which matters: accounts hold up to\n * 10 MiB, and a repeated-group regex overflows the stack on a few MiB.\n */\nfunction base64Data(value: unknown, what: string): Uint8Array {\n if (\n !Array.isArray(value) ||\n value.length !== 2 ||\n value[1] !== 'base64' ||\n typeof value[0] !== 'string' ||\n value[0].length % 4 !== 0\n ) {\n throw malformed(what);\n }\n const bytes = Buffer.from(value[0], 'base64');\n if (bytes.toString('base64') !== value[0]) throw malformed(what);\n return new Uint8Array(bytes);\n}\n\n/** A `getAccountInfo` answer (base64): the account, or `null` when it does not exist. */\nfunction parseAccount(result: unknown): AccountInfo | null {\n const value = contextValue(result, 'getAccountInfo');\n if (value === null) return null;\n const account = record(value);\n if (!account || !isAddress(account.owner) || typeof account.executable !== 'boolean') {\n throw malformed('getAccountInfo');\n }\n return {\n owner: account.owner,\n executable: account.executable,\n data: base64Data(account.data, 'getAccountInfo'),\n };\n}\n\n/** `getAccountInfo` (base64) at `confirmed`; `null` when the account does not exist. */\nexport async function accountInfo(\n ctx: SolanaContext,\n address: string,\n tags: SolanaCallTags,\n): Promise<AccountInfo | null> {\n return parseAccount(\n await call(\n ctx.transport,\n 'getAccountInfo',\n [address, { encoding: 'base64', commitment: 'confirmed' }],\n tags,\n ),\n );\n}\n\nconst assetError = (reason: string) => new ValidationError('ASSET_RESOLUTION', reason);\n\n/** The mint of an `spl` asset ref; any other standard is not a Solana token. */\nexport function mintOf(asset: AssetRef): string {\n if (asset === 'native' || asset.standard !== 'spl') {\n throw assetError(`Solana tokens use the 'spl' standard`);\n }\n if (!isAddress(asset.contract)) throw assetError('not a Solana mint address');\n return asset.contract;\n}\n\n/** What a mint account says about its token: the only fields a mint read decides on. */\ntype MintVerdict =\n | { readonly decimals: number }\n | { readonly refused: 'missing' | 'token-2022' | 'other-program' | 'unparsable' };\n\n/**\n * The verdict of a mint account, by its owning program first: a classic mint and a\n * Token-2022 one cannot be told apart by their size.\n */\nfunction mintVerdict(info: AccountInfo | null): MintVerdict {\n if (!info) return { refused: 'missing' };\n if (info.owner === TOKEN_2022_PROGRAM) return { refused: 'token-2022' };\n if (info.owner !== TOKEN_PROGRAM) return { refused: 'other-program' };\n const decoded = decodeMint(info.data);\n return decoded ? { decimals: decoded.decimals } : { refused: 'unparsable' };\n}\n\n/**\n * A mint read's quorum key, verdict fields only: the verdict itself, never the\n * context slot, the lamports or the supply, on which honest endpoints differ. A malformed\n * answer keys as such, so it never agrees with a verdict.\n */\nfunction mintKey(result: unknown): unknown {\n try {\n return mintVerdict(parseAccount(result));\n } catch {\n return 'malformed';\n }\n}\n\n/**\n * A classic Token mint's decimals: a missing mint, an account of another\n * program or data that does not parse is the token's own `ASSET_RESOLUTION`; a Token-2022\n * mint is `UNSUPPORTED_CAPABILITY`. A definitive node error is made retryable;\n * `PROVIDER_MISCONFIGURED` and retryable errors propagate unchanged. Under a quorum (the\n * token metadata the core caches), endpoints must agree on the verdict: a lagging one that\n * has no mint yet, or one with other decimals, decides nothing (`PROVIDER_INCONSISTENT`).\n */\nexport async function mintDecimals(\n ctx: SolanaContext,\n mint: string,\n tags: SolanaCallTags,\n): Promise<number> {\n let info: AccountInfo | null;\n try {\n info = await accountInfo(ctx, mint, { ...tags, quorumKey: mintKey });\n } catch (error) {\n if (isCryptoAioError(error, 'RPC_ERROR') && !error.retryable) {\n throw withContext(error, {}, { retryable: true });\n }\n throw error;\n }\n const verdict = mintVerdict(info);\n if ('decimals' in verdict) return verdict.decimals;\n switch (verdict.refused) {\n case 'missing':\n throw assetError('no mint at this address');\n case 'token-2022':\n throw new UnsupportedCapabilityError(\n 'UNSUPPORTED_CAPABILITY',\n 'Token-2022 mints are not supported',\n );\n case 'other-program':\n throw assetError('not an SPL token mint');\n case 'unparsable':\n throw assetError('the mint does not parse');\n }\n}\n\nexport function createSolanaAddressCodec(): AddressCodec {\n return {\n validate: (value) => isAddress(value),\n normalize: (value) => {\n if (!isAddress(value)) {\n throw new ValidationError('INVALID_ADDRESS', 'not a Solana address');\n }\n return { canonical: value, display: value };\n },\n fromPublicKey: (publicKey) => {\n const canonical = addressFromPublicKey(publicKey);\n return { canonical, display: canonical };\n },\n };\n}\n\nfunction driverBlock(height: bigint, header: BlockHeader): DriverBlock {\n return {\n height,\n hash: header.blockhash,\n parentHash: header.previousBlockhash,\n ...(header.blockTime !== undefined ? { timestamp: header.blockTime } : {}),\n };\n}\n\n/**\n * The block at dense `height` (`confirmed`), checked against the height it claims; `null`\n * while the endpoint has no block there. A contradicting answer is a retryable\n * `PROVIDER_INCONSISTENT`, and the cached slot it came from is dropped.\n */\nexport async function blockAtHeight(\n ctx: SolanaContext,\n height: bigint,\n tags: SolanaCallTags,\n): Promise<{ readonly slot: bigint; readonly block: DriverBlock } | null> {\n const slot = await ctx.heights.slotAt(height, 'confirmed', tags);\n if (slot === null) return null;\n const header = await ctx.heights.header(slot, 'confirmed', tags);\n if (!header) return null;\n if (header.blockHeight !== height) {\n ctx.heights.forget();\n throw inconsistent(`the block at slot ${slot} is not at height ${height}`);\n }\n return { slot, block: driverBlock(height, header) };\n}\n\n/**\n * Reads a transaction at `confirmed`, with its block's height and hash. The answer must be\n * the transaction asked for: another one decides nothing (a retryable \"not yet\"), never\n * reads as ours.\n */\nexport async function readTransaction(\n ctx: SolanaContext,\n signature: string,\n tags: SolanaCallTags,\n): Promise<{ readonly parsed: ParsedTransaction; readonly header: BlockHeader } | null> {\n const result = await call(\n ctx.transport,\n 'getTransaction',\n [signature, parsedOptions('confirmed')],\n tags,\n );\n if (result === null) return null;\n const parsed = parseTransaction(result, signature);\n if (parsed.slot === undefined) throw malformed('getTransaction');\n const header = await ctx.heights.header(parsed.slot, 'confirmed', tags);\n if (!header) throw notYet('the block of the transaction');\n return { parsed, header };\n}\n\n/**\n * Token metadata is read under the proof quorum, stricter than\n * the contract table's minimum: the core caches a token's decimals and \"no such token\" for\n * the container's life, so one lagging or wrong endpoint must not mis-scale every amount\n * until a restart. `mintDecimals` compares the mint's verdict only. The builder reads the\n * decimals it signs into `transferChecked` the same way, so a lagging\n * endpoint without the mint decides nothing instead of refusing the transfer.\n */\nexport const METADATA: SolanaCallTags = Object.freeze({ ...READ, quorum: 'proof' });\n\nexport function createSolanaReader(ctx: SolanaContext): ChainReader {\n const height = async (commitment: 'confirmed' | 'finalized') =>\n u64(\n await call(ctx.transport, 'getBlockHeight', [{ commitment }], MONITOR),\n 'getBlockHeight',\n );\n return {\n getBalance: async (address, asset) => {\n if (asset === 'native') {\n return u64(\n contextValue(\n await call(\n ctx.transport,\n 'getBalance',\n [address, { commitment: 'confirmed' }],\n READ,\n ),\n 'getBalance',\n ),\n 'balance',\n );\n }\n const mint = mintOf(asset);\n const accounts = await tokenAccountsOf(ctx, address, mint, READ);\n return accounts.reduce((sum, account) => sum + account.amount, 0n);\n },\n getBlockHeight: () => height('confirmed'),\n getFinalizedHeight: () => height('finalized'),\n getBlock: async (ref) => {\n if (typeof ref !== 'bigint') {\n throw new UnsupportedCapabilityError(\n 'UNSUPPORTED_CAPABILITY',\n 'Solana has no block lookup by hash; pass a block height',\n );\n }\n return (await blockAtHeight(ctx, ref, READ))?.block ?? null;\n },\n getTransaction: async (id) => {\n if (!isSignature(id)) return null;\n const found = await readTransaction(ctx, id, READ);\n if (!found) return null;\n return decodeTransaction(found.parsed, {\n height: found.header.blockHeight,\n hash: found.header.blockhash,\n ...(found.parsed.blockTime !== undefined\n ? { blockTime: found.parsed.blockTime }\n : {}),\n });\n },\n observe: async (ref, ordering, from): Promise<DriverTxObservation> => {\n if (!isSignature(ref.id)) return { seen: 'none' };\n const found = await readTransaction(ctx, ref.id, MONITOR);\n if (!found) return { seen: 'none' };\n const { parsed, header } = found;\n let success = parsed.err === null;\n let reason = success ? undefined : 'transaction failed';\n // The phantom-success guard applies to our own Attempts only. This is\n // one endpoint's `confirmed` view, so the core records it as observed evidence,\n // never terminal: a verdict reads the finalized transaction under the proof quorum's\n // key (`proofs.ts`). A node that drops the token instruction makes the transfer look\n // native here, which that verdict catches.\n if (success && ordering !== undefined && from !== undefined) {\n if (!tokenTransfersLanded(parsed, from)) {\n success = false;\n reason = 'token transfer failed';\n }\n }\n return {\n seen: 'block',\n txHash: parsed.signature,\n blockHeight: header.blockHeight,\n blockHash: header.blockhash,\n success,\n ...(reason !== undefined ? { reason } : {}),\n };\n },\n getTokenMetadata: async (ref: TokenRef): Promise<AssetMetadata> => {\n const mint = mintOf(ref);\n const decimals = await mintDecimals(ctx, mint, METADATA);\n // SPL mints carry no symbol on chain: a registered token has its own; any other\n // shows the first characters of its mint (display only).\n return { symbol: mint.slice(0, 8), decimals };\n },\n normalizeTokenRef: (ref) => ({ standard: 'spl', contract: mintOf(ref) }),\n };\n}\n\n/**\n * The classic token accounts of `owner`, optionally for one mint. The answer is filtered to\n * what was asked (lookups by id): an account of another owner or mint, as a node that\n * drops a filter would list it, is none of the owner's. Token-2022 accounts are skipped\n * (unsupported). An account listed twice is malformed, never a doubled balance.\n */\nexport async function tokenAccountsOf(\n ctx: SolanaContext,\n owner: string,\n mint: string | undefined,\n tags: SolanaCallTags,\n): Promise<SolanaTokenAccount[]> {\n const value = contextValue(\n await call(\n ctx.transport,\n 'getTokenAccountsByOwner',\n [\n owner,\n mint !== undefined ? { mint } : { programId: TOKEN_PROGRAM },\n { encoding: 'base64', commitment: 'confirmed' },\n ],\n tags,\n ),\n 'getTokenAccountsByOwner',\n );\n if (!Array.isArray(value)) throw malformed('getTokenAccountsByOwner');\n const accounts: SolanaTokenAccount[] = [];\n const listed = new Set<string>();\n for (const entry of value) {\n const item = record(entry);\n const account = record(item?.account);\n if (\n !item ||\n !account ||\n !isAddress(item.pubkey) ||\n listed.has(item.pubkey) ||\n !isAddress(account.owner)\n ) {\n throw malformed('getTokenAccountsByOwner');\n }\n listed.add(item.pubkey);\n if (account.owner !== TOKEN_PROGRAM) continue; // Token-2022 is unsupported.\n const decoded = decodeTokenAccount(\n base64Data(account.data, 'getTokenAccountsByOwner'),\n );\n if (!decoded) throw malformed('getTokenAccountsByOwner');\n const accountMint = encodeBase58(decoded.mint);\n if (encodeBase58(decoded.owner) !== owner) continue;\n if (mint !== undefined && accountMint !== mint) continue;\n accounts.push({\n address: item.pubkey,\n mint: accountMint,\n amount: decoded.amount,\n frozen: decoded.frozen,\n });\n }\n return accounts;\n}\n\nexport function createSolanaExt(ctx: SolanaContext): SolanaExt {\n return {\n solana: {\n getTokenAccounts: async (owner, mint) => {\n if (!isAddress(owner)) {\n throw new ValidationError('INVALID_ADDRESS', 'not a Solana address');\n }\n if (mint !== undefined && decodeBase58(mint, 32) === null) {\n throw new ValidationError('INVALID_ADDRESS', 'not a Solana mint address');\n }\n return tokenAccountsOf(ctx, owner, mint, READ);\n },\n },\n };\n}\n"]}
|