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,131 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.vsizeOf = exports.MAX_STANDARD_WEIGHT = void 0;
|
|
4
|
+
exports.txWeight = txWeight;
|
|
5
|
+
exports.selectCoins = selectCoins;
|
|
6
|
+
/**
|
|
7
|
+
* Transaction size and coin selection (pure; `accumulative`, the default, and
|
|
8
|
+
* `all`). Sizes are exact weight units with worst-case signatures (a low-s DER ECDSA
|
|
9
|
+
* signature is at most 71 bytes plus the sighash byte; BIP340 is 64 bytes), so the signed
|
|
10
|
+
* transaction is never larger than estimated and its fee rate never lower. Change below the
|
|
11
|
+
* dust threshold is not created; its value goes to the fee (bounded by the absurd-fee guard).
|
|
12
|
+
*/
|
|
13
|
+
const error_1 = require("../../core/errors/error");
|
|
14
|
+
const address_1 = require("./address");
|
|
15
|
+
const fees_1 = require("./fees");
|
|
16
|
+
/** Bitcoin Core's `MAX_STANDARD_TX_WEIGHT` (policy.h). */
|
|
17
|
+
exports.MAX_STANDARD_WEIGHT = 400_000;
|
|
18
|
+
/** Per input: non-witness bytes (outpoint, script, sequence) and witness bytes. */
|
|
19
|
+
const INPUT_SIZE = {
|
|
20
|
+
// 32 + 4 + 1 (empty script) + 4; witness: count, 72-byte signature push, 33-byte key push.
|
|
21
|
+
p2wpkh: { base: 41, witness: 1 + 1 + 72 + 1 + 33 },
|
|
22
|
+
// scriptSig: 1 (length) + 1 (push) + 22-byte redeem script.
|
|
23
|
+
'p2sh-p2wpkh': { base: 32 + 4 + 1 + 23 + 4, witness: 1 + 1 + 72 + 1 + 33 },
|
|
24
|
+
// scriptSig: 1 (length) + 1 + 72 + 1 + 33.
|
|
25
|
+
p2pkh: { base: 32 + 4 + 1 + 107 + 4, witness: 0 },
|
|
26
|
+
// witness: count, 64-byte signature push (SIGHASH_DEFAULT).
|
|
27
|
+
p2tr: { base: 41, witness: 1 + 1 + 64 },
|
|
28
|
+
};
|
|
29
|
+
/** The weight of a transaction spending `inputs` inputs of one type to these outputs. */
|
|
30
|
+
function txWeight(inputType, inputs, outputScriptLengths) {
|
|
31
|
+
const size = INPUT_SIZE[inputType];
|
|
32
|
+
let base = 4 +
|
|
33
|
+
(0, address_1.compactSize)(inputs) +
|
|
34
|
+
inputs * size.base +
|
|
35
|
+
(0, address_1.compactSize)(outputScriptLengths.length) +
|
|
36
|
+
4;
|
|
37
|
+
for (const length of outputScriptLengths)
|
|
38
|
+
base += 8 + (0, address_1.compactSize)(length) + length;
|
|
39
|
+
const witness = size.witness > 0 ? 2 + inputs * size.witness : 0;
|
|
40
|
+
return base * 4 + witness;
|
|
41
|
+
}
|
|
42
|
+
const vsizeOf = (weight) => Math.ceil(weight / 4);
|
|
43
|
+
exports.vsizeOf = vsizeOf;
|
|
44
|
+
const byValue = (a, b) => a.value === b.value ? (a.outpoint < b.outpoint ? -1 : 1) : a.value > b.value ? -1 : 1;
|
|
45
|
+
function assertStandard(weight) {
|
|
46
|
+
if (weight > exports.MAX_STANDARD_WEIGHT) {
|
|
47
|
+
throw new error_1.ValidationError('INVALID_INTENT', 'the transaction would exceed the standard size (400,000 weight units)');
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/** Picks inputs for the outputs at `rate`; deterministic for the same candidates. */
|
|
51
|
+
function selectCoins(request) {
|
|
52
|
+
const { outputs, inputType, rate, changeScript } = request;
|
|
53
|
+
const required = request.required ?? [];
|
|
54
|
+
// An outpoint is spent once, even when a listing names it twice (a node would refuse the
|
|
55
|
+
// transaction as `bad-txns-inputs-duplicate`, which ends the Attempt as rejected).
|
|
56
|
+
const seen = new Set(required.map((input) => input.outpoint));
|
|
57
|
+
const pool = [];
|
|
58
|
+
for (const candidate of request.candidates) {
|
|
59
|
+
if (seen.has(candidate.outpoint))
|
|
60
|
+
continue;
|
|
61
|
+
seen.add(candidate.outpoint);
|
|
62
|
+
pool.push(candidate);
|
|
63
|
+
}
|
|
64
|
+
pool.sort(byValue);
|
|
65
|
+
const scripts = outputs.map((o) => o.script.length);
|
|
66
|
+
const target = outputs.reduce((sum, o) => sum + o.value, 0n);
|
|
67
|
+
const dust = (0, address_1.dustThreshold)(changeScript, request.dustRelayFee);
|
|
68
|
+
const marginal = (0, fees_1.feeAt)(rate, (0, exports.vsizeOf)(txWeight(inputType, 1, []) - txWeight(inputType, 0, [])));
|
|
69
|
+
const settle = (inputs) => {
|
|
70
|
+
const total = inputs.reduce((sum, i) => sum + i.value, 0n);
|
|
71
|
+
const bare = (0, exports.vsizeOf)(txWeight(inputType, inputs.length, scripts));
|
|
72
|
+
if (total < target + (0, fees_1.feeAt)(rate, bare))
|
|
73
|
+
return undefined;
|
|
74
|
+
const withChangeWeight = txWeight(inputType, inputs.length, [
|
|
75
|
+
...scripts,
|
|
76
|
+
changeScript.length,
|
|
77
|
+
]);
|
|
78
|
+
const withChange = (0, exports.vsizeOf)(withChangeWeight);
|
|
79
|
+
const change = total - target - (0, fees_1.feeAt)(rate, withChange);
|
|
80
|
+
if (change >= dust) {
|
|
81
|
+
assertStandard(withChangeWeight);
|
|
82
|
+
return {
|
|
83
|
+
ok: true,
|
|
84
|
+
inputs,
|
|
85
|
+
change,
|
|
86
|
+
fee: total - target - change,
|
|
87
|
+
vsize: withChange,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
assertStandard(txWeight(inputType, inputs.length, scripts));
|
|
91
|
+
return { ok: true, inputs, change: 0n, fee: total - target, vsize: bare };
|
|
92
|
+
};
|
|
93
|
+
const everything = [...required, ...pool];
|
|
94
|
+
if (request.strategy === 'all') {
|
|
95
|
+
const done = everything.length > 0 ? settle(everything) : undefined;
|
|
96
|
+
if (done)
|
|
97
|
+
return done;
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
const chosen = [...required];
|
|
101
|
+
const first = chosen.length > 0 ? settle(chosen) : undefined;
|
|
102
|
+
if (first)
|
|
103
|
+
return first;
|
|
104
|
+
for (const candidate of pool) {
|
|
105
|
+
if (candidate.value <= marginal)
|
|
106
|
+
continue; // costs more to spend than it is worth
|
|
107
|
+
chosen.push(candidate);
|
|
108
|
+
const done = settle(chosen);
|
|
109
|
+
if (done)
|
|
110
|
+
return done;
|
|
111
|
+
}
|
|
112
|
+
// `marginal` rounds one input's cost up on its own, but a step in the whole
|
|
113
|
+
// transaction's size can be a vbyte or a satoshi less: a skipped output may still pay
|
|
114
|
+
// its way, so everything is tried before a shortfall is reported.
|
|
115
|
+
if (chosen.length < everything.length) {
|
|
116
|
+
const done = settle(everything);
|
|
117
|
+
if (done)
|
|
118
|
+
return done;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
const vsize = (0, exports.vsizeOf)(txWeight(inputType, everything.length, scripts));
|
|
122
|
+
const fee = (0, fees_1.feeAt)(rate, vsize);
|
|
123
|
+
return {
|
|
124
|
+
ok: false,
|
|
125
|
+
required: target + fee,
|
|
126
|
+
available: everything.reduce((sum, i) => sum + i.value, 0n),
|
|
127
|
+
fee,
|
|
128
|
+
vsize,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=coinselect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coinselect.js","sourceRoot":"","sources":["../../../src/adapters/utxo/coinselect.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Transaction size and coin selection (pure; `accumulative`, the default, and\n * `all`). Sizes are exact weight units with worst-case signatures (a low-s DER ECDSA\n * signature is at most 71 bytes plus the sighash byte; BIP340 is 64 bytes), so the signed\n * transaction is never larger than estimated and its fee rate never lower. Change below the\n * dust threshold is not created; its value goes to the fee (bounded by the absurd-fee guard).\n */\nimport { ValidationError } from '../../core/errors/error';\nimport { compactSize, dustThreshold } from './address';\nimport { feeAt } from './fees';\nimport type { CoinSelectionStrategy } from './network';\nimport type { UtxoAddressType } from './types';\n\n/** Bitcoin Core's `MAX_STANDARD_TX_WEIGHT` (policy.h). */\nexport const MAX_STANDARD_WEIGHT = 400_000;\n\n/** Per input: non-witness bytes (outpoint, script, sequence) and witness bytes. */\nconst INPUT_SIZE: Readonly<Record<UtxoAddressType, { base: number; witness: number }>> = {\n // 32 + 4 + 1 (empty script) + 4; witness: count, 72-byte signature push, 33-byte key push.\n p2wpkh: { base: 41, witness: 1 + 1 + 72 + 1 + 33 },\n // scriptSig: 1 (length) + 1 (push) + 22-byte redeem script.\n 'p2sh-p2wpkh': { base: 32 + 4 + 1 + 23 + 4, witness: 1 + 1 + 72 + 1 + 33 },\n // scriptSig: 1 (length) + 1 + 72 + 1 + 33.\n p2pkh: { base: 32 + 4 + 1 + 107 + 4, witness: 0 },\n // witness: count, 64-byte signature push (SIGHASH_DEFAULT).\n p2tr: { base: 41, witness: 1 + 1 + 64 },\n};\n\n/** The weight of a transaction spending `inputs` inputs of one type to these outputs. */\nexport function txWeight(\n inputType: UtxoAddressType,\n inputs: number,\n outputScriptLengths: readonly number[],\n): number {\n const size = INPUT_SIZE[inputType];\n let base =\n 4 +\n compactSize(inputs) +\n inputs * size.base +\n compactSize(outputScriptLengths.length) +\n 4;\n for (const length of outputScriptLengths) base += 8 + compactSize(length) + length;\n const witness = size.witness > 0 ? 2 + inputs * size.witness : 0;\n return base * 4 + witness;\n}\n\nexport const vsizeOf = (weight: number): number => Math.ceil(weight / 4);\n\nexport interface Spendable {\n /** `txid:vout`. */\n readonly outpoint: string;\n readonly txid: string;\n readonly vout: number;\n readonly value: bigint;\n}\n\nexport interface PlannedOutput {\n readonly script: Uint8Array;\n readonly value: bigint;\n}\n\nexport interface SelectionRequest {\n /** Eligible outputs of the wallet (already filtered for reservations and confirmations). */\n readonly candidates: readonly Spendable[];\n /** Inputs that must be spent (an RBF replacement keeps every earlier input). */\n readonly required?: readonly Spendable[];\n readonly outputs: readonly PlannedOutput[];\n readonly changeScript: Uint8Array;\n readonly inputType: UtxoAddressType;\n /** sat/kvB. */\n readonly rate: bigint;\n readonly dustRelayFee: bigint;\n readonly strategy: CoinSelectionStrategy;\n}\n\nexport interface Selection {\n readonly ok: true;\n readonly inputs: readonly Spendable[];\n readonly change: bigint;\n readonly fee: bigint;\n readonly vsize: number;\n}\n\nexport interface Shortfall {\n readonly ok: false;\n readonly required: bigint;\n readonly available: bigint;\n /** The fee of spending every eligible output (for an estimate that cannot be met). */\n readonly fee: bigint;\n readonly vsize: number;\n}\n\nconst byValue = (a: Spendable, b: Spendable): number =>\n a.value === b.value ? (a.outpoint < b.outpoint ? -1 : 1) : a.value > b.value ? -1 : 1;\n\nfunction assertStandard(weight: number): void {\n if (weight > MAX_STANDARD_WEIGHT) {\n throw new ValidationError(\n 'INVALID_INTENT',\n 'the transaction would exceed the standard size (400,000 weight units)',\n );\n }\n}\n\n/** Picks inputs for the outputs at `rate`; deterministic for the same candidates. */\nexport function selectCoins(request: SelectionRequest): Selection | Shortfall {\n const { outputs, inputType, rate, changeScript } = request;\n const required = request.required ?? [];\n // An outpoint is spent once, even when a listing names it twice (a node would refuse the\n // transaction as `bad-txns-inputs-duplicate`, which ends the Attempt as rejected).\n const seen = new Set(required.map((input) => input.outpoint));\n const pool: Spendable[] = [];\n for (const candidate of request.candidates) {\n if (seen.has(candidate.outpoint)) continue;\n seen.add(candidate.outpoint);\n pool.push(candidate);\n }\n pool.sort(byValue);\n const scripts = outputs.map((o) => o.script.length);\n const target = outputs.reduce((sum, o) => sum + o.value, 0n);\n const dust = dustThreshold(changeScript, request.dustRelayFee);\n const marginal = feeAt(\n rate,\n vsizeOf(txWeight(inputType, 1, []) - txWeight(inputType, 0, [])),\n );\n\n const settle = (inputs: readonly Spendable[]): Selection | undefined => {\n const total = inputs.reduce((sum, i) => sum + i.value, 0n);\n const bare = vsizeOf(txWeight(inputType, inputs.length, scripts));\n if (total < target + feeAt(rate, bare)) return undefined;\n const withChangeWeight = txWeight(inputType, inputs.length, [\n ...scripts,\n changeScript.length,\n ]);\n const withChange = vsizeOf(withChangeWeight);\n const change = total - target - feeAt(rate, withChange);\n if (change >= dust) {\n assertStandard(withChangeWeight);\n return {\n ok: true,\n inputs,\n change,\n fee: total - target - change,\n vsize: withChange,\n };\n }\n assertStandard(txWeight(inputType, inputs.length, scripts));\n return { ok: true, inputs, change: 0n, fee: total - target, vsize: bare };\n };\n\n const everything = [...required, ...pool];\n if (request.strategy === 'all') {\n const done = everything.length > 0 ? settle(everything) : undefined;\n if (done) return done;\n } else {\n const chosen: Spendable[] = [...required];\n const first = chosen.length > 0 ? settle(chosen) : undefined;\n if (first) return first;\n for (const candidate of pool) {\n if (candidate.value <= marginal) continue; // costs more to spend than it is worth\n chosen.push(candidate);\n const done = settle(chosen);\n if (done) return done;\n }\n // `marginal` rounds one input's cost up on its own, but a step in the whole\n // transaction's size can be a vbyte or a satoshi less: a skipped output may still pay\n // its way, so everything is tried before a shortfall is reported.\n if (chosen.length < everything.length) {\n const done = settle(everything);\n if (done) return done;\n }\n }\n const vsize = vsizeOf(txWeight(inputType, everything.length, scripts));\n const fee = feeAt(rate, vsize);\n return {\n ok: false,\n required: target + fee,\n available: everything.reduce((sum, i) => sum + i.value, 0n),\n fee,\n vsize,\n };\n}\n"]}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What every UTXO port is built from, the transport tags of the `ChainDriver` contract
|
|
3
|
+
* table, and the wallet options every builder call parses.
|
|
4
|
+
*/
|
|
5
|
+
import type { WalletOptions } from '../../core/driver/types';
|
|
6
|
+
import type { AssetRef } from '../../core/model/asset';
|
|
7
|
+
import type { Logger } from '../../core/events/logger';
|
|
8
|
+
import type { ChainInfo, NetworkInfo } from '../../core/model/chain';
|
|
9
|
+
import { type DecodedAddress } from './address';
|
|
10
|
+
import type { EsploraClient } from './esplora';
|
|
11
|
+
import type { UtxoNetworkConfig } from './network';
|
|
12
|
+
import type { UtxoAddressType, UtxoCallTags } from './types';
|
|
13
|
+
export interface UtxoContext {
|
|
14
|
+
readonly esplora: EsploraClient;
|
|
15
|
+
readonly chain: ChainInfo;
|
|
16
|
+
readonly network: NetworkInfo;
|
|
17
|
+
readonly config: UtxoNetworkConfig;
|
|
18
|
+
readonly log: Logger;
|
|
19
|
+
}
|
|
20
|
+
export declare const READ: UtxoCallTags;
|
|
21
|
+
export declare const MONITOR: UtxoCallTags;
|
|
22
|
+
export declare const PROOF: UtxoCallTags;
|
|
23
|
+
export declare const withSignal: (tags: UtxoCallTags, signal?: AbortSignal) => UtxoCallTags;
|
|
24
|
+
/**
|
|
25
|
+
* Runs `work` on each item, at most `limit` at a time. After a failure the
|
|
26
|
+
* other runners stop at their next step, and the first failure is thrown.
|
|
27
|
+
*/
|
|
28
|
+
export declare function forEachBounded<T>(items: readonly T[], limit: number, work: (item: T) => Promise<void>): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* On a proof path only a definitive negative proof may answer "no"
|
|
31
|
+
* (for Bitcoin: a quorum-attested final spend by another transaction). Every other RPC or
|
|
32
|
+
* HTTP error decides nothing: a non-retryable provider error, such as a CDN or proxy 400,
|
|
33
|
+
* 410 or 422 (the transport's `RPC_ERROR`, ambiguous or not) or a 401/403
|
|
34
|
+
* (`PROVIDER_MISCONFIGURED`), becomes a retryable `PROVIDER_UNAVAILABLE` here, so the monitor
|
|
35
|
+
* never rethrows it. Retryable provider errors already decide nothing and pass unchanged, as
|
|
36
|
+
* do Esplora's own 404s, which the client maps to `null` first. The cost is liveness only.
|
|
37
|
+
*/
|
|
38
|
+
export declare function proofRead<T>(read: () => Promise<T>): Promise<T>;
|
|
39
|
+
export declare const ADDRESS_TYPES: readonly UtxoAddressType[];
|
|
40
|
+
export interface ParsedWalletOptions {
|
|
41
|
+
readonly addressType: UtxoAddressType;
|
|
42
|
+
readonly changeAddress?: DecodedAddress;
|
|
43
|
+
/** The explicit opt-out for a change address the wallet's key does not derive. */
|
|
44
|
+
readonly allowExternalChangeAddress: boolean;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* `WalletConfig.utxo`, validated (`CONFIG_INVALID`): the address type, the change address
|
|
48
|
+
* and its opt-out. Whether the wallet derives the change address is checked where the
|
|
49
|
+
* wallet's keys are known (`changeAddressOf`, `spend.ts`).
|
|
50
|
+
*/
|
|
51
|
+
export declare function parseWalletOptions(wallet: WalletOptions | undefined, config: UtxoNetworkConfig): ParsedWalletOptions;
|
|
52
|
+
export declare function assertNative(asset: AssetRef): void;
|
|
53
|
+
/** Splits an `inputs` ordering entry (`txid:vout`); malformed data decides nothing. */
|
|
54
|
+
export declare function parseOutpoint(outpoint: string): {
|
|
55
|
+
txid: string;
|
|
56
|
+
vout: number;
|
|
57
|
+
};
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ADDRESS_TYPES = exports.withSignal = exports.PROOF = exports.MONITOR = exports.READ = void 0;
|
|
4
|
+
exports.forEachBounded = forEachBounded;
|
|
5
|
+
exports.proofRead = proofRead;
|
|
6
|
+
exports.parseWalletOptions = parseWalletOptions;
|
|
7
|
+
exports.assertNative = assertNative;
|
|
8
|
+
exports.parseOutpoint = parseOutpoint;
|
|
9
|
+
const error_1 = require("../../core/errors/error");
|
|
10
|
+
const names_1 = require("../../core/util/names");
|
|
11
|
+
const address_1 = require("./address");
|
|
12
|
+
exports.READ = { purpose: 'read', retry: 'safe' };
|
|
13
|
+
exports.MONITOR = { purpose: 'monitor', retry: 'safe' };
|
|
14
|
+
exports.PROOF = { purpose: 'proof', retry: 'safe', quorum: 'proof' };
|
|
15
|
+
const withSignal = (tags, signal) => signal ? { ...tags, signal } : tags;
|
|
16
|
+
exports.withSignal = withSignal;
|
|
17
|
+
/**
|
|
18
|
+
* Runs `work` on each item, at most `limit` at a time. After a failure the
|
|
19
|
+
* other runners stop at their next step, and the first failure is thrown.
|
|
20
|
+
*/
|
|
21
|
+
async function forEachBounded(items, limit, work) {
|
|
22
|
+
let next = 0;
|
|
23
|
+
let failed = false;
|
|
24
|
+
const runner = async () => {
|
|
25
|
+
while (!failed && next < items.length) {
|
|
26
|
+
const item = items[next++];
|
|
27
|
+
try {
|
|
28
|
+
await work(item);
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
failed = true;
|
|
32
|
+
throw error;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
await Promise.all(Array.from({ length: Math.min(limit, items.length) }, runner));
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* On a proof path only a definitive negative proof may answer "no"
|
|
40
|
+
* (for Bitcoin: a quorum-attested final spend by another transaction). Every other RPC or
|
|
41
|
+
* HTTP error decides nothing: a non-retryable provider error, such as a CDN or proxy 400,
|
|
42
|
+
* 410 or 422 (the transport's `RPC_ERROR`, ambiguous or not) or a 401/403
|
|
43
|
+
* (`PROVIDER_MISCONFIGURED`), becomes a retryable `PROVIDER_UNAVAILABLE` here, so the monitor
|
|
44
|
+
* never rethrows it. Retryable provider errors already decide nothing and pass unchanged, as
|
|
45
|
+
* do Esplora's own 404s, which the client maps to `null` first. The cost is liveness only.
|
|
46
|
+
*/
|
|
47
|
+
async function proofRead(read) {
|
|
48
|
+
try {
|
|
49
|
+
return await read();
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
if ((0, error_1.isCryptoAioError)(error) && error.category === 'provider' && !error.retryable) {
|
|
53
|
+
throw new error_1.ProviderError('PROVIDER_UNAVAILABLE', 'the proof read failed on this endpoint; nothing is decided', { cause: error });
|
|
54
|
+
}
|
|
55
|
+
throw error;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
exports.ADDRESS_TYPES = [
|
|
59
|
+
'p2wpkh',
|
|
60
|
+
'p2sh-p2wpkh',
|
|
61
|
+
'p2pkh',
|
|
62
|
+
'p2tr',
|
|
63
|
+
];
|
|
64
|
+
const WALLET_OPTION_KEYS = ['addressType', 'changeAddress', 'allowExternalChangeAddress'];
|
|
65
|
+
/**
|
|
66
|
+
* `WalletConfig.utxo`, validated (`CONFIG_INVALID`): the address type, the change address
|
|
67
|
+
* and its opt-out. Whether the wallet derives the change address is checked where the
|
|
68
|
+
* wallet's keys are known (`changeAddressOf`, `spend.ts`).
|
|
69
|
+
*/
|
|
70
|
+
function parseWalletOptions(wallet, config) {
|
|
71
|
+
const raw = wallet?.utxo;
|
|
72
|
+
if (raw === undefined)
|
|
73
|
+
return { addressType: 'p2wpkh', allowExternalChangeAddress: false };
|
|
74
|
+
if (raw === null || typeof raw !== 'object' || Array.isArray(raw)) {
|
|
75
|
+
throw new error_1.ConfigError('CONFIG_INVALID', 'wallet.utxo must be an object');
|
|
76
|
+
}
|
|
77
|
+
const options = raw;
|
|
78
|
+
// The accepted names, never the caller's key (it may be a pasted secret).
|
|
79
|
+
if (Object.keys(options).some((key) => !WALLET_OPTION_KEYS.includes(key))) {
|
|
80
|
+
throw new error_1.ConfigError('CONFIG_INVALID', `wallet.utxo has an ${(0, names_1.unknownName)('option', WALLET_OPTION_KEYS)}`);
|
|
81
|
+
}
|
|
82
|
+
const type = options.addressType ?? 'p2wpkh';
|
|
83
|
+
if (!exports.ADDRESS_TYPES.includes(type)) {
|
|
84
|
+
throw new error_1.ConfigError('CONFIG_INVALID', `wallet.utxo.addressType must be one of ${exports.ADDRESS_TYPES.join(', ')}`);
|
|
85
|
+
}
|
|
86
|
+
let changeAddress;
|
|
87
|
+
if (options.changeAddress !== undefined) {
|
|
88
|
+
try {
|
|
89
|
+
changeAddress = (0, address_1.decodeAddress)(options.changeAddress, config.address);
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
throw new error_1.ConfigError('CONFIG_INVALID', 'wallet.utxo.changeAddress is not a valid address on this network');
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
const external = options.allowExternalChangeAddress ?? false;
|
|
96
|
+
if (typeof external !== 'boolean') {
|
|
97
|
+
throw new error_1.ConfigError('CONFIG_INVALID', 'wallet.utxo.allowExternalChangeAddress must be a boolean');
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
addressType: type,
|
|
101
|
+
...(changeAddress ? { changeAddress } : {}),
|
|
102
|
+
allowExternalChangeAddress: external,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
function assertNative(asset) {
|
|
106
|
+
if (asset !== 'native') {
|
|
107
|
+
throw new error_1.UnsupportedCapabilityError('UNSUPPORTED_CAPABILITY', 'Bitcoin has no tokens; only the native asset can be sent');
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/** Splits an `inputs` ordering entry (`txid:vout`); malformed data decides nothing. */
|
|
111
|
+
function parseOutpoint(outpoint) {
|
|
112
|
+
const match = /^([0-9a-f]{64}):(0|[1-9][0-9]{0,9})$/.exec(outpoint);
|
|
113
|
+
if (!match || Number(match[2]) > 0xffffffff) {
|
|
114
|
+
throw new error_1.ProviderError('PROVIDER_UNAVAILABLE', 'malformed outpoint in the ordering');
|
|
115
|
+
}
|
|
116
|
+
return { txid: match[1], vout: Number(match[2]) };
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../../src/adapters/utxo/context.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * What every UTXO port is built from, the transport tags of the `ChainDriver` contract\n * table, and the wallet options every builder call parses.\n */\nimport type { WalletOptions } from '../../core/driver/types';\nimport {\n ConfigError,\n ProviderError,\n UnsupportedCapabilityError,\n isCryptoAioError,\n} from '../../core/errors/error';\nimport type { AssetRef } from '../../core/model/asset';\nimport { unknownName } from '../../core/util/names';\nimport type { Logger } from '../../core/events/logger';\nimport type { ChainInfo, NetworkInfo } from '../../core/model/chain';\nimport { decodeAddress, type DecodedAddress } from './address';\nimport type { EsploraClient } from './esplora';\nimport type { UtxoNetworkConfig } from './network';\nimport type { UtxoAddressType, UtxoCallTags } from './types';\n\nexport interface UtxoContext {\n readonly esplora: EsploraClient;\n readonly chain: ChainInfo;\n readonly network: NetworkInfo;\n readonly config: UtxoNetworkConfig;\n readonly log: Logger;\n}\n\nexport const READ: UtxoCallTags = { purpose: 'read', retry: 'safe' };\nexport const MONITOR: UtxoCallTags = { purpose: 'monitor', retry: 'safe' };\nexport const PROOF: UtxoCallTags = { purpose: 'proof', retry: 'safe', quorum: 'proof' };\n\nexport const withSignal = (tags: UtxoCallTags, signal?: AbortSignal): UtxoCallTags =>\n signal ? { ...tags, signal } : tags;\n\n/**\n * Runs `work` on each item, at most `limit` at a time. After a failure the\n * other runners stop at their next step, and the first failure is thrown.\n */\nexport async function forEachBounded<T>(\n items: readonly T[],\n limit: number,\n work: (item: T) => Promise<void>,\n): Promise<void> {\n let next = 0;\n let failed = false;\n const runner = async (): Promise<void> => {\n while (!failed && next < items.length) {\n const item = items[next++] as T;\n try {\n await work(item);\n } catch (error) {\n failed = true;\n throw error;\n }\n }\n };\n await Promise.all(Array.from({ length: Math.min(limit, items.length) }, runner));\n}\n\n/**\n * On a proof path only a definitive negative proof may answer \"no\"\n * (for Bitcoin: a quorum-attested final spend by another transaction). Every other RPC or\n * HTTP error decides nothing: a non-retryable provider error, such as a CDN or proxy 400,\n * 410 or 422 (the transport's `RPC_ERROR`, ambiguous or not) or a 401/403\n * (`PROVIDER_MISCONFIGURED`), becomes a retryable `PROVIDER_UNAVAILABLE` here, so the monitor\n * never rethrows it. Retryable provider errors already decide nothing and pass unchanged, as\n * do Esplora's own 404s, which the client maps to `null` first. The cost is liveness only.\n */\nexport async function proofRead<T>(read: () => Promise<T>): Promise<T> {\n try {\n return await read();\n } catch (error) {\n if (isCryptoAioError(error) && error.category === 'provider' && !error.retryable) {\n throw new ProviderError(\n 'PROVIDER_UNAVAILABLE',\n 'the proof read failed on this endpoint; nothing is decided',\n { cause: error },\n );\n }\n throw error;\n }\n}\n\nexport const ADDRESS_TYPES: readonly UtxoAddressType[] = [\n 'p2wpkh',\n 'p2sh-p2wpkh',\n 'p2pkh',\n 'p2tr',\n];\n\nexport interface ParsedWalletOptions {\n readonly addressType: UtxoAddressType;\n readonly changeAddress?: DecodedAddress;\n /** The explicit opt-out for a change address the wallet's key does not derive. */\n readonly allowExternalChangeAddress: boolean;\n}\n\nconst WALLET_OPTION_KEYS = ['addressType', 'changeAddress', 'allowExternalChangeAddress'];\n\n/**\n * `WalletConfig.utxo`, validated (`CONFIG_INVALID`): the address type, the change address\n * and its opt-out. Whether the wallet derives the change address is checked where the\n * wallet's keys are known (`changeAddressOf`, `spend.ts`).\n */\nexport function parseWalletOptions(\n wallet: WalletOptions | undefined,\n config: UtxoNetworkConfig,\n): ParsedWalletOptions {\n const raw = wallet?.utxo;\n if (raw === undefined)\n return { addressType: 'p2wpkh', allowExternalChangeAddress: false };\n if (raw === null || typeof raw !== 'object' || Array.isArray(raw)) {\n throw new ConfigError('CONFIG_INVALID', 'wallet.utxo must be an object');\n }\n const options = raw as Readonly<Record<string, unknown>>;\n // The accepted names, never the caller's key (it may be a pasted secret).\n if (Object.keys(options).some((key) => !WALLET_OPTION_KEYS.includes(key))) {\n throw new ConfigError(\n 'CONFIG_INVALID',\n `wallet.utxo has an ${unknownName('option', WALLET_OPTION_KEYS)}`,\n );\n }\n const type = options.addressType ?? 'p2wpkh';\n if (!ADDRESS_TYPES.includes(type as UtxoAddressType)) {\n throw new ConfigError(\n 'CONFIG_INVALID',\n `wallet.utxo.addressType must be one of ${ADDRESS_TYPES.join(', ')}`,\n );\n }\n let changeAddress: DecodedAddress | undefined;\n if (options.changeAddress !== undefined) {\n try {\n changeAddress = decodeAddress(options.changeAddress as string, config.address);\n } catch {\n throw new ConfigError(\n 'CONFIG_INVALID',\n 'wallet.utxo.changeAddress is not a valid address on this network',\n );\n }\n }\n const external = options.allowExternalChangeAddress ?? false;\n if (typeof external !== 'boolean') {\n throw new ConfigError(\n 'CONFIG_INVALID',\n 'wallet.utxo.allowExternalChangeAddress must be a boolean',\n );\n }\n return {\n addressType: type as UtxoAddressType,\n ...(changeAddress ? { changeAddress } : {}),\n allowExternalChangeAddress: external,\n };\n}\n\nexport function assertNative(asset: AssetRef): void {\n if (asset !== 'native') {\n throw new UnsupportedCapabilityError(\n 'UNSUPPORTED_CAPABILITY',\n 'Bitcoin has no tokens; only the native asset can be sent',\n );\n }\n}\n\n/** Splits an `inputs` ordering entry (`txid:vout`); malformed data decides nothing. */\nexport function parseOutpoint(outpoint: string): { txid: string; vout: number } {\n const match = /^([0-9a-f]{64}):(0|[1-9][0-9]{0,9})$/.exec(outpoint);\n if (!match || Number(match[2]) > 0xffffffff) {\n throw new ProviderError('PROVIDER_UNAVAILABLE', 'malformed outpoint in the ordering');\n }\n return { txid: match[1] as string, vout: Number(match[2]) };\n}\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Esplora transactions as `DriverTransaction`s (SDK-free). Every output whose script has an
|
|
3
|
+
* address is a `vout:<n>` transfer from the input addresses; an output this
|
|
4
|
+
* library cannot name that carries value (a future witness version, a bare script) makes the
|
|
5
|
+
* decoding `partial`. Addresses are derived from the scripts, never taken from the server's
|
|
6
|
+
* `scriptpubkey_address`, which a server could leave out (making a deposit `partial`) or
|
|
7
|
+
* change (crediting another address). A Bitcoin transaction that is in a block has executed:
|
|
8
|
+
* `success` is `true` (general decoding reports the chain as it is).
|
|
9
|
+
*/
|
|
10
|
+
import type { DriverTransaction, DriverTxObservation } from '../../core/driver/types';
|
|
11
|
+
import { type AddressParams } from './address';
|
|
12
|
+
import type { EsploraStatus, EsploraTx } from './types';
|
|
13
|
+
export declare function observationOf(txid: string, status: EsploraStatus): DriverTxObservation;
|
|
14
|
+
export declare function decodeTransaction(tx: EsploraTx, params: AddressParams): DriverTransaction;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.observationOf = observationOf;
|
|
4
|
+
exports.decodeTransaction = decodeTransaction;
|
|
5
|
+
const bytes_1 = require("../../core/util/bytes");
|
|
6
|
+
const address_1 = require("./address");
|
|
7
|
+
function observationOf(txid, status) {
|
|
8
|
+
return status.confirmed
|
|
9
|
+
? {
|
|
10
|
+
seen: 'block',
|
|
11
|
+
txHash: txid,
|
|
12
|
+
blockHeight: status.blockHeight,
|
|
13
|
+
blockHash: status.blockHash,
|
|
14
|
+
success: true,
|
|
15
|
+
}
|
|
16
|
+
: { seen: 'mempool', txHash: txid };
|
|
17
|
+
}
|
|
18
|
+
/** The canonical address an output's script pays on this network, or `undefined`. */
|
|
19
|
+
function addressOf(output, params) {
|
|
20
|
+
return (0, address_1.addressFromScript)((0, bytes_1.fromHex)(output.script), params)?.canonical;
|
|
21
|
+
}
|
|
22
|
+
function decodeTransaction(tx, params) {
|
|
23
|
+
const coinbase = tx.vin.some((input) => input.coinbase);
|
|
24
|
+
const senders = tx.vin.map((input) => input.prevout ? addressOf(input.prevout, params) : undefined);
|
|
25
|
+
const recipients = tx.vout.map((output) => addressOf(output, params));
|
|
26
|
+
const from = [
|
|
27
|
+
...new Set(senders.filter((address) => address !== undefined)),
|
|
28
|
+
];
|
|
29
|
+
const transfers = [];
|
|
30
|
+
let partial = false;
|
|
31
|
+
tx.vout.forEach((output, n) => {
|
|
32
|
+
const to = recipients[n];
|
|
33
|
+
if (to === undefined) {
|
|
34
|
+
if (output.value > 0n)
|
|
35
|
+
partial = true;
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
transfers.push({
|
|
39
|
+
locator: `vout:${n}`,
|
|
40
|
+
from,
|
|
41
|
+
to,
|
|
42
|
+
asset: 'native',
|
|
43
|
+
amount: output.value,
|
|
44
|
+
source: 'native',
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
return {
|
|
48
|
+
id: tx.txid,
|
|
49
|
+
observation: observationOf(tx.txid, tx.status),
|
|
50
|
+
...(coinbase ? {} : { fee: [{ asset: 'native', amount: tx.fee }] }),
|
|
51
|
+
transfers,
|
|
52
|
+
decoding: partial ? 'partial' : 'complete',
|
|
53
|
+
...(tx.status.blockTime !== undefined ? { timestamp: tx.status.blockTime } : {}),
|
|
54
|
+
details: {
|
|
55
|
+
version: tx.version,
|
|
56
|
+
locktime: tx.locktime,
|
|
57
|
+
weight: tx.weight,
|
|
58
|
+
vin: tx.vin.map((input, n) => {
|
|
59
|
+
const address = senders[n];
|
|
60
|
+
return {
|
|
61
|
+
txid: input.txid,
|
|
62
|
+
vout: input.vout,
|
|
63
|
+
coinbase: input.coinbase,
|
|
64
|
+
sequence: input.sequence,
|
|
65
|
+
...(input.prevout
|
|
66
|
+
? {
|
|
67
|
+
value: input.prevout.value,
|
|
68
|
+
...(address !== undefined ? { address } : {}),
|
|
69
|
+
}
|
|
70
|
+
: {}),
|
|
71
|
+
};
|
|
72
|
+
}),
|
|
73
|
+
vout: tx.vout.map((output, n) => {
|
|
74
|
+
const address = recipients[n];
|
|
75
|
+
return {
|
|
76
|
+
n,
|
|
77
|
+
value: output.value,
|
|
78
|
+
type: output.type,
|
|
79
|
+
...(address !== undefined ? { address } : {}),
|
|
80
|
+
};
|
|
81
|
+
}),
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=decode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decode.js","sourceRoot":"","sources":["../../../src/adapters/utxo/decode.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Esplora transactions as `DriverTransaction`s (SDK-free). Every output whose script has an\n * address is a `vout:<n>` transfer from the input addresses; an output this\n * library cannot name that carries value (a future witness version, a bare script) makes the\n * decoding `partial`. Addresses are derived from the scripts, never taken from the server's\n * `scriptpubkey_address`, which a server could leave out (making a deposit `partial`) or\n * change (crediting another address). A Bitcoin transaction that is in a block has executed:\n * `success` is `true` (general decoding reports the chain as it is).\n */\nimport type {\n DriverTransaction,\n DriverTransfer,\n DriverTxObservation,\n} from '../../core/driver/types';\nimport { fromHex } from '../../core/util/bytes';\nimport { addressFromScript, type AddressParams } from './address';\nimport type { EsploraOutput, EsploraStatus, EsploraTx } from './types';\n\nexport function observationOf(txid: string, status: EsploraStatus): DriverTxObservation {\n return status.confirmed\n ? {\n seen: 'block',\n txHash: txid,\n blockHeight: status.blockHeight as bigint,\n blockHash: status.blockHash as string,\n success: true,\n }\n : { seen: 'mempool', txHash: txid };\n}\n\n/** The canonical address an output's script pays on this network, or `undefined`. */\nfunction addressOf(output: EsploraOutput, params: AddressParams): string | undefined {\n return addressFromScript(fromHex(output.script), params)?.canonical;\n}\n\nexport function decodeTransaction(\n tx: EsploraTx,\n params: AddressParams,\n): DriverTransaction {\n const coinbase = tx.vin.some((input) => input.coinbase);\n const senders = tx.vin.map((input) =>\n input.prevout ? addressOf(input.prevout, params) : undefined,\n );\n const recipients = tx.vout.map((output) => addressOf(output, params));\n const from = [\n ...new Set(senders.filter((address): address is string => address !== undefined)),\n ];\n const transfers: DriverTransfer[] = [];\n let partial = false;\n tx.vout.forEach((output, n) => {\n const to = recipients[n];\n if (to === undefined) {\n if (output.value > 0n) partial = true;\n return;\n }\n transfers.push({\n locator: `vout:${n}`,\n from,\n to,\n asset: 'native',\n amount: output.value,\n source: 'native',\n });\n });\n return {\n id: tx.txid,\n observation: observationOf(tx.txid, tx.status),\n ...(coinbase ? {} : { fee: [{ asset: 'native' as const, amount: tx.fee }] }),\n transfers,\n decoding: partial ? 'partial' : 'complete',\n ...(tx.status.blockTime !== undefined ? { timestamp: tx.status.blockTime } : {}),\n details: {\n version: tx.version,\n locktime: tx.locktime,\n weight: tx.weight,\n vin: tx.vin.map((input, n) => {\n const address = senders[n];\n return {\n txid: input.txid,\n vout: input.vout,\n coinbase: input.coinbase,\n sequence: input.sequence,\n ...(input.prevout\n ? {\n value: input.prevout.value,\n ...(address !== undefined ? { address } : {}),\n }\n : {}),\n };\n }),\n vout: tx.vout.map((output, n) => {\n const address = recipients[n];\n return {\n n,\n value: output.value,\n type: output.type,\n ...(address !== undefined ? { address } : {}),\n };\n }),\n },\n };\n}\n"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The UTXO driver factory: validated network config, endpoint probes on both transports,
|
|
3
|
+
* and the ports. Loaded only by the manifest's `load()`, with bitcoinjs-lib.
|
|
4
|
+
*/
|
|
5
|
+
import type { DriverFactory } from '../../core/driver/types';
|
|
6
|
+
import { networkOf } from './codec';
|
|
7
|
+
import { bitcoin } from './sdk';
|
|
8
|
+
export interface UtxoNativeClient {
|
|
9
|
+
/** The bitcoinjs-lib module, with this library's `@noble/curves` ECC backend installed. */
|
|
10
|
+
readonly bitcoin: typeof bitcoin;
|
|
11
|
+
/** A fresh copy of this network's bitcoinjs parameters. */
|
|
12
|
+
readonly network: ReturnType<typeof networkOf>;
|
|
13
|
+
/** A GET to the handle's Esplora (`rpc`) endpoints, through the policy-wrapped transport. */
|
|
14
|
+
esplora<T = unknown>(path: string, responseType?: 'json' | 'text'): Promise<T>;
|
|
15
|
+
}
|
|
16
|
+
export declare const utxoDriverFactory: DriverFactory;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.utxoDriverFactory = void 0;
|
|
4
|
+
const error_1 = require("../../core/errors/error");
|
|
5
|
+
const builder_1 = require("./builder");
|
|
6
|
+
const codec_1 = require("./codec");
|
|
7
|
+
const context_1 = require("./context");
|
|
8
|
+
const esplora_1 = require("./esplora");
|
|
9
|
+
const network_1 = require("./network");
|
|
10
|
+
const proofs_1 = require("./proofs");
|
|
11
|
+
const reader_1 = require("./reader");
|
|
12
|
+
const sdk_1 = require("./sdk");
|
|
13
|
+
const preview_1 = require("./preview");
|
|
14
|
+
const spend_1 = require("./spend");
|
|
15
|
+
function probes(expectedIdentity) {
|
|
16
|
+
const text = (call, path, route) => call.http({ method: 'GET', path, route, responseType: 'text' });
|
|
17
|
+
return {
|
|
18
|
+
identity: async (call) => (0, esplora_1.parseHash)(await text(call, '/block-height/0', '/block-height/:height')),
|
|
19
|
+
expectedIdentity,
|
|
20
|
+
height: async (call) => (0, esplora_1.parseHeight)(await text(call, '/blocks/tip/height', '/blocks/tip/height')),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
exports.utxoDriverFactory = {
|
|
24
|
+
async create(ctx) {
|
|
25
|
+
const config = (0, network_1.utxoNetworkConfig)(ctx.chain, ctx.network, ctx.options);
|
|
26
|
+
if (!ctx.indexer) {
|
|
27
|
+
throw new error_1.ConfigError('CONFIG_INVALID', 'the UTXO driver requires an indexer provider');
|
|
28
|
+
}
|
|
29
|
+
// Both transports, before any traffic: the genesis-hash probe keeps an endpoint of
|
|
30
|
+
// another network out of the `rpc` reads and the `indexer` reads alike.
|
|
31
|
+
ctx.transport.setProbes(probes(config.genesisHash));
|
|
32
|
+
ctx.indexer.setProbes(probes(config.genesisHash));
|
|
33
|
+
const esplora = new esplora_1.EsploraClient(ctx.transport, ctx.indexer);
|
|
34
|
+
const utxo = {
|
|
35
|
+
esplora,
|
|
36
|
+
chain: ctx.chain,
|
|
37
|
+
network: ctx.network,
|
|
38
|
+
config,
|
|
39
|
+
log: ctx.log,
|
|
40
|
+
};
|
|
41
|
+
const network = (0, codec_1.networkOf)(config.address);
|
|
42
|
+
const builder = (0, builder_1.utxoBuilder)(utxo, network);
|
|
43
|
+
return {
|
|
44
|
+
ordering: 'inputs',
|
|
45
|
+
capabilities: config.capabilities,
|
|
46
|
+
address: (0, reader_1.addressCodec)(utxo),
|
|
47
|
+
reader: (0, reader_1.chainReader)(utxo),
|
|
48
|
+
builder,
|
|
49
|
+
broadcaster: (0, builder_1.utxoBroadcaster)(utxo),
|
|
50
|
+
proofs: (0, proofs_1.proofSource)(utxo),
|
|
51
|
+
replacement: (0, builder_1.utxoReplacement)(utxo, network),
|
|
52
|
+
blocks: (0, proofs_1.blockSource)(utxo),
|
|
53
|
+
history: (0, reader_1.addressHistory)(utxo),
|
|
54
|
+
ext: {
|
|
55
|
+
utxo: {
|
|
56
|
+
listUnspent: (address) => (0, reader_1.listUnspent)(utxo, address),
|
|
57
|
+
coinSelection: (request) => (0, preview_1.coinSelectionPreview)(utxo, request),
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
limits: () => ({ maxOutputs: spend_1.MAX_OUTPUTS }),
|
|
61
|
+
createNativeClient: () => {
|
|
62
|
+
// The doc's promise: taproot works on this module (and a swapped backend is undone).
|
|
63
|
+
(0, sdk_1.useNobleEcc)();
|
|
64
|
+
const client = {
|
|
65
|
+
bitcoin: sdk_1.bitcoin,
|
|
66
|
+
network: { ...network, bip32: { ...network.bip32 } },
|
|
67
|
+
esplora: (path, responseType = 'json') => ctx.transport.http({ method: 'GET', path, route: '/native', responseType }, context_1.READ),
|
|
68
|
+
};
|
|
69
|
+
return { client };
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
//# sourceMappingURL=driver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"driver.js","sourceRoot":"","sources":["../../../src/adapters/utxo/driver.ts"],"names":[],"mappings":";;;AAKA,mDAAsD;AAEtD,uCAA0E;AAC1E,mCAAoC;AACpC,uCAAmD;AACnD,uCAAkE;AAClE,uCAA8C;AAC9C,qCAAoD;AACpD,qCAAkF;AAClF,+BAA6C;AAC7C,uCAAiD;AACjD,mCAAsC;AAYtC,SAAS,MAAM,CAAC,gBAAwB;IACtC,MAAM,IAAI,GAAG,CAAC,IAAkB,EAAE,IAAY,EAAE,KAAa,EAAE,EAAE,CAC/D,IAAI,CAAC,IAAI,CAAS,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC,CAAC;IAC1E,OAAO;QACL,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CACvB,IAAA,mBAAS,EAAC,MAAM,IAAI,CAAC,IAAI,EAAE,iBAAiB,EAAE,uBAAuB,CAAC,CAAC;QACzE,gBAAgB;QAChB,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CACrB,IAAA,qBAAW,EAAC,MAAM,IAAI,CAAC,IAAI,EAAE,oBAAoB,EAAE,oBAAoB,CAAC,CAAC;KAC5E,CAAC;AACJ,CAAC;AAEY,QAAA,iBAAiB,GAAkB;IAC9C,KAAK,CAAC,MAAM,CAAC,GAAkB;QAC7B,MAAM,MAAM,GAAG,IAAA,2BAAiB,EAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;QACtE,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;YACjB,MAAM,IAAI,mBAAW,CACnB,gBAAgB,EAChB,8CAA8C,CAC/C,CAAC;QACJ,CAAC;QACD,mFAAmF;QACnF,wEAAwE;QACxE,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC;QACpD,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC;QAClD,MAAM,OAAO,GAAG,IAAI,uBAAa,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;QAC9D,MAAM,IAAI,GAAgB;YACxB,OAAO;YACP,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,OAAO,EAAE,GAAG,CAAC,OAAO;YACpB,MAAM;YACN,GAAG,EAAE,GAAG,CAAC,GAAG;SACb,CAAC;QACF,MAAM,OAAO,GAAG,IAAA,iBAAS,EAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC1C,MAAM,OAAO,GAAG,IAAA,qBAAW,EAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC3C,OAAO;YACL,QAAQ,EAAE,QAAQ;YAClB,YAAY,EAAE,MAAM,CAAC,YAAY;YACjC,OAAO,EAAE,IAAA,qBAAY,EAAC,IAAI,CAAC;YAC3B,MAAM,EAAE,IAAA,oBAAW,EAAC,IAAI,CAAC;YACzB,OAAO;YACP,WAAW,EAAE,IAAA,yBAAe,EAAC,IAAI,CAAC;YAClC,MAAM,EAAE,IAAA,oBAAW,EAAC,IAAI,CAAC;YACzB,WAAW,EAAE,IAAA,yBAAe,EAAC,IAAI,EAAE,OAAO,CAAC;YAC3C,MAAM,EAAE,IAAA,oBAAW,EAAC,IAAI,CAAC;YACzB,OAAO,EAAE,IAAA,uBAAc,EAAC,IAAI,CAAC;YAC7B,GAAG,EAAE;gBACH,IAAI,EAAE;oBACJ,WAAW,EAAE,CAAC,OAAe,EAAE,EAAE,CAAC,IAAA,oBAAW,EAAC,IAAI,EAAE,OAAO,CAAC;oBAC5D,aAAa,EAAE,CAAC,OAAwD,EAAE,EAAE,CAC1E,IAAA,8BAAoB,EAAC,IAAI,EAAE,OAAO,CAAC;iBACtC;aACgB;YACnB,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,mBAAW,EAAE,CAAC;YAC3C,kBAAkB,EAAE,GAAG,EAAE;gBACvB,qFAAqF;gBACrF,IAAA,iBAAW,GAAE,CAAC;gBACd,MAAM,MAAM,GAAqB;oBAC/B,OAAO,EAAP,aAAO;oBACP,OAAO,EAAE,EAAE,GAAG,OAAO,EAAE,KAAK,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,EAAE,EAAE;oBACpD,OAAO,EAAE,CAAI,IAAY,EAAE,eAAgC,MAAM,EAAE,EAAE,CACnE,GAAG,CAAC,SAAS,CAAC,IAAI,CAChB,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,EACvD,cAAI,CACL;iBACJ,CAAC;gBACF,OAAO,EAAE,MAAM,EAAE,CAAC;YACpB,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC","sourcesContent":["/**\n * The UTXO driver factory: validated network config, endpoint probes on both transports,\n * and the ports. Loaded only by the manifest's `load()`, with bitcoinjs-lib.\n */\nimport type { ChainDriver, DriverContext, DriverFactory } from '../../core/driver/types';\nimport { ConfigError } from '../../core/errors/error';\nimport type { EndpointCall, HealthProbes } from '../../core/transport/types';\nimport { utxoBroadcaster, utxoBuilder, utxoReplacement } from './builder';\nimport { networkOf } from './codec';\nimport { READ, type UtxoContext } from './context';\nimport { EsploraClient, parseHash, parseHeight } from './esplora';\nimport { utxoNetworkConfig } from './network';\nimport { blockSource, proofSource } from './proofs';\nimport { addressCodec, addressHistory, chainReader, listUnspent } from './reader';\nimport { bitcoin, useNobleEcc } from './sdk';\nimport { coinSelectionPreview } from './preview';\nimport { MAX_OUTPUTS } from './spend';\nimport type { UtxoExt } from './types';\n\nexport interface UtxoNativeClient {\n /** The bitcoinjs-lib module, with this library's `@noble/curves` ECC backend installed. */\n readonly bitcoin: typeof bitcoin;\n /** A fresh copy of this network's bitcoinjs parameters. */\n readonly network: ReturnType<typeof networkOf>;\n /** A GET to the handle's Esplora (`rpc`) endpoints, through the policy-wrapped transport. */\n esplora<T = unknown>(path: string, responseType?: 'json' | 'text'): Promise<T>;\n}\n\nfunction probes(expectedIdentity: string): HealthProbes {\n const text = (call: EndpointCall, path: string, route: string) =>\n call.http<string>({ method: 'GET', path, route, responseType: 'text' });\n return {\n identity: async (call) =>\n parseHash(await text(call, '/block-height/0', '/block-height/:height')),\n expectedIdentity,\n height: async (call) =>\n parseHeight(await text(call, '/blocks/tip/height', '/blocks/tip/height')),\n };\n}\n\nexport const utxoDriverFactory: DriverFactory = {\n async create(ctx: DriverContext): Promise<ChainDriver> {\n const config = utxoNetworkConfig(ctx.chain, ctx.network, ctx.options);\n if (!ctx.indexer) {\n throw new ConfigError(\n 'CONFIG_INVALID',\n 'the UTXO driver requires an indexer provider',\n );\n }\n // Both transports, before any traffic: the genesis-hash probe keeps an endpoint of\n // another network out of the `rpc` reads and the `indexer` reads alike.\n ctx.transport.setProbes(probes(config.genesisHash));\n ctx.indexer.setProbes(probes(config.genesisHash));\n const esplora = new EsploraClient(ctx.transport, ctx.indexer);\n const utxo: UtxoContext = {\n esplora,\n chain: ctx.chain,\n network: ctx.network,\n config,\n log: ctx.log,\n };\n const network = networkOf(config.address);\n const builder = utxoBuilder(utxo, network);\n return {\n ordering: 'inputs',\n capabilities: config.capabilities,\n address: addressCodec(utxo),\n reader: chainReader(utxo),\n builder,\n broadcaster: utxoBroadcaster(utxo),\n proofs: proofSource(utxo),\n replacement: utxoReplacement(utxo, network),\n blocks: blockSource(utxo),\n history: addressHistory(utxo),\n ext: {\n utxo: {\n listUnspent: (address: string) => listUnspent(utxo, address),\n coinSelection: (request: Parameters<UtxoExt['utxo']['coinSelection']>[0]) =>\n coinSelectionPreview(utxo, request),\n },\n } satisfies UtxoExt,\n limits: () => ({ maxOutputs: MAX_OUTPUTS }),\n createNativeClient: () => {\n // The doc's promise: taproot works on this module (and a swapped backend is undone).\n useNobleEcc();\n const client: UtxoNativeClient = {\n bitcoin,\n network: { ...network, bip32: { ...network.bip32 } },\n esplora: <T>(path: string, responseType: 'json' | 'text' = 'json') =>\n ctx.transport.http<T>(\n { method: 'GET', path, route: '/native', responseType },\n READ,\n ),\n };\n return { client };\n },\n };\n },\n};\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { isXOnlyPoint } from './address';
|
|
2
|
+
export interface XOnlyTweakResult {
|
|
3
|
+
readonly parity: 0 | 1;
|
|
4
|
+
readonly xOnlyPubkey: Uint8Array;
|
|
5
|
+
}
|
|
6
|
+
export declare const nobleEcc: Readonly<{
|
|
7
|
+
isXOnlyPoint: typeof isXOnlyPoint;
|
|
8
|
+
xOnlyPointAddTweak(point: Uint8Array, tweak: Uint8Array): XOnlyTweakResult | null;
|
|
9
|
+
}>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.nobleEcc = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* bitcoinjs-lib's ECC interface (`isXOnlyPoint`, `xOnlyPointAddTweak`) over
|
|
6
|
+
* `@noble/curves`. SDK-free: bitcoinjs checks it against its own vectors when
|
|
7
|
+
* `initEccLib` installs it.
|
|
8
|
+
*/
|
|
9
|
+
const secp256k1_1 = require("@noble/curves/secp256k1");
|
|
10
|
+
const address_1 = require("./address");
|
|
11
|
+
exports.nobleEcc = Object.freeze({
|
|
12
|
+
isXOnlyPoint: address_1.isXOnlyPoint,
|
|
13
|
+
xOnlyPointAddTweak(point, tweak) {
|
|
14
|
+
if (!(0, address_1.isXOnlyPoint)(point) || tweak.length !== 32)
|
|
15
|
+
return null;
|
|
16
|
+
const t = secp256k1_1.schnorr.utils.bytesToNumberBE(tweak);
|
|
17
|
+
if (t >= secp256k1_1.secp256k1.CURVE.n)
|
|
18
|
+
return null;
|
|
19
|
+
const P = secp256k1_1.schnorr.utils.lift_x(secp256k1_1.schnorr.utils.bytesToNumberBE(point));
|
|
20
|
+
const Q = t === 0n ? P : P.add(secp256k1_1.secp256k1.ProjectivePoint.BASE.multiply(t));
|
|
21
|
+
if (Q.equals(secp256k1_1.secp256k1.ProjectivePoint.ZERO))
|
|
22
|
+
return null;
|
|
23
|
+
return { parity: Q.hasEvenY() ? 0 : 1, xOnlyPubkey: Q.toRawBytes(true).slice(1) };
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
//# sourceMappingURL=ecc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ecc.js","sourceRoot":"","sources":["../../../src/adapters/utxo/ecc.ts"],"names":[],"mappings":";;;AAAA;;;;GAIG;AACH,uDAA6D;AAC7D,uCAAyC;AAO5B,QAAA,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC;IACpC,YAAY,EAAZ,sBAAY;IACZ,kBAAkB,CAAC,KAAiB,EAAE,KAAiB;QACrD,IAAI,CAAC,IAAA,sBAAY,EAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,EAAE;YAAE,OAAO,IAAI,CAAC;QAC7D,MAAM,CAAC,GAAG,mBAAO,CAAC,KAAK,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;QAC/C,IAAI,CAAC,IAAI,qBAAS,CAAC,KAAK,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;QACxC,MAAM,CAAC,GAAG,mBAAO,CAAC,KAAK,CAAC,MAAM,CAAC,mBAAO,CAAC,KAAK,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC;QACrE,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,qBAAS,CAAC,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3E,IAAI,CAAC,CAAC,MAAM,CAAC,qBAAS,CAAC,eAAe,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QAC1D,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;IACpF,CAAC;CACF,CAAC,CAAC","sourcesContent":["/**\n * bitcoinjs-lib's ECC interface (`isXOnlyPoint`, `xOnlyPointAddTweak`) over\n * `@noble/curves`. SDK-free: bitcoinjs checks it against its own vectors when\n * `initEccLib` installs it.\n */\nimport { schnorr, secp256k1 } from '@noble/curves/secp256k1';\nimport { isXOnlyPoint } from './address';\n\nexport interface XOnlyTweakResult {\n readonly parity: 0 | 1;\n readonly xOnlyPubkey: Uint8Array;\n}\n\nexport const nobleEcc = Object.freeze({\n isXOnlyPoint,\n xOnlyPointAddTweak(point: Uint8Array, tweak: Uint8Array): XOnlyTweakResult | null {\n if (!isXOnlyPoint(point) || tweak.length !== 32) return null;\n const t = schnorr.utils.bytesToNumberBE(tweak);\n if (t >= secp256k1.CURVE.n) return null;\n const P = schnorr.utils.lift_x(schnorr.utils.bytesToNumberBE(point));\n const Q = t === 0n ? P : P.add(secp256k1.ProjectivePoint.BASE.multiply(t));\n if (Q.equals(secp256k1.ProjectivePoint.ZERO)) return null;\n return { parity: Q.hasEvenY() ? 0 : 1, xOnlyPubkey: Q.toRawBytes(true).slice(1) };\n },\n});\n"]}
|