@getomnichain/omnichain 0.2.0 → 0.3.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/dist/cjs/abstract_gas_pricing.js +27 -0
- package/dist/cjs/abstract_gas_pricing.js.map +1 -0
- package/dist/cjs/address.factory.js +81 -0
- package/dist/cjs/address.factory.js.map +1 -0
- package/dist/cjs/address.js +17 -0
- package/dist/cjs/address.js.map +1 -0
- package/dist/cjs/address_field.decorator.js +37 -0
- package/dist/cjs/address_field.decorator.js.map +1 -0
- package/dist/cjs/chain.base.js +118 -0
- package/dist/cjs/chain.base.js.map +1 -0
- package/dist/cjs/chain_ids.js +205 -0
- package/dist/cjs/chain_ids.js.map +1 -0
- package/dist/cjs/errors.js +118 -0
- package/dist/cjs/errors.js.map +1 -0
- package/dist/cjs/evm/evm_address.js +63 -0
- package/dist/cjs/evm/evm_address.js.map +1 -0
- package/dist/cjs/evm/evm_chain.js +1109 -0
- package/dist/cjs/evm/evm_chain.js.map +1 -0
- package/dist/cjs/evm/evm_chains.js +530 -0
- package/dist/cjs/evm/evm_chains.js.map +1 -0
- package/dist/cjs/evm/evm_gas_estimate.js +76 -0
- package/dist/cjs/evm/evm_gas_estimate.js.map +1 -0
- package/dist/cjs/evm/evm_gas_pricing.js +62 -0
- package/dist/cjs/evm/evm_gas_pricing.js.map +1 -0
- package/dist/cjs/evm/evm_token.js +26 -0
- package/dist/cjs/evm/evm_token.js.map +1 -0
- package/dist/cjs/evm/evm_tokens.js +109 -0
- package/dist/cjs/evm/evm_tokens.js.map +1 -0
- package/dist/cjs/evm/evm_transaction_status.js +187 -0
- package/dist/cjs/evm/evm_transaction_status.js.map +1 -0
- package/dist/cjs/evm/index.js +26 -0
- package/dist/cjs/evm/index.js.map +1 -0
- package/dist/cjs/evm/unsigned_evm_transaction.js +34 -0
- package/dist/cjs/evm/unsigned_evm_transaction.js.map +1 -0
- package/dist/cjs/index.js +34 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/is_address.decorator.js +54 -0
- package/dist/cjs/is_address.decorator.js.map +1 -0
- package/dist/cjs/network_type.js +152 -0
- package/dist/cjs/network_type.js.map +1 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/priority.js +26 -0
- package/dist/cjs/priority.js.map +1 -0
- package/dist/cjs/solana/index.js +25 -0
- package/dist/cjs/solana/index.js.map +1 -0
- package/dist/cjs/solana/solana_address.js +49 -0
- package/dist/cjs/solana/solana_address.js.map +1 -0
- package/dist/cjs/solana/solana_chain.js +1305 -0
- package/dist/cjs/solana/solana_chain.js.map +1 -0
- package/dist/cjs/solana/solana_chains.js +88 -0
- package/dist/cjs/solana/solana_chains.js.map +1 -0
- package/dist/cjs/solana/solana_gas_pricing.js +30 -0
- package/dist/cjs/solana/solana_gas_pricing.js.map +1 -0
- package/dist/cjs/solana/solana_token.js +38 -0
- package/dist/cjs/solana/solana_token.js.map +1 -0
- package/dist/cjs/solana/solana_tokens.js +29 -0
- package/dist/cjs/solana/solana_tokens.js.map +1 -0
- package/dist/cjs/solana/solana_transaction_status.js +149 -0
- package/dist/cjs/solana/solana_transaction_status.js.map +1 -0
- package/dist/cjs/solana/unsigned_solana_transaction.js +63 -0
- package/dist/cjs/solana/unsigned_solana_transaction.js.map +1 -0
- package/dist/cjs/token.js +66 -0
- package/dist/cjs/token.js.map +1 -0
- package/dist/cjs/ton/index.js +18 -0
- package/dist/cjs/ton/index.js.map +1 -0
- package/dist/cjs/ton/ton_address.js +57 -0
- package/dist/cjs/ton/ton_address.js.map +1 -0
- package/dist/cjs/transaction_status.js +283 -0
- package/dist/cjs/transaction_status.js.map +1 -0
- package/dist/cjs/unsigned_transaction.js +13 -0
- package/dist/cjs/unsigned_transaction.js.map +1 -0
- package/dist/cjs/utxo/btc/btc_address.js +43 -0
- package/dist/cjs/utxo/btc/btc_address.js.map +1 -0
- package/dist/cjs/utxo/btc/btc_chain.js +66 -0
- package/dist/cjs/utxo/btc/btc_chain.js.map +1 -0
- package/dist/cjs/utxo/btc/btc_chains.js +49 -0
- package/dist/cjs/utxo/btc/btc_chains.js.map +1 -0
- package/dist/cjs/utxo/btc/btc_token.js +15 -0
- package/dist/cjs/utxo/btc/btc_token.js.map +1 -0
- package/dist/cjs/utxo/btc/index.js +30 -0
- package/dist/cjs/utxo/btc/index.js.map +1 -0
- package/dist/cjs/utxo/btc/network_params.js +196 -0
- package/dist/cjs/utxo/btc/network_params.js.map +1 -0
- package/dist/cjs/utxo/btc/tools/asset_outpoint.js +16 -0
- package/dist/cjs/utxo/btc/tools/asset_outpoint.js.map +1 -0
- package/dist/cjs/utxo/btc/tools/bitcoin_core.tool.js +179 -0
- package/dist/cjs/utxo/btc/tools/bitcoin_core.tool.js.map +1 -0
- package/dist/cjs/utxo/btc/tools/esplora.tool.js +120 -0
- package/dist/cjs/utxo/btc/tools/esplora.tool.js.map +1 -0
- package/dist/cjs/utxo/btc/tools/inscription_index.js +3 -0
- package/dist/cjs/utxo/btc/tools/inscription_index.js.map +1 -0
- package/dist/cjs/utxo/btc/tools/ordiscan.tool.js +60 -0
- package/dist/cjs/utxo/btc/tools/ordiscan.tool.js.map +1 -0
- package/dist/cjs/utxo/btc/tools/rare_sat_index.js +3 -0
- package/dist/cjs/utxo/btc/tools/rare_sat_index.js.map +1 -0
- package/dist/cjs/utxo/btc/tools/rune_index.js +3 -0
- package/dist/cjs/utxo/btc/tools/rune_index.js.map +1 -0
- package/dist/cjs/utxo/btc/tools/unisat.tool.js +56 -0
- package/dist/cjs/utxo/btc/tools/unisat.tool.js.map +1 -0
- package/dist/cjs/utxo/coin_selection.js +160 -0
- package/dist/cjs/utxo/coin_selection.js.map +1 -0
- package/dist/cjs/utxo/doge/doge_chains.js +32 -0
- package/dist/cjs/utxo/doge/doge_chains.js.map +1 -0
- package/dist/cjs/utxo/doge/index.js +19 -0
- package/dist/cjs/utxo/doge/index.js.map +1 -0
- package/dist/cjs/utxo/doge/network_params.js +30 -0
- package/dist/cjs/utxo/doge/network_params.js.map +1 -0
- package/dist/cjs/utxo/ecc.js +47 -0
- package/dist/cjs/utxo/ecc.js.map +1 -0
- package/dist/cjs/utxo/fee.js +61 -0
- package/dist/cjs/utxo/fee.js.map +1 -0
- package/dist/cjs/utxo/index.js +36 -0
- package/dist/cjs/utxo/index.js.map +1 -0
- package/dist/cjs/utxo/ltc/index.js +19 -0
- package/dist/cjs/utxo/ltc/index.js.map +1 -0
- package/dist/cjs/utxo/ltc/ltc_chains.js +32 -0
- package/dist/cjs/utxo/ltc/ltc_chains.js.map +1 -0
- package/dist/cjs/utxo/ltc/network_params.js +33 -0
- package/dist/cjs/utxo/ltc/network_params.js.map +1 -0
- package/dist/cjs/utxo/script.js +59 -0
- package/dist/cjs/utxo/script.js.map +1 -0
- package/dist/cjs/utxo/tools/broadcaster.js +3 -0
- package/dist/cjs/utxo/tools/broadcaster.js.map +1 -0
- package/dist/cjs/utxo/tools/chain_tip_provider.js +3 -0
- package/dist/cjs/utxo/tools/chain_tip_provider.js.map +1 -0
- package/dist/cjs/utxo/tools/fee_estimator.js +3 -0
- package/dist/cjs/utxo/tools/fee_estimator.js.map +1 -0
- package/dist/cjs/utxo/tools/raw_transaction_provider.js +3 -0
- package/dist/cjs/utxo/tools/raw_transaction_provider.js.map +1 -0
- package/dist/cjs/utxo/tools/utxo_provider.js +3 -0
- package/dist/cjs/utxo/tools/utxo_provider.js.map +1 -0
- package/dist/cjs/utxo/unsigned_utxo_transaction.js +36 -0
- package/dist/cjs/utxo/unsigned_utxo_transaction.js.map +1 -0
- package/dist/cjs/utxo/utxo.js +3 -0
- package/dist/{utxo → cjs/utxo}/utxo.js.map +1 -1
- package/dist/cjs/utxo/utxo_chain.js +612 -0
- package/dist/cjs/utxo/utxo_chain.js.map +1 -0
- package/dist/cjs/utxo/utxo_chains.js +68 -0
- package/dist/cjs/utxo/utxo_chains.js.map +1 -0
- package/dist/cjs/utxo/utxo_gas_pricing.js +24 -0
- package/dist/cjs/utxo/utxo_gas_pricing.js.map +1 -0
- package/dist/cjs/utxo/utxo_network_params.js +18 -0
- package/dist/cjs/utxo/utxo_network_params.js.map +1 -0
- package/dist/cjs/utxo/utxo_transaction_status.js +95 -0
- package/dist/cjs/utxo/utxo_transaction_status.js.map +1 -0
- package/dist/esm/abstract_gas_pricing.d.ts.map +1 -0
- package/dist/esm/abstract_gas_pricing.js.map +1 -0
- package/dist/esm/address.d.ts.map +1 -0
- package/dist/esm/address.factory.d.ts.map +1 -0
- package/dist/esm/address.factory.js.map +1 -0
- package/dist/esm/address.js.map +1 -0
- package/dist/esm/address_field.decorator.d.ts.map +1 -0
- package/dist/esm/address_field.decorator.js.map +1 -0
- package/dist/{chain.base.d.ts → esm/chain.base.d.ts} +38 -1
- package/dist/esm/chain.base.d.ts.map +1 -0
- package/dist/esm/chain.base.js.map +1 -0
- package/dist/esm/chain_ids.d.ts.map +1 -0
- package/dist/esm/chain_ids.js.map +1 -0
- package/dist/{errors.d.ts → esm/errors.d.ts} +13 -0
- package/dist/esm/errors.d.ts.map +1 -0
- package/dist/esm/errors.js +107 -0
- package/dist/esm/errors.js.map +1 -0
- package/dist/esm/evm/evm_address.d.ts.map +1 -0
- package/dist/esm/evm/evm_address.js.map +1 -0
- package/dist/{evm → esm/evm}/evm_chain.d.ts +48 -2
- package/dist/esm/evm/evm_chain.d.ts.map +1 -0
- package/dist/{evm → esm/evm}/evm_chain.js +423 -4
- package/dist/esm/evm/evm_chain.js.map +1 -0
- package/dist/esm/evm/evm_chains.d.ts.map +1 -0
- package/dist/esm/evm/evm_chains.js.map +1 -0
- package/dist/esm/evm/evm_gas_estimate.d.ts.map +1 -0
- package/dist/esm/evm/evm_gas_estimate.js.map +1 -0
- package/dist/esm/evm/evm_gas_pricing.d.ts.map +1 -0
- package/dist/esm/evm/evm_gas_pricing.js.map +1 -0
- package/dist/esm/evm/evm_token.d.ts.map +1 -0
- package/dist/esm/evm/evm_token.js.map +1 -0
- package/dist/esm/evm/evm_tokens.d.ts.map +1 -0
- package/dist/esm/evm/evm_tokens.js.map +1 -0
- package/dist/{evm → esm/evm}/evm_transaction_status.d.ts +4 -0
- package/dist/esm/evm/evm_transaction_status.d.ts.map +1 -0
- package/dist/{evm → esm/evm}/evm_transaction_status.js +4 -0
- package/dist/esm/evm/evm_transaction_status.js.map +1 -0
- package/dist/esm/evm/index.d.ts.map +1 -0
- package/dist/esm/evm/index.js.map +1 -0
- package/dist/{evm → esm/evm}/unsigned_evm_transaction.d.ts +13 -0
- package/dist/esm/evm/unsigned_evm_transaction.d.ts.map +1 -0
- package/dist/{evm → esm/evm}/unsigned_evm_transaction.js +12 -0
- package/dist/esm/evm/unsigned_evm_transaction.js.map +1 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/is_address.decorator.d.ts.map +1 -0
- package/dist/esm/is_address.decorator.js.map +1 -0
- package/dist/esm/network_type.d.ts.map +1 -0
- package/dist/esm/network_type.js.map +1 -0
- package/dist/esm/package.json +3 -0
- package/dist/esm/priority.d.ts.map +1 -0
- package/dist/esm/priority.js.map +1 -0
- package/dist/esm/solana/index.d.ts.map +1 -0
- package/dist/esm/solana/index.js.map +1 -0
- package/dist/esm/solana/solana_address.d.ts.map +1 -0
- package/dist/esm/solana/solana_address.js.map +1 -0
- package/dist/{solana → esm/solana}/solana_chain.d.ts +87 -3
- package/dist/esm/solana/solana_chain.d.ts.map +1 -0
- package/dist/{solana → esm/solana}/solana_chain.js +618 -23
- package/dist/esm/solana/solana_chain.js.map +1 -0
- package/dist/esm/solana/solana_chains.d.ts.map +1 -0
- package/dist/esm/solana/solana_chains.js.map +1 -0
- package/dist/esm/solana/solana_gas_pricing.d.ts.map +1 -0
- package/dist/esm/solana/solana_gas_pricing.js.map +1 -0
- package/dist/esm/solana/solana_token.d.ts.map +1 -0
- package/dist/esm/solana/solana_token.js.map +1 -0
- package/dist/esm/solana/solana_tokens.d.ts.map +1 -0
- package/dist/esm/solana/solana_tokens.js.map +1 -0
- package/dist/esm/solana/solana_transaction_status.d.ts.map +1 -0
- package/dist/esm/solana/solana_transaction_status.js.map +1 -0
- package/dist/{solana → esm/solana}/unsigned_solana_transaction.d.ts +20 -1
- package/dist/esm/solana/unsigned_solana_transaction.d.ts.map +1 -0
- package/dist/esm/solana/unsigned_solana_transaction.js +59 -0
- package/dist/esm/solana/unsigned_solana_transaction.js.map +1 -0
- package/dist/esm/token.d.ts.map +1 -0
- package/dist/esm/token.js.map +1 -0
- package/dist/esm/ton/index.d.ts.map +1 -0
- package/dist/esm/ton/index.js.map +1 -0
- package/dist/esm/ton/ton_address.d.ts.map +1 -0
- package/dist/esm/ton/ton_address.js.map +1 -0
- package/dist/esm/transaction_status.d.ts.map +1 -0
- package/dist/esm/transaction_status.js.map +1 -0
- package/dist/esm/unsigned_transaction.d.ts.map +1 -0
- package/dist/esm/unsigned_transaction.js.map +1 -0
- package/dist/esm/utxo/btc/btc_address.d.ts.map +1 -0
- package/dist/esm/utxo/btc/btc_address.js.map +1 -0
- package/dist/esm/utxo/btc/btc_chain.d.ts.map +1 -0
- package/dist/esm/utxo/btc/btc_chain.js.map +1 -0
- package/dist/esm/utxo/btc/btc_chains.d.ts.map +1 -0
- package/dist/esm/utxo/btc/btc_chains.js.map +1 -0
- package/dist/esm/utxo/btc/btc_token.d.ts.map +1 -0
- package/dist/esm/utxo/btc/btc_token.js.map +1 -0
- package/dist/esm/utxo/btc/index.d.ts.map +1 -0
- package/dist/esm/utxo/btc/index.js.map +1 -0
- package/dist/esm/utxo/btc/network_params.d.ts.map +1 -0
- package/dist/esm/utxo/btc/network_params.js.map +1 -0
- package/dist/esm/utxo/btc/tools/asset_outpoint.d.ts.map +1 -0
- package/dist/esm/utxo/btc/tools/asset_outpoint.js.map +1 -0
- package/dist/esm/utxo/btc/tools/bitcoin_core.tool.d.ts.map +1 -0
- package/dist/esm/utxo/btc/tools/bitcoin_core.tool.js.map +1 -0
- package/dist/esm/utxo/btc/tools/esplora.tool.d.ts.map +1 -0
- package/dist/esm/utxo/btc/tools/esplora.tool.js.map +1 -0
- package/dist/esm/utxo/btc/tools/inscription_index.d.ts.map +1 -0
- package/dist/esm/utxo/btc/tools/inscription_index.js.map +1 -0
- package/dist/esm/utxo/btc/tools/ordiscan.tool.d.ts.map +1 -0
- package/dist/esm/utxo/btc/tools/ordiscan.tool.js.map +1 -0
- package/dist/esm/utxo/btc/tools/rare_sat_index.d.ts.map +1 -0
- package/dist/esm/utxo/btc/tools/rare_sat_index.js.map +1 -0
- package/dist/esm/utxo/btc/tools/rune_index.d.ts.map +1 -0
- package/dist/esm/utxo/btc/tools/rune_index.js.map +1 -0
- package/dist/esm/utxo/btc/tools/unisat.tool.d.ts.map +1 -0
- package/dist/esm/utxo/btc/tools/unisat.tool.js.map +1 -0
- package/dist/esm/utxo/coin_selection.d.ts.map +1 -0
- package/dist/esm/utxo/coin_selection.js.map +1 -0
- package/dist/esm/utxo/doge/doge_chains.d.ts.map +1 -0
- package/dist/esm/utxo/doge/doge_chains.js.map +1 -0
- package/dist/esm/utxo/doge/index.d.ts.map +1 -0
- package/dist/esm/utxo/doge/index.js.map +1 -0
- package/dist/esm/utxo/doge/network_params.d.ts.map +1 -0
- package/dist/esm/utxo/doge/network_params.js.map +1 -0
- package/dist/esm/utxo/ecc.d.ts.map +1 -0
- package/dist/esm/utxo/ecc.js.map +1 -0
- package/dist/esm/utxo/fee.d.ts.map +1 -0
- package/dist/esm/utxo/fee.js.map +1 -0
- package/dist/esm/utxo/index.d.ts.map +1 -0
- package/dist/esm/utxo/index.js.map +1 -0
- package/dist/esm/utxo/ltc/index.d.ts.map +1 -0
- package/dist/esm/utxo/ltc/index.js.map +1 -0
- package/dist/{utxo/doge/doge_chains.d.ts.map → esm/utxo/ltc/ltc_chains.d.ts.map} +1 -1
- package/dist/{utxo/doge/doge_chains.js.map → esm/utxo/ltc/ltc_chains.js.map} +1 -1
- package/dist/esm/utxo/ltc/network_params.d.ts.map +1 -0
- package/dist/esm/utxo/ltc/network_params.js.map +1 -0
- package/dist/esm/utxo/script.d.ts.map +1 -0
- package/dist/esm/utxo/script.js.map +1 -0
- package/dist/esm/utxo/tools/broadcaster.d.ts.map +1 -0
- package/dist/esm/utxo/tools/broadcaster.js.map +1 -0
- package/dist/esm/utxo/tools/chain_tip_provider.d.ts.map +1 -0
- package/dist/esm/utxo/tools/chain_tip_provider.js.map +1 -0
- package/dist/esm/utxo/tools/fee_estimator.d.ts.map +1 -0
- package/dist/esm/utxo/tools/fee_estimator.js.map +1 -0
- package/dist/esm/utxo/tools/raw_transaction_provider.d.ts.map +1 -0
- package/dist/esm/utxo/tools/raw_transaction_provider.js.map +1 -0
- package/dist/esm/utxo/tools/utxo_provider.d.ts.map +1 -0
- package/dist/esm/utxo/tools/utxo_provider.js.map +1 -0
- package/dist/esm/utxo/unsigned_utxo_transaction.d.ts.map +1 -0
- package/dist/esm/utxo/unsigned_utxo_transaction.js.map +1 -0
- package/dist/esm/utxo/utxo.d.ts.map +1 -0
- package/dist/esm/utxo/utxo.js.map +1 -0
- package/dist/{utxo → esm/utxo}/utxo_chain.d.ts +15 -2
- package/dist/esm/utxo/utxo_chain.d.ts.map +1 -0
- package/dist/{utxo → esm/utxo}/utxo_chain.js +96 -13
- package/dist/esm/utxo/utxo_chain.js.map +1 -0
- package/dist/esm/utxo/utxo_chains.d.ts.map +1 -0
- package/dist/esm/utxo/utxo_chains.js.map +1 -0
- package/dist/esm/utxo/utxo_gas_pricing.d.ts.map +1 -0
- package/dist/esm/utxo/utxo_gas_pricing.js.map +1 -0
- package/dist/esm/utxo/utxo_network_params.d.ts.map +1 -0
- package/dist/esm/utxo/utxo_network_params.js.map +1 -0
- package/dist/esm/utxo/utxo_transaction_status.d.ts.map +1 -0
- package/dist/esm/utxo/utxo_transaction_status.js.map +1 -0
- package/docs/CONNECTIONS.md +33 -0
- package/docs/EIP7702.md +77 -0
- package/docs/JITO.md +41 -0
- package/docs/MULTI_RPC.md +28 -0
- package/package.json +32 -16
- package/dist/abstract_gas_pricing.d.ts.map +0 -1
- package/dist/abstract_gas_pricing.js.map +0 -1
- package/dist/address.d.ts.map +0 -1
- package/dist/address.factory.d.ts.map +0 -1
- package/dist/address.factory.js.map +0 -1
- package/dist/address.js.map +0 -1
- package/dist/address_field.decorator.d.ts.map +0 -1
- package/dist/address_field.decorator.js.map +0 -1
- package/dist/chain.base.d.ts.map +0 -1
- package/dist/chain.base.js.map +0 -1
- package/dist/chain_ids.d.ts.map +0 -1
- package/dist/chain_ids.js.map +0 -1
- package/dist/errors.d.ts.map +0 -1
- package/dist/errors.js +0 -62
- package/dist/errors.js.map +0 -1
- package/dist/evm/evm_address.d.ts.map +0 -1
- package/dist/evm/evm_address.js.map +0 -1
- package/dist/evm/evm_chain.d.ts.map +0 -1
- package/dist/evm/evm_chain.js.map +0 -1
- package/dist/evm/evm_chains.d.ts.map +0 -1
- package/dist/evm/evm_chains.js.map +0 -1
- package/dist/evm/evm_gas_estimate.d.ts.map +0 -1
- package/dist/evm/evm_gas_estimate.js.map +0 -1
- package/dist/evm/evm_gas_pricing.d.ts.map +0 -1
- package/dist/evm/evm_gas_pricing.js.map +0 -1
- package/dist/evm/evm_token.d.ts.map +0 -1
- package/dist/evm/evm_token.js.map +0 -1
- package/dist/evm/evm_tokens.d.ts.map +0 -1
- package/dist/evm/evm_tokens.js.map +0 -1
- package/dist/evm/evm_transaction_status.d.ts.map +0 -1
- package/dist/evm/evm_transaction_status.js.map +0 -1
- package/dist/evm/index.d.ts.map +0 -1
- package/dist/evm/index.js.map +0 -1
- package/dist/evm/unsigned_evm_transaction.d.ts.map +0 -1
- package/dist/evm/unsigned_evm_transaction.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/is_address.decorator.d.ts.map +0 -1
- package/dist/is_address.decorator.js.map +0 -1
- package/dist/network_type.d.ts.map +0 -1
- package/dist/network_type.js.map +0 -1
- package/dist/priority.d.ts.map +0 -1
- package/dist/priority.js.map +0 -1
- package/dist/solana/index.d.ts.map +0 -1
- package/dist/solana/index.js.map +0 -1
- package/dist/solana/solana_address.d.ts.map +0 -1
- package/dist/solana/solana_address.js.map +0 -1
- package/dist/solana/solana_chain.d.ts.map +0 -1
- package/dist/solana/solana_chain.js.map +0 -1
- package/dist/solana/solana_chains.d.ts.map +0 -1
- package/dist/solana/solana_chains.js.map +0 -1
- package/dist/solana/solana_gas_pricing.d.ts.map +0 -1
- package/dist/solana/solana_gas_pricing.js.map +0 -1
- package/dist/solana/solana_token.d.ts.map +0 -1
- package/dist/solana/solana_token.js.map +0 -1
- package/dist/solana/solana_tokens.d.ts.map +0 -1
- package/dist/solana/solana_tokens.js.map +0 -1
- package/dist/solana/solana_transaction_status.d.ts.map +0 -1
- package/dist/solana/solana_transaction_status.js.map +0 -1
- package/dist/solana/unsigned_solana_transaction.d.ts.map +0 -1
- package/dist/solana/unsigned_solana_transaction.js +0 -26
- package/dist/solana/unsigned_solana_transaction.js.map +0 -1
- package/dist/token.d.ts.map +0 -1
- package/dist/token.js.map +0 -1
- package/dist/ton/index.d.ts.map +0 -1
- package/dist/ton/index.js.map +0 -1
- package/dist/ton/ton_address.d.ts.map +0 -1
- package/dist/ton/ton_address.js.map +0 -1
- package/dist/transaction_status.d.ts.map +0 -1
- package/dist/transaction_status.js.map +0 -1
- package/dist/unsigned_transaction.d.ts.map +0 -1
- package/dist/unsigned_transaction.js.map +0 -1
- package/dist/utxo/btc/btc_address.d.ts.map +0 -1
- package/dist/utxo/btc/btc_address.js.map +0 -1
- package/dist/utxo/btc/btc_chain.d.ts.map +0 -1
- package/dist/utxo/btc/btc_chain.js.map +0 -1
- package/dist/utxo/btc/btc_chains.d.ts.map +0 -1
- package/dist/utxo/btc/btc_chains.js.map +0 -1
- package/dist/utxo/btc/btc_token.d.ts.map +0 -1
- package/dist/utxo/btc/btc_token.js.map +0 -1
- package/dist/utxo/btc/index.d.ts.map +0 -1
- package/dist/utxo/btc/index.js.map +0 -1
- package/dist/utxo/btc/network_params.d.ts.map +0 -1
- package/dist/utxo/btc/network_params.js.map +0 -1
- package/dist/utxo/btc/tools/asset_outpoint.d.ts.map +0 -1
- package/dist/utxo/btc/tools/asset_outpoint.js.map +0 -1
- package/dist/utxo/btc/tools/bitcoin_core.tool.d.ts.map +0 -1
- package/dist/utxo/btc/tools/bitcoin_core.tool.js.map +0 -1
- package/dist/utxo/btc/tools/esplora.tool.d.ts.map +0 -1
- package/dist/utxo/btc/tools/esplora.tool.js.map +0 -1
- package/dist/utxo/btc/tools/inscription_index.d.ts.map +0 -1
- package/dist/utxo/btc/tools/inscription_index.js.map +0 -1
- package/dist/utxo/btc/tools/ordiscan.tool.d.ts.map +0 -1
- package/dist/utxo/btc/tools/ordiscan.tool.js.map +0 -1
- package/dist/utxo/btc/tools/rare_sat_index.d.ts.map +0 -1
- package/dist/utxo/btc/tools/rare_sat_index.js.map +0 -1
- package/dist/utxo/btc/tools/rune_index.d.ts.map +0 -1
- package/dist/utxo/btc/tools/rune_index.js.map +0 -1
- package/dist/utxo/btc/tools/unisat.tool.d.ts.map +0 -1
- package/dist/utxo/btc/tools/unisat.tool.js.map +0 -1
- package/dist/utxo/coin_selection.d.ts.map +0 -1
- package/dist/utxo/coin_selection.js.map +0 -1
- package/dist/utxo/doge/index.d.ts.map +0 -1
- package/dist/utxo/doge/index.js.map +0 -1
- package/dist/utxo/doge/network_params.d.ts.map +0 -1
- package/dist/utxo/doge/network_params.js.map +0 -1
- package/dist/utxo/ecc.d.ts.map +0 -1
- package/dist/utxo/ecc.js.map +0 -1
- package/dist/utxo/fee.d.ts.map +0 -1
- package/dist/utxo/fee.js.map +0 -1
- package/dist/utxo/index.d.ts.map +0 -1
- package/dist/utxo/index.js.map +0 -1
- package/dist/utxo/ltc/index.d.ts.map +0 -1
- package/dist/utxo/ltc/index.js.map +0 -1
- package/dist/utxo/ltc/ltc_chains.d.ts.map +0 -1
- package/dist/utxo/ltc/ltc_chains.js.map +0 -1
- package/dist/utxo/ltc/network_params.d.ts.map +0 -1
- package/dist/utxo/ltc/network_params.js.map +0 -1
- package/dist/utxo/script.d.ts.map +0 -1
- package/dist/utxo/script.js.map +0 -1
- package/dist/utxo/tools/broadcaster.d.ts.map +0 -1
- package/dist/utxo/tools/broadcaster.js.map +0 -1
- package/dist/utxo/tools/chain_tip_provider.d.ts.map +0 -1
- package/dist/utxo/tools/chain_tip_provider.js.map +0 -1
- package/dist/utxo/tools/fee_estimator.d.ts.map +0 -1
- package/dist/utxo/tools/fee_estimator.js.map +0 -1
- package/dist/utxo/tools/raw_transaction_provider.d.ts.map +0 -1
- package/dist/utxo/tools/raw_transaction_provider.js.map +0 -1
- package/dist/utxo/tools/utxo_provider.d.ts.map +0 -1
- package/dist/utxo/tools/utxo_provider.js.map +0 -1
- package/dist/utxo/unsigned_utxo_transaction.d.ts.map +0 -1
- package/dist/utxo/unsigned_utxo_transaction.js.map +0 -1
- package/dist/utxo/utxo.d.ts.map +0 -1
- package/dist/utxo/utxo_chain.d.ts.map +0 -1
- package/dist/utxo/utxo_chain.js.map +0 -1
- package/dist/utxo/utxo_chains.d.ts.map +0 -1
- package/dist/utxo/utxo_chains.js.map +0 -1
- package/dist/utxo/utxo_gas_pricing.d.ts.map +0 -1
- package/dist/utxo/utxo_gas_pricing.js.map +0 -1
- package/dist/utxo/utxo_network_params.d.ts.map +0 -1
- package/dist/utxo/utxo_network_params.js.map +0 -1
- package/dist/utxo/utxo_transaction_status.d.ts.map +0 -1
- package/dist/utxo/utxo_transaction_status.js.map +0 -1
- /package/dist/{abstract_gas_pricing.d.ts → esm/abstract_gas_pricing.d.ts} +0 -0
- /package/dist/{abstract_gas_pricing.js → esm/abstract_gas_pricing.js} +0 -0
- /package/dist/{address.d.ts → esm/address.d.ts} +0 -0
- /package/dist/{address.factory.d.ts → esm/address.factory.d.ts} +0 -0
- /package/dist/{address.factory.js → esm/address.factory.js} +0 -0
- /package/dist/{address.js → esm/address.js} +0 -0
- /package/dist/{address_field.decorator.d.ts → esm/address_field.decorator.d.ts} +0 -0
- /package/dist/{address_field.decorator.js → esm/address_field.decorator.js} +0 -0
- /package/dist/{chain.base.js → esm/chain.base.js} +0 -0
- /package/dist/{chain_ids.d.ts → esm/chain_ids.d.ts} +0 -0
- /package/dist/{chain_ids.js → esm/chain_ids.js} +0 -0
- /package/dist/{evm → esm/evm}/evm_address.d.ts +0 -0
- /package/dist/{evm → esm/evm}/evm_address.js +0 -0
- /package/dist/{evm → esm/evm}/evm_chains.d.ts +0 -0
- /package/dist/{evm → esm/evm}/evm_chains.js +0 -0
- /package/dist/{evm → esm/evm}/evm_gas_estimate.d.ts +0 -0
- /package/dist/{evm → esm/evm}/evm_gas_estimate.js +0 -0
- /package/dist/{evm → esm/evm}/evm_gas_pricing.d.ts +0 -0
- /package/dist/{evm → esm/evm}/evm_gas_pricing.js +0 -0
- /package/dist/{evm → esm/evm}/evm_token.d.ts +0 -0
- /package/dist/{evm → esm/evm}/evm_token.js +0 -0
- /package/dist/{evm → esm/evm}/evm_tokens.d.ts +0 -0
- /package/dist/{evm → esm/evm}/evm_tokens.js +0 -0
- /package/dist/{evm → esm/evm}/index.d.ts +0 -0
- /package/dist/{evm → esm/evm}/index.js +0 -0
- /package/dist/{index.d.ts → esm/index.d.ts} +0 -0
- /package/dist/{index.js → esm/index.js} +0 -0
- /package/dist/{is_address.decorator.d.ts → esm/is_address.decorator.d.ts} +0 -0
- /package/dist/{is_address.decorator.js → esm/is_address.decorator.js} +0 -0
- /package/dist/{network_type.d.ts → esm/network_type.d.ts} +0 -0
- /package/dist/{network_type.js → esm/network_type.js} +0 -0
- /package/dist/{priority.d.ts → esm/priority.d.ts} +0 -0
- /package/dist/{priority.js → esm/priority.js} +0 -0
- /package/dist/{solana → esm/solana}/index.d.ts +0 -0
- /package/dist/{solana → esm/solana}/index.js +0 -0
- /package/dist/{solana → esm/solana}/solana_address.d.ts +0 -0
- /package/dist/{solana → esm/solana}/solana_address.js +0 -0
- /package/dist/{solana → esm/solana}/solana_chains.d.ts +0 -0
- /package/dist/{solana → esm/solana}/solana_chains.js +0 -0
- /package/dist/{solana → esm/solana}/solana_gas_pricing.d.ts +0 -0
- /package/dist/{solana → esm/solana}/solana_gas_pricing.js +0 -0
- /package/dist/{solana → esm/solana}/solana_token.d.ts +0 -0
- /package/dist/{solana → esm/solana}/solana_token.js +0 -0
- /package/dist/{solana → esm/solana}/solana_tokens.d.ts +0 -0
- /package/dist/{solana → esm/solana}/solana_tokens.js +0 -0
- /package/dist/{solana → esm/solana}/solana_transaction_status.d.ts +0 -0
- /package/dist/{solana → esm/solana}/solana_transaction_status.js +0 -0
- /package/dist/{token.d.ts → esm/token.d.ts} +0 -0
- /package/dist/{token.js → esm/token.js} +0 -0
- /package/dist/{ton → esm/ton}/index.d.ts +0 -0
- /package/dist/{ton → esm/ton}/index.js +0 -0
- /package/dist/{ton → esm/ton}/ton_address.d.ts +0 -0
- /package/dist/{ton → esm/ton}/ton_address.js +0 -0
- /package/dist/{transaction_status.d.ts → esm/transaction_status.d.ts} +0 -0
- /package/dist/{transaction_status.js → esm/transaction_status.js} +0 -0
- /package/dist/{unsigned_transaction.d.ts → esm/unsigned_transaction.d.ts} +0 -0
- /package/dist/{unsigned_transaction.js → esm/unsigned_transaction.js} +0 -0
- /package/dist/{utxo → esm/utxo}/btc/btc_address.d.ts +0 -0
- /package/dist/{utxo → esm/utxo}/btc/btc_address.js +0 -0
- /package/dist/{utxo → esm/utxo}/btc/btc_chain.d.ts +0 -0
- /package/dist/{utxo → esm/utxo}/btc/btc_chain.js +0 -0
- /package/dist/{utxo → esm/utxo}/btc/btc_chains.d.ts +0 -0
- /package/dist/{utxo → esm/utxo}/btc/btc_chains.js +0 -0
- /package/dist/{utxo → esm/utxo}/btc/btc_token.d.ts +0 -0
- /package/dist/{utxo → esm/utxo}/btc/btc_token.js +0 -0
- /package/dist/{utxo → esm/utxo}/btc/index.d.ts +0 -0
- /package/dist/{utxo → esm/utxo}/btc/index.js +0 -0
- /package/dist/{utxo → esm/utxo}/btc/network_params.d.ts +0 -0
- /package/dist/{utxo → esm/utxo}/btc/network_params.js +0 -0
- /package/dist/{utxo → esm/utxo}/btc/tools/asset_outpoint.d.ts +0 -0
- /package/dist/{utxo → esm/utxo}/btc/tools/asset_outpoint.js +0 -0
- /package/dist/{utxo → esm/utxo}/btc/tools/bitcoin_core.tool.d.ts +0 -0
- /package/dist/{utxo → esm/utxo}/btc/tools/bitcoin_core.tool.js +0 -0
- /package/dist/{utxo → esm/utxo}/btc/tools/esplora.tool.d.ts +0 -0
- /package/dist/{utxo → esm/utxo}/btc/tools/esplora.tool.js +0 -0
- /package/dist/{utxo → esm/utxo}/btc/tools/inscription_index.d.ts +0 -0
- /package/dist/{utxo → esm/utxo}/btc/tools/inscription_index.js +0 -0
- /package/dist/{utxo → esm/utxo}/btc/tools/ordiscan.tool.d.ts +0 -0
- /package/dist/{utxo → esm/utxo}/btc/tools/ordiscan.tool.js +0 -0
- /package/dist/{utxo → esm/utxo}/btc/tools/rare_sat_index.d.ts +0 -0
- /package/dist/{utxo → esm/utxo}/btc/tools/rare_sat_index.js +0 -0
- /package/dist/{utxo → esm/utxo}/btc/tools/rune_index.d.ts +0 -0
- /package/dist/{utxo → esm/utxo}/btc/tools/rune_index.js +0 -0
- /package/dist/{utxo → esm/utxo}/btc/tools/unisat.tool.d.ts +0 -0
- /package/dist/{utxo → esm/utxo}/btc/tools/unisat.tool.js +0 -0
- /package/dist/{utxo → esm/utxo}/coin_selection.d.ts +0 -0
- /package/dist/{utxo → esm/utxo}/coin_selection.js +0 -0
- /package/dist/{utxo → esm/utxo}/doge/doge_chains.d.ts +0 -0
- /package/dist/{utxo → esm/utxo}/doge/doge_chains.js +0 -0
- /package/dist/{utxo → esm/utxo}/doge/index.d.ts +0 -0
- /package/dist/{utxo → esm/utxo}/doge/index.js +0 -0
- /package/dist/{utxo → esm/utxo}/doge/network_params.d.ts +0 -0
- /package/dist/{utxo → esm/utxo}/doge/network_params.js +0 -0
- /package/dist/{utxo → esm/utxo}/ecc.d.ts +0 -0
- /package/dist/{utxo → esm/utxo}/ecc.js +0 -0
- /package/dist/{utxo → esm/utxo}/fee.d.ts +0 -0
- /package/dist/{utxo → esm/utxo}/fee.js +0 -0
- /package/dist/{utxo → esm/utxo}/index.d.ts +0 -0
- /package/dist/{utxo → esm/utxo}/index.js +0 -0
- /package/dist/{utxo → esm/utxo}/ltc/index.d.ts +0 -0
- /package/dist/{utxo → esm/utxo}/ltc/index.js +0 -0
- /package/dist/{utxo → esm/utxo}/ltc/ltc_chains.d.ts +0 -0
- /package/dist/{utxo → esm/utxo}/ltc/ltc_chains.js +0 -0
- /package/dist/{utxo → esm/utxo}/ltc/network_params.d.ts +0 -0
- /package/dist/{utxo → esm/utxo}/ltc/network_params.js +0 -0
- /package/dist/{utxo → esm/utxo}/script.d.ts +0 -0
- /package/dist/{utxo → esm/utxo}/script.js +0 -0
- /package/dist/{utxo → esm/utxo}/tools/broadcaster.d.ts +0 -0
- /package/dist/{utxo → esm/utxo}/tools/broadcaster.js +0 -0
- /package/dist/{utxo → esm/utxo}/tools/chain_tip_provider.d.ts +0 -0
- /package/dist/{utxo → esm/utxo}/tools/chain_tip_provider.js +0 -0
- /package/dist/{utxo → esm/utxo}/tools/fee_estimator.d.ts +0 -0
- /package/dist/{utxo → esm/utxo}/tools/fee_estimator.js +0 -0
- /package/dist/{utxo → esm/utxo}/tools/raw_transaction_provider.d.ts +0 -0
- /package/dist/{utxo → esm/utxo}/tools/raw_transaction_provider.js +0 -0
- /package/dist/{utxo → esm/utxo}/tools/utxo_provider.d.ts +0 -0
- /package/dist/{utxo → esm/utxo}/tools/utxo_provider.js +0 -0
- /package/dist/{utxo → esm/utxo}/unsigned_utxo_transaction.d.ts +0 -0
- /package/dist/{utxo → esm/utxo}/unsigned_utxo_transaction.js +0 -0
- /package/dist/{utxo → esm/utxo}/utxo.d.ts +0 -0
- /package/dist/{utxo → esm/utxo}/utxo.js +0 -0
- /package/dist/{utxo → esm/utxo}/utxo_chains.d.ts +0 -0
- /package/dist/{utxo → esm/utxo}/utxo_chains.js +0 -0
- /package/dist/{utxo → esm/utxo}/utxo_gas_pricing.d.ts +0 -0
- /package/dist/{utxo → esm/utxo}/utxo_gas_pricing.js +0 -0
- /package/dist/{utxo → esm/utxo}/utxo_network_params.d.ts +0 -0
- /package/dist/{utxo → esm/utxo}/utxo_network_params.js +0 -0
- /package/dist/{utxo → esm/utxo}/utxo_transaction_status.d.ts +0 -0
- /package/dist/{utxo → esm/utxo}/utxo_transaction_status.js +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ComputeBudgetProgram, Connection, MessageV0, PublicKey, SystemProgram, VersionedTransaction, } from '@solana/web3.js';
|
|
2
|
-
import { TOKEN_2022_PROGRAM_ID, TOKEN_PROGRAM_ID, createAssociatedTokenAccountIdempotentInstruction, createAssociatedTokenAccountInstruction, createTransferCheckedInstruction, getAccount, getAssociatedTokenAddressSync, getMint, } from '@solana/spl-token';
|
|
3
|
-
import { Chain, resolveTransferAmount } from "../chain.base.js";
|
|
2
|
+
import { TOKEN_2022_PROGRAM_ID, TOKEN_PROGRAM_ID, TokenAccountNotFoundError, TokenInvalidAccountOwnerError, createAssociatedTokenAccountIdempotentInstruction, createAssociatedTokenAccountInstruction, createTransferCheckedInstruction, getAccount, getAssociatedTokenAddressSync, getMint, } from '@solana/spl-token';
|
|
3
|
+
import { Chain, resolveTransferAmount, } from "../chain.base.js";
|
|
4
4
|
import { ChainError, ChainErrorKinds, sanitizeCause, sanitizeMessage } from "../errors.js";
|
|
5
5
|
import { NetworkType, registerNonEvmChain } from "../network_type.js";
|
|
6
6
|
import { Priority } from "../priority.js";
|
|
@@ -33,18 +33,26 @@ const SOL_PRIORITY_PERCENTILE = {
|
|
|
33
33
|
export class SolanaChain extends Chain {
|
|
34
34
|
defaultRpcUrl;
|
|
35
35
|
rpcUrl;
|
|
36
|
+
rpcUrls;
|
|
36
37
|
legacyRpcEnvNames;
|
|
37
38
|
explorerClusterSuffix;
|
|
38
39
|
chainAgnosticGenesisHash;
|
|
40
|
+
jito;
|
|
39
41
|
_nativeToken;
|
|
40
42
|
_connection = null;
|
|
43
|
+
_rpcUrlIndex = 0;
|
|
41
44
|
constructor(init) {
|
|
42
45
|
super(init.chainId, init.name, NetworkType.SOLANA, init.blockTimeSeconds, init.nativeSymbol, init.explorerBaseUrl);
|
|
43
46
|
this.defaultRpcUrl = init.defaultRpcUrl;
|
|
44
47
|
this.rpcUrl = init.rpcUrl;
|
|
48
|
+
this.rpcUrls = init.rpcUrls ?? [];
|
|
49
|
+
if (this.rpcUrls.length > 1) {
|
|
50
|
+
throw new ChainError(ChainErrorKinds.InvalidArgument, `SolanaChainInit.rpcUrls accepts only ONE endpoint in 0.3.0 (got ${this.rpcUrls.length}). Automatic failover retry is deferred to a follow-up release; passing >1 endpoint would silently discard entries.`, { chainId: init.chainId });
|
|
51
|
+
}
|
|
45
52
|
this.legacyRpcEnvNames = init.legacyRpcEnvNames ?? [];
|
|
46
53
|
this.explorerClusterSuffix = init.explorerClusterSuffix ?? '';
|
|
47
54
|
this.chainAgnosticGenesisHash = init.chainAgnosticGenesisHash;
|
|
55
|
+
this.jito = init.jito ?? null;
|
|
48
56
|
this._nativeToken = SolanaToken.native(init.chainId, init.nativeSymbol, init.nativeDecimals ?? 9);
|
|
49
57
|
registerNonEvmChain(init.chainId, NetworkType.SOLANA);
|
|
50
58
|
}
|
|
@@ -103,9 +111,35 @@ export class SolanaChain extends Chain {
|
|
|
103
111
|
* the pre-rename `SOLANA_RPC_URL` here)
|
|
104
112
|
* 5. `defaultRpcUrl` (never throws — public cluster)
|
|
105
113
|
*/
|
|
114
|
+
resolvedRpcUrlForRedaction() {
|
|
115
|
+
try {
|
|
116
|
+
return this.readRpcUrl();
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
async rpcWrap(fn, label) {
|
|
123
|
+
try {
|
|
124
|
+
return await fn();
|
|
125
|
+
}
|
|
126
|
+
catch (err) {
|
|
127
|
+
if (err instanceof ChainError)
|
|
128
|
+
throw err;
|
|
129
|
+
const rpc = this.resolvedRpcUrlForRedaction();
|
|
130
|
+
throw new ChainError(ChainErrorKinds.RpcError, sanitizeMessage(`Solana ${label} failed on ${this.name}`, rpc), { chainId: this.chainId }, sanitizeCause(err, rpc));
|
|
131
|
+
}
|
|
132
|
+
}
|
|
106
133
|
readRpcUrl() {
|
|
107
134
|
if (this.rpcUrl && this.rpcUrl.trim().length > 0)
|
|
108
135
|
return this.rpcUrl.trim();
|
|
136
|
+
if (this.rpcUrls.length > 0) {
|
|
137
|
+
for (const candidate of this.rpcUrls) {
|
|
138
|
+
if (candidate && candidate.trim().length > 0)
|
|
139
|
+
return candidate.trim();
|
|
140
|
+
}
|
|
141
|
+
throw new ChainError(ChainErrorKinds.RpcNotConfigured, `${this.name}: rpcUrls was supplied but every entry is blank; refusing to fall back to env or the public default cluster`, { chainId: this.chainId });
|
|
142
|
+
}
|
|
109
143
|
const env = globalThis.process?.env;
|
|
110
144
|
const candidates = [
|
|
111
145
|
this.name.replace(/ /g, '_').toUpperCase() + '_RPC_URL',
|
|
@@ -269,19 +303,39 @@ export class SolanaChain extends Chain {
|
|
|
269
303
|
}
|
|
270
304
|
instructions.push(createTransferCheckedInstruction(sourceAta, mintPk, destAta, fromPk, amountMr, decimals, [], programId));
|
|
271
305
|
}
|
|
272
|
-
const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash('finalized');
|
|
273
|
-
const
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
306
|
+
const { blockhash, lastValidBlockHeight } = await this.rpcWrap(() => connection.getLatestBlockhash('finalized'), 'getLatestBlockhash');
|
|
307
|
+
const alts = validateAltList(req.addressLookupTables, this.chainId);
|
|
308
|
+
let message;
|
|
309
|
+
try {
|
|
310
|
+
message = MessageV0.compile({
|
|
311
|
+
payerKey: feePayerPk,
|
|
312
|
+
instructions,
|
|
313
|
+
recentBlockhash: blockhash,
|
|
314
|
+
addressLookupTableAccounts: alts,
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
catch (err) {
|
|
318
|
+
throw new ChainError(ChainErrorKinds.InvalidArgument, `Solana createTransferUnsignedTransaction: MessageV0.compile failed — instruction or ALT layout invalid`, { chainId: this.chainId }, err instanceof Error ? err : undefined);
|
|
319
|
+
}
|
|
320
|
+
const tx = new VersionedTransaction(message);
|
|
321
|
+
let serializedSize;
|
|
322
|
+
try {
|
|
323
|
+
serializedSize = tx.serialize().length;
|
|
324
|
+
}
|
|
325
|
+
catch (err) {
|
|
326
|
+
throw new ChainError(ChainErrorKinds.TransactionTooLarge, `Compiled Solana tx exceeds the serialize buffer; supply addressLookupTables to compress the account list`, { chainId: this.chainId }, err instanceof Error ? err : undefined);
|
|
327
|
+
}
|
|
328
|
+
if (serializedSize > 1232) {
|
|
329
|
+
throw new ChainError(ChainErrorKinds.TransactionTooLarge, `Compiled Solana transfer exceeds 1232-byte wire limit; supply addressLookupTables to compress the account list`, { chainId: this.chainId });
|
|
330
|
+
}
|
|
278
331
|
return new UnsignedSolanaTransaction({
|
|
279
332
|
chainId: this.chainId,
|
|
280
|
-
transaction:
|
|
333
|
+
transaction: tx,
|
|
281
334
|
feePayer: feePayerAddress,
|
|
282
335
|
recentBlockhash: blockhash,
|
|
283
336
|
lastValidBlockHeight,
|
|
284
337
|
instructions,
|
|
338
|
+
addressLookupTables: alts,
|
|
285
339
|
});
|
|
286
340
|
}
|
|
287
341
|
/**
|
|
@@ -328,19 +382,39 @@ export class SolanaChain extends Chain {
|
|
|
328
382
|
for (const ix of req.instructions)
|
|
329
383
|
allIxs.push(ix);
|
|
330
384
|
const connection = this.getConnection();
|
|
331
|
-
const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash('finalized');
|
|
332
|
-
const
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
385
|
+
const { blockhash, lastValidBlockHeight } = await this.rpcWrap(() => connection.getLatestBlockhash('finalized'), 'getLatestBlockhash');
|
|
386
|
+
const alts = validateAltList(req.addressLookupTables, this.chainId);
|
|
387
|
+
let message;
|
|
388
|
+
try {
|
|
389
|
+
message = MessageV0.compile({
|
|
390
|
+
payerKey: feePayerPk,
|
|
391
|
+
instructions: allIxs,
|
|
392
|
+
recentBlockhash: blockhash,
|
|
393
|
+
addressLookupTableAccounts: alts,
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
catch (err) {
|
|
397
|
+
throw new ChainError(ChainErrorKinds.InvalidArgument, `Solana createInstructionsUnsignedTransaction: MessageV0.compile failed — instruction or ALT layout invalid`, { chainId: this.chainId }, err instanceof Error ? err : undefined);
|
|
398
|
+
}
|
|
399
|
+
const tx = new VersionedTransaction(message);
|
|
400
|
+
let serializedSize;
|
|
401
|
+
try {
|
|
402
|
+
serializedSize = tx.serialize().length;
|
|
403
|
+
}
|
|
404
|
+
catch (err) {
|
|
405
|
+
throw new ChainError(ChainErrorKinds.TransactionTooLarge, `Compiled Solana tx exceeds the serialize buffer; supply addressLookupTables to compress the account list`, { chainId: this.chainId }, err instanceof Error ? err : undefined);
|
|
406
|
+
}
|
|
407
|
+
if (serializedSize > 1232) {
|
|
408
|
+
throw new ChainError(ChainErrorKinds.TransactionTooLarge, `Compiled Solana tx exceeds 1232-byte wire limit; supply addressLookupTables to compress the account list`, { chainId: this.chainId });
|
|
409
|
+
}
|
|
337
410
|
return new UnsignedSolanaTransaction({
|
|
338
411
|
chainId: this.chainId,
|
|
339
|
-
transaction:
|
|
412
|
+
transaction: tx,
|
|
340
413
|
feePayer: feePayerAddress,
|
|
341
414
|
recentBlockhash: blockhash,
|
|
342
415
|
lastValidBlockHeight,
|
|
343
416
|
instructions: allIxs,
|
|
417
|
+
addressLookupTables: alts,
|
|
344
418
|
});
|
|
345
419
|
}
|
|
346
420
|
/**
|
|
@@ -352,13 +426,14 @@ export class SolanaChain extends Chain {
|
|
|
352
426
|
*/
|
|
353
427
|
async refreshBlockhash(unsigned) {
|
|
354
428
|
const connection = this.getConnection();
|
|
355
|
-
const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash('finalized');
|
|
429
|
+
const { blockhash, lastValidBlockHeight } = await this.rpcWrap(() => connection.getLatestBlockhash('finalized'), 'getLatestBlockhash');
|
|
356
430
|
if (blockhash === unsigned.recentBlockhash)
|
|
357
431
|
return unsigned;
|
|
358
432
|
const message = MessageV0.compile({
|
|
359
433
|
payerKey: unsigned.feePayerPubkey,
|
|
360
434
|
instructions: unsigned.instructions,
|
|
361
435
|
recentBlockhash: blockhash,
|
|
436
|
+
addressLookupTableAccounts: unsigned.addressLookupTables,
|
|
362
437
|
});
|
|
363
438
|
return new UnsignedSolanaTransaction({
|
|
364
439
|
chainId: unsigned.chainId,
|
|
@@ -367,6 +442,7 @@ export class SolanaChain extends Chain {
|
|
|
367
442
|
recentBlockhash: blockhash,
|
|
368
443
|
lastValidBlockHeight,
|
|
369
444
|
instructions: unsigned.instructions,
|
|
445
|
+
addressLookupTables: unsigned.addressLookupTables,
|
|
370
446
|
});
|
|
371
447
|
}
|
|
372
448
|
/**
|
|
@@ -377,13 +453,13 @@ export class SolanaChain extends Chain {
|
|
|
377
453
|
*/
|
|
378
454
|
async estimateAndApplyCu(unsigned) {
|
|
379
455
|
const connection = this.getConnection();
|
|
380
|
-
const sim = await connection.simulateTransaction(unsigned.transaction, {
|
|
456
|
+
const sim = await this.rpcWrap(() => connection.simulateTransaction(unsigned.transaction, {
|
|
381
457
|
sigVerify: false,
|
|
382
458
|
replaceRecentBlockhash: true,
|
|
383
459
|
commitment: 'confirmed',
|
|
384
|
-
});
|
|
460
|
+
}), 'simulateTransaction');
|
|
385
461
|
if (sim.value.err) {
|
|
386
|
-
throw new ChainError(ChainErrorKinds.
|
|
462
|
+
throw new ChainError(ChainErrorKinds.SimulationFailed, `Solana simulation rejected the tx: ${JSON.stringify(sim.value.err)}`, { chainId: this.chainId });
|
|
387
463
|
}
|
|
388
464
|
const consumed = sim.value.unitsConsumed;
|
|
389
465
|
if (!consumed)
|
|
@@ -403,6 +479,7 @@ export class SolanaChain extends Chain {
|
|
|
403
479
|
payerKey: unsigned.feePayerPubkey,
|
|
404
480
|
instructions: newInstructions,
|
|
405
481
|
recentBlockhash: unsigned.recentBlockhash,
|
|
482
|
+
addressLookupTableAccounts: unsigned.addressLookupTables,
|
|
406
483
|
});
|
|
407
484
|
return new UnsignedSolanaTransaction({
|
|
408
485
|
chainId: unsigned.chainId,
|
|
@@ -411,11 +488,12 @@ export class SolanaChain extends Chain {
|
|
|
411
488
|
recentBlockhash: unsigned.recentBlockhash,
|
|
412
489
|
lastValidBlockHeight: unsigned.lastValidBlockHeight,
|
|
413
490
|
instructions: newInstructions,
|
|
491
|
+
addressLookupTables: unsigned.addressLookupTables,
|
|
414
492
|
});
|
|
415
493
|
}
|
|
416
494
|
/** Whether the given error came from a preflight simulation rejection (vs network/transport). */
|
|
417
495
|
static isSimulationError(err) {
|
|
418
|
-
if (err instanceof ChainError && err.kind === ChainErrorKinds.
|
|
496
|
+
if (err instanceof ChainError && err.kind === ChainErrorKinds.SimulationFailed)
|
|
419
497
|
return true;
|
|
420
498
|
const msg = err?.message ?? '';
|
|
421
499
|
return /simulation failed|transaction simulation failed/i.test(msg);
|
|
@@ -425,7 +503,68 @@ export class SolanaChain extends Chain {
|
|
|
425
503
|
const msg = err?.message ?? '';
|
|
426
504
|
return /blockhash not found|expired blockhash|blockhash.*expired/i.test(msg);
|
|
427
505
|
}
|
|
428
|
-
async getTransactionStatus(txHash) {
|
|
506
|
+
async getTransactionStatus(txHash, opts) {
|
|
507
|
+
if (Array.isArray(txHash)) {
|
|
508
|
+
return runSolanaBatchStatus(txHash, (h, batchSignal) => {
|
|
509
|
+
const composedSignal = opts?.signal
|
|
510
|
+
? anySignal(opts.signal, batchSignal)
|
|
511
|
+
: batchSignal;
|
|
512
|
+
return this.getSingleSolanaStatus(h, { ...opts, signal: composedSignal });
|
|
513
|
+
});
|
|
514
|
+
}
|
|
515
|
+
return this.getSingleSolanaStatus(txHash, opts);
|
|
516
|
+
}
|
|
517
|
+
async getSingleSolanaStatus(txHash, opts) {
|
|
518
|
+
if (opts?.confirmations !== undefined && opts.confirmations > 1 && !opts.wait) {
|
|
519
|
+
throw new ChainError(ChainErrorKinds.InvalidArgument, `getTransactionStatus: confirmations > 1 requires wait: true (a single status read cannot enforce finality)`, { chainId: this.chainId, txHash });
|
|
520
|
+
}
|
|
521
|
+
if (!opts?.wait)
|
|
522
|
+
return this.getSolanaStatusOnce(txHash);
|
|
523
|
+
if (opts.signal?.aborted) {
|
|
524
|
+
throw new ChainError(ChainErrorKinds.InvalidArgument, `getTransactionStatus aborted before first poll`, { chainId: this.chainId, txHash });
|
|
525
|
+
}
|
|
526
|
+
const c = opts.confirmations ?? 1;
|
|
527
|
+
if (c !== 1 && c < 32) {
|
|
528
|
+
throw new ChainError(ChainErrorKinds.InvalidArgument, `Solana getTransactionStatus.confirmations must be 1 (confirmed) or >=32 (finalized); ${c} would ambiguously map otherwise.`, { chainId: this.chainId, txHash });
|
|
529
|
+
}
|
|
530
|
+
if (opts.timeoutMs === undefined) {
|
|
531
|
+
throw new ChainError(ChainErrorKinds.InvalidArgument, `getTransactionStatus: wait: true requires an explicit timeoutMs. Unbounded polling would pin an RPC worker + connection forever if the tx is dropped.`, { chainId: this.chainId, txHash });
|
|
532
|
+
}
|
|
533
|
+
if (opts.timeoutMs < 0) {
|
|
534
|
+
throw new ChainError(ChainErrorKinds.InvalidArgument, `getTransactionStatus: timeoutMs must be >= 0`, { chainId: this.chainId, txHash });
|
|
535
|
+
}
|
|
536
|
+
const deadline = Date.now() + opts.timeoutMs;
|
|
537
|
+
const pollMs = Math.max(400, this.blockTimeSeconds * 1000);
|
|
538
|
+
const wantFinalized = c >= 32;
|
|
539
|
+
let last;
|
|
540
|
+
while (true) {
|
|
541
|
+
last = await this.getSolanaStatusOnce(txHash);
|
|
542
|
+
if (last.status === 'Success' || last.status === 'Failed') {
|
|
543
|
+
if (!wantFinalized)
|
|
544
|
+
return last;
|
|
545
|
+
let sigStatus;
|
|
546
|
+
try {
|
|
547
|
+
sigStatus = await this.getConnection().getSignatureStatus(txHash, { searchTransactionHistory: true });
|
|
548
|
+
}
|
|
549
|
+
catch (err) {
|
|
550
|
+
throw new ChainError(ChainErrorKinds.RpcError, sanitizeMessage(`Failed to poll signature status for finalization on ${this.name}`, this.resolvedRpcUrlForRedaction()), { chainId: this.chainId, txHash }, sanitizeCause(err, this.resolvedRpcUrlForRedaction()));
|
|
551
|
+
}
|
|
552
|
+
if (sigStatus.value?.confirmationStatus === 'finalized')
|
|
553
|
+
return last;
|
|
554
|
+
if (Date.now() >= deadline) {
|
|
555
|
+
throw new ChainError(ChainErrorKinds.RpcError, `getTransactionStatus timed out after ${opts.timeoutMs}ms before reaching finalized; last confirmation status: ${sigStatus.value?.confirmationStatus ?? 'unknown'}. Consumer must NOT credit as final.`, { chainId: this.chainId, txHash });
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
else if (Date.now() >= deadline) {
|
|
559
|
+
throw new ChainError(ChainErrorKinds.RpcError, `getTransactionStatus timed out after ${opts.timeoutMs}ms; last observed status was ${last.status}. Consumer must NOT credit as final AND must NOT re-sign — the tx may still land. Re-broadcast the same signed bytes or continue polling with the same txHash.`, { chainId: this.chainId, txHash });
|
|
560
|
+
}
|
|
561
|
+
await solanaInterruptibleSleep(pollMs, opts.signal);
|
|
562
|
+
if (opts.signal?.aborted) {
|
|
563
|
+
throw new ChainError(ChainErrorKinds.InvalidArgument, `getTransactionStatus aborted mid-poll`, { chainId: this.chainId, txHash });
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
async getSolanaStatusOnce(txHash) {
|
|
429
568
|
const connection = this.getConnection();
|
|
430
569
|
// Best-effort read of the current rpc URL for message/cause scrubbing.
|
|
431
570
|
// readRpcUrl throws when nothing is configured; there'd be no
|
|
@@ -533,7 +672,342 @@ export class SolanaChain extends Chain {
|
|
|
533
672
|
});
|
|
534
673
|
}
|
|
535
674
|
async getChainTipHeight() {
|
|
536
|
-
return this.getConnection().getSlot('confirmed');
|
|
675
|
+
return this.rpcWrap(() => this.getConnection().getSlot('confirmed'), 'getSlot');
|
|
676
|
+
}
|
|
677
|
+
async broadcast(signed, opts) {
|
|
678
|
+
if (opts && opts.signal !== undefined) {
|
|
679
|
+
throw new ChainError(ChainErrorKinds.FeatureNotSupported, `Solana broadcast: signal is not honored in 0.3.0 (silently ignoring would let a caller conclude 'not sent' while the tx still lands). Cancellation returns in 0.3.1.`, { chainId: this.chainId });
|
|
680
|
+
}
|
|
681
|
+
let bytes;
|
|
682
|
+
if (typeof signed === 'string') {
|
|
683
|
+
const stripped = signed.startsWith('0x') ? signed.slice(2) : signed;
|
|
684
|
+
if (!/^[0-9a-fA-F]+$/.test(stripped) || stripped.length % 2 !== 0 || stripped.length === 0) {
|
|
685
|
+
throw new ChainError(ChainErrorKinds.InvalidArgument, `Solana broadcast: signed must be Uint8Array or 0x-prefixed hex; got malformed string (len ${signed.length}). Base58/base64 encodings are NOT accepted — decode to bytes first.`, { chainId: this.chainId });
|
|
686
|
+
}
|
|
687
|
+
bytes = new Uint8Array(Buffer.from(stripped, 'hex'));
|
|
688
|
+
}
|
|
689
|
+
else {
|
|
690
|
+
bytes = signed;
|
|
691
|
+
}
|
|
692
|
+
if (bytes.length < 65) {
|
|
693
|
+
throw new ChainError(ChainErrorKinds.InvalidArgument, `Solana broadcast: signed bytes must be >= 65 bytes (1 sig-count + 64-byte signature), got ${bytes.length}`, { chainId: this.chainId });
|
|
694
|
+
}
|
|
695
|
+
if (bytes.length > 1232) {
|
|
696
|
+
throw new ChainError(ChainErrorKinds.TransactionTooLarge, `Solana broadcast: signed tx is ${bytes.length} bytes, exceeds 1232-byte wire limit`, { chainId: this.chainId });
|
|
697
|
+
}
|
|
698
|
+
if (opts?.via === 'jito') {
|
|
699
|
+
if (!this.jito) {
|
|
700
|
+
throw new ChainError(ChainErrorKinds.FeatureNotSupported, `Solana broadcast: via: 'jito' requires SolanaChain to be constructed with jito config`, { chainId: this.chainId });
|
|
701
|
+
}
|
|
702
|
+
if (opts.skipPreflight !== undefined || opts.maxRetries !== undefined) {
|
|
703
|
+
throw new ChainError(ChainErrorKinds.InvalidArgument, `Solana broadcast: skipPreflight/maxRetries do not apply to the Jito path (block-engine has its own retry semantics)`, { chainId: this.chainId });
|
|
704
|
+
}
|
|
705
|
+
const signature = signatureBase58FromBytes(bytes);
|
|
706
|
+
await this.submitJitoBundle([bytes]);
|
|
707
|
+
return signature;
|
|
708
|
+
}
|
|
709
|
+
try {
|
|
710
|
+
const sig = await this.getConnection().sendRawTransaction(bytes, {
|
|
711
|
+
skipPreflight: opts?.skipPreflight ?? false,
|
|
712
|
+
maxRetries: opts?.maxRetries,
|
|
713
|
+
});
|
|
714
|
+
return sig;
|
|
715
|
+
}
|
|
716
|
+
catch (err) {
|
|
717
|
+
const rawMsg = (err instanceof Error ? err.message : String(err)).toLowerCase();
|
|
718
|
+
if (rawMsg.includes('already been processed') || rawMsg.includes('already processed')) {
|
|
719
|
+
return signatureBase58FromBytes(bytes);
|
|
720
|
+
}
|
|
721
|
+
throw this.classifyBroadcastError(err);
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
async submitJitoBundle(signedTxs, opts) {
|
|
725
|
+
if (!this.jito) {
|
|
726
|
+
throw new ChainError(ChainErrorKinds.FeatureNotSupported, 'Jito bundle submission requires SolanaChain to be constructed with jito config', { chainId: this.chainId });
|
|
727
|
+
}
|
|
728
|
+
const body = {
|
|
729
|
+
jsonrpc: '2.0',
|
|
730
|
+
id: 1,
|
|
731
|
+
method: 'sendBundle',
|
|
732
|
+
params: [
|
|
733
|
+
signedTxs.map((b) => Buffer.from(b).toString('base64')),
|
|
734
|
+
{ encoding: 'base64' },
|
|
735
|
+
],
|
|
736
|
+
};
|
|
737
|
+
const jitoUrl = this.jito.url;
|
|
738
|
+
const signal = combineJitoSignal(opts?.signal, opts?.timeoutMs ?? 15_000);
|
|
739
|
+
let json;
|
|
740
|
+
try {
|
|
741
|
+
const resp = await fetch(jitoUrl, {
|
|
742
|
+
method: 'POST',
|
|
743
|
+
headers: {
|
|
744
|
+
'Content-Type': 'application/json',
|
|
745
|
+
...(this.jito.auth ? { Authorization: `Bearer ${this.jito.auth}` } : {}),
|
|
746
|
+
},
|
|
747
|
+
body: JSON.stringify(body),
|
|
748
|
+
signal,
|
|
749
|
+
});
|
|
750
|
+
if (!resp.ok) {
|
|
751
|
+
// 401/403 = jito auth config problem, not a bundle rejection.
|
|
752
|
+
// Treat as RpcError so consumer doesn't push the tx toward re-sign.
|
|
753
|
+
throw new ChainError(ChainErrorKinds.RpcError, sanitizeMessage(`Jito submitBundle HTTP ${resp.status} on ${this.name}`, jitoUrl), { chainId: this.chainId });
|
|
754
|
+
}
|
|
755
|
+
json = (await resp.json());
|
|
756
|
+
}
|
|
757
|
+
catch (err) {
|
|
758
|
+
if (err instanceof ChainError)
|
|
759
|
+
throw err;
|
|
760
|
+
throw new ChainError(ChainErrorKinds.RpcError, sanitizeMessage(`Jito submitBundle transport failed on ${this.name}`, jitoUrl), { chainId: this.chainId }, sanitizeCause(err, jitoUrl));
|
|
761
|
+
}
|
|
762
|
+
if (json.error || !json.result) {
|
|
763
|
+
throw new ChainError(ChainErrorKinds.BroadcastRejected, sanitizeMessage(`Jito submitBundle rejected on ${this.name}: ${json.error?.message ?? 'no bundle id returned'}`, jitoUrl), { chainId: this.chainId });
|
|
764
|
+
}
|
|
765
|
+
return json.result;
|
|
766
|
+
}
|
|
767
|
+
async getBundleStatus(bundleId, opts) {
|
|
768
|
+
if (!this.jito) {
|
|
769
|
+
throw new ChainError(ChainErrorKinds.FeatureNotSupported, 'Jito getBundleStatus requires SolanaChain to be constructed with jito config', { chainId: this.chainId });
|
|
770
|
+
}
|
|
771
|
+
const ids = Array.isArray(bundleId) ? bundleId : [bundleId];
|
|
772
|
+
const body = {
|
|
773
|
+
jsonrpc: '2.0',
|
|
774
|
+
id: 1,
|
|
775
|
+
method: 'getBundleStatuses',
|
|
776
|
+
params: [ids],
|
|
777
|
+
};
|
|
778
|
+
let json;
|
|
779
|
+
const jitoUrl = this.jito.url;
|
|
780
|
+
const signal = combineJitoSignal(opts?.signal, opts?.timeoutMs ?? 15_000);
|
|
781
|
+
try {
|
|
782
|
+
const resp = await fetch(jitoUrl, {
|
|
783
|
+
method: 'POST',
|
|
784
|
+
headers: {
|
|
785
|
+
'Content-Type': 'application/json',
|
|
786
|
+
...(this.jito.auth ? { Authorization: `Bearer ${this.jito.auth}` } : {}),
|
|
787
|
+
},
|
|
788
|
+
body: JSON.stringify(body),
|
|
789
|
+
signal,
|
|
790
|
+
});
|
|
791
|
+
if (!resp.ok) {
|
|
792
|
+
throw new ChainError(ChainErrorKinds.RpcError, sanitizeMessage(`Jito getBundleStatuses HTTP ${resp.status} on ${this.name}`, jitoUrl), { chainId: this.chainId });
|
|
793
|
+
}
|
|
794
|
+
json = (await resp.json());
|
|
795
|
+
}
|
|
796
|
+
catch (err) {
|
|
797
|
+
if (err instanceof ChainError)
|
|
798
|
+
throw err;
|
|
799
|
+
throw new ChainError(ChainErrorKinds.RpcError, sanitizeMessage(`Jito getBundleStatuses transport failed on ${this.name}`, jitoUrl), { chainId: this.chainId }, sanitizeCause(err, jitoUrl));
|
|
800
|
+
}
|
|
801
|
+
if (json.error) {
|
|
802
|
+
throw new ChainError(ChainErrorKinds.RpcError, sanitizeMessage(`Jito getBundleStatuses error on ${this.name}: ${json.error.message ?? 'unknown'}`, jitoUrl), { chainId: this.chainId });
|
|
803
|
+
}
|
|
804
|
+
const rawValue = json.result?.value;
|
|
805
|
+
if (rawValue !== undefined && rawValue !== null && !Array.isArray(rawValue)) {
|
|
806
|
+
throw new ChainError(ChainErrorKinds.RpcError, sanitizeMessage(`Jito getBundleStatuses returned malformed value (expected array or null)`, jitoUrl), { chainId: this.chainId });
|
|
807
|
+
}
|
|
808
|
+
const rows = Array.isArray(rawValue) ? rawValue : [];
|
|
809
|
+
const statuses = ids.map((id) => {
|
|
810
|
+
const row = rows.find((r) => r != null && r.bundle_id === id);
|
|
811
|
+
if (!row)
|
|
812
|
+
return { bundleId: id, state: 'Pending' };
|
|
813
|
+
// Jito's err field varies: null (success), { Ok: null } (success),
|
|
814
|
+
// { Err: <anything> } (failed), or a plain string (some proxies).
|
|
815
|
+
// Anything that's non-null AND not { Ok: null } means failure.
|
|
816
|
+
const rawErr = row.err;
|
|
817
|
+
const isOk = rawErr === null || rawErr === undefined
|
|
818
|
+
|| (typeof rawErr === 'object' && 'Ok' in rawErr && rawErr.Ok === null && !('Err' in rawErr));
|
|
819
|
+
const errStr = isOk
|
|
820
|
+
? undefined
|
|
821
|
+
: typeof rawErr === 'string'
|
|
822
|
+
? rawErr
|
|
823
|
+
: typeof rawErr === 'object' && rawErr !== null && 'Err' in rawErr
|
|
824
|
+
? String(rawErr.Err)
|
|
825
|
+
: JSON.stringify(rawErr);
|
|
826
|
+
const confStatus = row.confirmation_status;
|
|
827
|
+
const state = errStr !== undefined
|
|
828
|
+
? 'Failed'
|
|
829
|
+
: (confStatus === 'finalized' || confStatus === 'confirmed' ? 'Landed' : 'Pending');
|
|
830
|
+
return { bundleId: id, state, slot: row.slot, err: errStr };
|
|
831
|
+
});
|
|
832
|
+
return Array.isArray(bundleId) ? statuses : statuses[0];
|
|
833
|
+
}
|
|
834
|
+
async createUnsignedTransaction(req) {
|
|
835
|
+
if (req && req.signal !== undefined) {
|
|
836
|
+
throw new ChainError(ChainErrorKinds.FeatureNotSupported, `Solana createUnsignedTransaction: signal is not honored in 0.3.0 (silently ignoring would let a caller conclude 'not built' while getLatestBlockhash continues). Cancellation returns in 0.3.1.`, { chainId: this.chainId });
|
|
837
|
+
}
|
|
838
|
+
if (!req.payer) {
|
|
839
|
+
throw new ChainError(ChainErrorKinds.InvalidArgument, 'CreateSolanaUnsignedTransactionRequest.payer is required', { chainId: this.chainId });
|
|
840
|
+
}
|
|
841
|
+
let payerKey;
|
|
842
|
+
try {
|
|
843
|
+
payerKey = new PublicKey(req.payer);
|
|
844
|
+
}
|
|
845
|
+
catch (err) {
|
|
846
|
+
throw new ChainError(ChainErrorKinds.InvalidAddress, `Invalid Solana payer pubkey: ${req.payer}`, { chainId: this.chainId, address: req.payer }, err instanceof Error ? err : undefined);
|
|
847
|
+
}
|
|
848
|
+
if (!Array.isArray(req.instructions) || req.instructions.length === 0) {
|
|
849
|
+
throw new ChainError(ChainErrorKinds.InvalidArgument, 'CreateSolanaUnsignedTransactionRequest.instructions must be a non-empty array', { chainId: this.chainId });
|
|
850
|
+
}
|
|
851
|
+
const connection = this.getConnection();
|
|
852
|
+
let blockhash;
|
|
853
|
+
let lastValidBlockHeight;
|
|
854
|
+
try {
|
|
855
|
+
const bh = await connection.getLatestBlockhash('finalized');
|
|
856
|
+
blockhash = bh.blockhash;
|
|
857
|
+
lastValidBlockHeight = bh.lastValidBlockHeight;
|
|
858
|
+
}
|
|
859
|
+
catch (err) {
|
|
860
|
+
throw new ChainError(ChainErrorKinds.RpcError, sanitizeMessage(`Solana createUnsignedTransaction: getLatestBlockhash failed on ${this.name}`, this.resolvedRpcUrlForRedaction()), { chainId: this.chainId }, sanitizeCause(err, this.resolvedRpcUrlForRedaction()));
|
|
861
|
+
}
|
|
862
|
+
let message;
|
|
863
|
+
try {
|
|
864
|
+
message = MessageV0.compile({
|
|
865
|
+
payerKey,
|
|
866
|
+
instructions: req.instructions,
|
|
867
|
+
recentBlockhash: blockhash,
|
|
868
|
+
addressLookupTableAccounts: req.addressLookupTables ?? [],
|
|
869
|
+
});
|
|
870
|
+
}
|
|
871
|
+
catch (err) {
|
|
872
|
+
throw new ChainError(ChainErrorKinds.InvalidArgument, `Solana createUnsignedTransaction: MessageV0.compile failed — instruction or ALT layout invalid`, { chainId: this.chainId }, err instanceof Error ? err : undefined);
|
|
873
|
+
}
|
|
874
|
+
const tx = new VersionedTransaction(message);
|
|
875
|
+
let serializedSize;
|
|
876
|
+
try {
|
|
877
|
+
serializedSize = tx.serialize().length;
|
|
878
|
+
}
|
|
879
|
+
catch (err) {
|
|
880
|
+
throw new ChainError(ChainErrorKinds.TransactionTooLarge, `Compiled Solana tx exceeds the serialize buffer; supply addressLookupTables to compress the account list`, { chainId: this.chainId }, err instanceof Error ? err : undefined);
|
|
881
|
+
}
|
|
882
|
+
if (serializedSize > 1232) {
|
|
883
|
+
throw new ChainError(ChainErrorKinds.TransactionTooLarge, `Compiled Solana tx exceeds 1232-byte wire limit; supply addressLookupTables to reduce size`, { chainId: this.chainId });
|
|
884
|
+
}
|
|
885
|
+
return new UnsignedSolanaTransaction({
|
|
886
|
+
chainId: this.chainId,
|
|
887
|
+
transaction: tx,
|
|
888
|
+
feePayer: req.payer,
|
|
889
|
+
recentBlockhash: blockhash,
|
|
890
|
+
lastValidBlockHeight,
|
|
891
|
+
instructions: req.instructions,
|
|
892
|
+
addressLookupTables: req.addressLookupTables,
|
|
893
|
+
});
|
|
894
|
+
}
|
|
895
|
+
async getAccountInfo(pubkey) {
|
|
896
|
+
const connection = this.getConnection();
|
|
897
|
+
const toPk = (raw) => {
|
|
898
|
+
try {
|
|
899
|
+
return new PublicKey(raw);
|
|
900
|
+
}
|
|
901
|
+
catch (err) {
|
|
902
|
+
throw new ChainError(ChainErrorKinds.InvalidAddress, `Invalid Solana pubkey: ${raw}`, { chainId: this.chainId, address: raw }, err instanceof Error ? err : undefined);
|
|
903
|
+
}
|
|
904
|
+
};
|
|
905
|
+
if (Array.isArray(pubkey)) {
|
|
906
|
+
const pks = pubkey.map(toPk);
|
|
907
|
+
try {
|
|
908
|
+
const infos = await connection.getMultipleAccountsInfo(pks);
|
|
909
|
+
return infos.map((info) => (info === null ? null : toAccountInfoResult(info)));
|
|
910
|
+
}
|
|
911
|
+
catch (err) {
|
|
912
|
+
throw new ChainError(ChainErrorKinds.RpcError, sanitizeMessage(`Solana getMultipleAccountsInfo RPC failure on ${this.name}`, this.resolvedRpcUrlForRedaction()), { chainId: this.chainId }, sanitizeCause(err, this.resolvedRpcUrlForRedaction()));
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
try {
|
|
916
|
+
const info = await connection.getAccountInfo(toPk(pubkey));
|
|
917
|
+
return info === null ? null : toAccountInfoResult(info);
|
|
918
|
+
}
|
|
919
|
+
catch (err) {
|
|
920
|
+
if (err instanceof ChainError)
|
|
921
|
+
throw err;
|
|
922
|
+
throw new ChainError(ChainErrorKinds.RpcError, sanitizeMessage(`Solana getAccountInfo RPC failure on ${this.name}`, this.resolvedRpcUrlForRedaction()), { chainId: this.chainId, address: pubkey }, sanitizeCause(err, this.resolvedRpcUrlForRedaction()));
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
async getTokenAccount(owner, mint, opts) {
|
|
926
|
+
let ownerPk;
|
|
927
|
+
let mintPk;
|
|
928
|
+
try {
|
|
929
|
+
ownerPk = new PublicKey(owner);
|
|
930
|
+
}
|
|
931
|
+
catch (err) {
|
|
932
|
+
throw new ChainError(ChainErrorKinds.InvalidAddress, `Invalid Solana owner pubkey: ${owner}`, { chainId: this.chainId, address: owner }, err instanceof Error ? err : undefined);
|
|
933
|
+
}
|
|
934
|
+
try {
|
|
935
|
+
mintPk = new PublicKey(mint);
|
|
936
|
+
}
|
|
937
|
+
catch (err) {
|
|
938
|
+
throw new ChainError(ChainErrorKinds.InvalidTokenIdentifier, `Invalid Solana mint pubkey: ${mint}`, { chainId: this.chainId, identifier: mint }, err instanceof Error ? err : undefined);
|
|
939
|
+
}
|
|
940
|
+
let programId;
|
|
941
|
+
try {
|
|
942
|
+
programId = await this.resolveTokenProgramId(mintPk);
|
|
943
|
+
}
|
|
944
|
+
catch (err) {
|
|
945
|
+
if (err instanceof ChainError)
|
|
946
|
+
throw err;
|
|
947
|
+
throw new ChainError(ChainErrorKinds.RpcError, sanitizeMessage(`Solana getTokenAccount: mint-program lookup failed on ${this.name}`, this.resolvedRpcUrlForRedaction()), { chainId: this.chainId, identifier: mint }, sanitizeCause(err, this.resolvedRpcUrlForRedaction()));
|
|
948
|
+
}
|
|
949
|
+
let ataPk;
|
|
950
|
+
try {
|
|
951
|
+
ataPk = getAssociatedTokenAddressSync(mintPk, ownerPk, opts?.allowOwnerOffCurve ?? false, programId);
|
|
952
|
+
}
|
|
953
|
+
catch (err) {
|
|
954
|
+
throw new ChainError(ChainErrorKinds.InvalidArgument, `ATA derivation failed: ${err instanceof Error ? err.message : String(err)}`, { chainId: this.chainId, address: owner }, err instanceof Error ? err : undefined);
|
|
955
|
+
}
|
|
956
|
+
try {
|
|
957
|
+
const acc = await getAccount(this.getConnection(), ataPk, undefined, programId);
|
|
958
|
+
return { ata: ataPk.toBase58(), exists: true, balanceMr: acc.amount };
|
|
959
|
+
}
|
|
960
|
+
catch (err) {
|
|
961
|
+
if (err instanceof TokenAccountNotFoundError) {
|
|
962
|
+
return { ata: ataPk.toBase58(), exists: false, balanceMr: undefined };
|
|
963
|
+
}
|
|
964
|
+
if (err instanceof TokenInvalidAccountOwnerError) {
|
|
965
|
+
throw new ChainError(ChainErrorKinds.InvalidArgument, `Solana getTokenAccount: account at ${ataPk.toBase58()} exists but is owned by an unexpected program (hostile squat or wrong mint program). Consumer should NOT create-ATA blindly.`, { chainId: this.chainId, address: ataPk.toBase58() }, err);
|
|
966
|
+
}
|
|
967
|
+
throw new ChainError(ChainErrorKinds.RpcError, sanitizeMessage(`Solana getTokenAccount RPC failure on ${this.name}`, this.resolvedRpcUrlForRedaction()), { chainId: this.chainId, address: ataPk.toBase58() }, sanitizeCause(err, this.resolvedRpcUrlForRedaction()));
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
async fetchAddressLookupTable(altAddress) {
|
|
971
|
+
let pk;
|
|
972
|
+
try {
|
|
973
|
+
pk = new PublicKey(altAddress);
|
|
974
|
+
}
|
|
975
|
+
catch (err) {
|
|
976
|
+
throw new ChainError(ChainErrorKinds.InvalidAddress, `Invalid ALT pubkey: ${altAddress}`, { chainId: this.chainId, address: altAddress }, err instanceof Error ? err : undefined);
|
|
977
|
+
}
|
|
978
|
+
let res;
|
|
979
|
+
try {
|
|
980
|
+
res = await this.getConnection().getAddressLookupTable(pk);
|
|
981
|
+
}
|
|
982
|
+
catch (err) {
|
|
983
|
+
throw new ChainError(ChainErrorKinds.RpcError, sanitizeMessage(`Solana fetchAddressLookupTable RPC failure on ${this.name}`, this.resolvedRpcUrlForRedaction()), { chainId: this.chainId, address: altAddress }, sanitizeCause(err, this.resolvedRpcUrlForRedaction()));
|
|
984
|
+
}
|
|
985
|
+
if (!res.value) {
|
|
986
|
+
throw new ChainError(ChainErrorKinds.InvalidArgument, `Address lookup table ${altAddress} not found`, { chainId: this.chainId, address: altAddress });
|
|
987
|
+
}
|
|
988
|
+
return res.value;
|
|
989
|
+
}
|
|
990
|
+
classifyBroadcastError(err) {
|
|
991
|
+
const rpc = this.resolvedRpcUrlForRedaction();
|
|
992
|
+
const msg = err instanceof Error ? err.message.toLowerCase() : String(err).toLowerCase();
|
|
993
|
+
const safeCause = sanitizeCause(err, rpc);
|
|
994
|
+
const transportSignals = /econnreset|econnrefused|econnaborted|etimedout|enotfound|network request failed|fetch failed|socket hang up|too\s+many\s+requests|rate.?limit/;
|
|
995
|
+
if (/blockhash\s+not\s+found|blockhash\s+expired|block\s+height\s+exceeded/.test(msg)) {
|
|
996
|
+
return new ChainError(ChainErrorKinds.BlockhashExpired, sanitizeMessage(`Solana broadcast rejected: blockhash expired on ${this.name}`, rpc), { chainId: this.chainId }, safeCause);
|
|
997
|
+
}
|
|
998
|
+
// Preflight/simulation MUST be checked before the size predicate — Solana
|
|
999
|
+
// preflight errors routinely embed "exceeds <N>" for CU / account-count
|
|
1000
|
+
// limits, and would otherwise be misclassified as TransactionTooLarge.
|
|
1001
|
+
if (msg.includes('preflight') || msg.includes('simulation failed') || msg.includes('sendtransactionerror')) {
|
|
1002
|
+
return new ChainError(ChainErrorKinds.SimulationFailed, sanitizeMessage(`Solana broadcast rejected: preflight simulation failed on ${this.name}`, rpc), { chainId: this.chainId }, safeCause);
|
|
1003
|
+
}
|
|
1004
|
+
if (/transaction\s+too\s+large|encoded\/raw transaction size exceeds|exceeds\s+the\s+maximum\s+transaction\s+size/.test(msg)) {
|
|
1005
|
+
return new ChainError(ChainErrorKinds.TransactionTooLarge, sanitizeMessage(`Solana broadcast rejected: transaction exceeds 1232 bytes on ${this.name} (use ALT)`, rpc), { chainId: this.chainId }, safeCause);
|
|
1006
|
+
}
|
|
1007
|
+
if (transportSignals.test(msg)) {
|
|
1008
|
+
return new ChainError(ChainErrorKinds.RpcError, sanitizeMessage(`Solana broadcast RPC transport failure on ${this.name}`, rpc), { chainId: this.chainId }, safeCause);
|
|
1009
|
+
}
|
|
1010
|
+
return new ChainError(ChainErrorKinds.BroadcastRejected, sanitizeMessage(`Solana broadcast rejected on ${this.name}`, rpc), { chainId: this.chainId }, safeCause);
|
|
537
1011
|
}
|
|
538
1012
|
/**
|
|
539
1013
|
* Resolves the token program owner for a given mint. Token-2022 mints are owned by
|
|
@@ -701,4 +1175,125 @@ export class SolanaChain extends Chain {
|
|
|
701
1175
|
return result;
|
|
702
1176
|
}
|
|
703
1177
|
}
|
|
1178
|
+
function validateAltList(input, chainId) {
|
|
1179
|
+
if (input === undefined || input === null)
|
|
1180
|
+
return [];
|
|
1181
|
+
if (!Array.isArray(input)) {
|
|
1182
|
+
throw new ChainError(ChainErrorKinds.InvalidArgument, `addressLookupTables must be an array of AddressLookupTableAccount, got ${typeof input}`, { chainId });
|
|
1183
|
+
}
|
|
1184
|
+
for (let i = 0; i < input.length; i++) {
|
|
1185
|
+
const a = input[i];
|
|
1186
|
+
if (a === null || typeof a !== 'object' || !('key' in a) || !('state' in a)) {
|
|
1187
|
+
throw new ChainError(ChainErrorKinds.InvalidArgument, `addressLookupTables[${i}] is not an AddressLookupTableAccount (missing key/state). Use SolanaChain.fetchAddressLookupTable to obtain valid instances.`, { chainId });
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1190
|
+
return input;
|
|
1191
|
+
}
|
|
1192
|
+
export function signatureBase58FromBytes(txBytes) {
|
|
1193
|
+
if (txBytes.length < 65) {
|
|
1194
|
+
throw new ChainError(ChainErrorKinds.InvalidArgument, `Solana broadcast: signed bytes too short (${txBytes.length}) to extract signature`, {});
|
|
1195
|
+
}
|
|
1196
|
+
const numSigs = txBytes[0];
|
|
1197
|
+
if (numSigs === 0 || txBytes.length < 1 + 64) {
|
|
1198
|
+
throw new ChainError(ChainErrorKinds.InvalidArgument, `Solana broadcast: no signatures in serialized transaction`, {});
|
|
1199
|
+
}
|
|
1200
|
+
const sigBytes = txBytes.subarray(1, 1 + 64);
|
|
1201
|
+
return bs58encode(sigBytes);
|
|
1202
|
+
}
|
|
1203
|
+
const BS58_ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
|
|
1204
|
+
export function bs58encode(bytes) {
|
|
1205
|
+
let n = 0n;
|
|
1206
|
+
for (const b of bytes)
|
|
1207
|
+
n = (n << 8n) | BigInt(b);
|
|
1208
|
+
let out = '';
|
|
1209
|
+
while (n > 0n) {
|
|
1210
|
+
const rem = Number(n % 58n);
|
|
1211
|
+
out = BS58_ALPHABET[rem] + out;
|
|
1212
|
+
n = n / 58n;
|
|
1213
|
+
}
|
|
1214
|
+
for (const b of bytes) {
|
|
1215
|
+
if (b === 0)
|
|
1216
|
+
out = '1' + out;
|
|
1217
|
+
else
|
|
1218
|
+
break;
|
|
1219
|
+
}
|
|
1220
|
+
return out;
|
|
1221
|
+
}
|
|
1222
|
+
const SOLANA_BATCH_STATUS_CONCURRENCY = 8;
|
|
1223
|
+
async function runSolanaBatchStatus(items, fetchOne) {
|
|
1224
|
+
const results = new Array(items.length);
|
|
1225
|
+
const ac = new AbortController();
|
|
1226
|
+
let cursor = 0;
|
|
1227
|
+
const workers = [];
|
|
1228
|
+
const spawn = async () => {
|
|
1229
|
+
while (!ac.signal.aborted) {
|
|
1230
|
+
const idx = cursor++;
|
|
1231
|
+
if (idx >= items.length)
|
|
1232
|
+
return;
|
|
1233
|
+
try {
|
|
1234
|
+
results[idx] = await fetchOne(items[idx], ac.signal);
|
|
1235
|
+
}
|
|
1236
|
+
catch (err) {
|
|
1237
|
+
ac.abort();
|
|
1238
|
+
throw err;
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1241
|
+
};
|
|
1242
|
+
const workerCount = Math.min(SOLANA_BATCH_STATUS_CONCURRENCY, items.length);
|
|
1243
|
+
for (let i = 0; i < workerCount; i++)
|
|
1244
|
+
workers.push(spawn());
|
|
1245
|
+
await Promise.all(workers);
|
|
1246
|
+
return results;
|
|
1247
|
+
}
|
|
1248
|
+
function anySignal(a, b) {
|
|
1249
|
+
if (typeof AbortSignal.any === 'function')
|
|
1250
|
+
return AbortSignal.any([a, b]);
|
|
1251
|
+
const ac = new AbortController();
|
|
1252
|
+
const onAbort = () => ac.abort();
|
|
1253
|
+
if (a.aborted || b.aborted)
|
|
1254
|
+
ac.abort();
|
|
1255
|
+
else {
|
|
1256
|
+
a.addEventListener('abort', onAbort, { once: true });
|
|
1257
|
+
b.addEventListener('abort', onAbort, { once: true });
|
|
1258
|
+
}
|
|
1259
|
+
return ac.signal;
|
|
1260
|
+
}
|
|
1261
|
+
function combineJitoSignal(consumerSignal, timeoutMs) {
|
|
1262
|
+
const timeout = AbortSignal.timeout(timeoutMs);
|
|
1263
|
+
if (!consumerSignal)
|
|
1264
|
+
return timeout;
|
|
1265
|
+
const ac = new AbortController();
|
|
1266
|
+
const onAbort = () => ac.abort();
|
|
1267
|
+
if (consumerSignal.aborted || timeout.aborted)
|
|
1268
|
+
ac.abort();
|
|
1269
|
+
else {
|
|
1270
|
+
consumerSignal.addEventListener('abort', onAbort, { once: true });
|
|
1271
|
+
timeout.addEventListener('abort', onAbort, { once: true });
|
|
1272
|
+
}
|
|
1273
|
+
return ac.signal;
|
|
1274
|
+
}
|
|
1275
|
+
async function solanaInterruptibleSleep(ms, signal) {
|
|
1276
|
+
if (signal?.aborted)
|
|
1277
|
+
return;
|
|
1278
|
+
await new Promise((resolve) => {
|
|
1279
|
+
const t = setTimeout(() => {
|
|
1280
|
+
signal?.removeEventListener('abort', onAbort);
|
|
1281
|
+
resolve();
|
|
1282
|
+
}, ms);
|
|
1283
|
+
const onAbort = () => {
|
|
1284
|
+
clearTimeout(t);
|
|
1285
|
+
resolve();
|
|
1286
|
+
};
|
|
1287
|
+
signal?.addEventListener('abort', onAbort, { once: true });
|
|
1288
|
+
});
|
|
1289
|
+
}
|
|
1290
|
+
function toAccountInfoResult(info) {
|
|
1291
|
+
return {
|
|
1292
|
+
owner: info.owner.toBase58(),
|
|
1293
|
+
lamports: BigInt(info.lamports),
|
|
1294
|
+
data: Uint8Array.from(info.data),
|
|
1295
|
+
executable: info.executable,
|
|
1296
|
+
rentEpoch: info.rentEpoch === undefined ? undefined : BigInt(info.rentEpoch),
|
|
1297
|
+
};
|
|
1298
|
+
}
|
|
704
1299
|
//# sourceMappingURL=solana_chain.js.map
|