@across-protocol/sdk 4.3.110 → 4.3.111-alpha.1
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/addressAggregator/adapters/abstract.js +50 -64
- package/dist/cjs/addressAggregator/adapters/abstract.js.map +1 -1
- package/dist/cjs/addressAggregator/adapters/bybit.js +16 -29
- package/dist/cjs/addressAggregator/adapters/bybit.js.map +1 -1
- package/dist/cjs/addressAggregator/adapters/env.js +11 -15
- package/dist/cjs/addressAggregator/adapters/env.js.map +1 -1
- package/dist/cjs/addressAggregator/adapters/file.js +32 -45
- package/dist/cjs/addressAggregator/adapters/file.js.map +1 -1
- package/dist/cjs/addressAggregator/adapters/index.js +1 -1
- package/dist/cjs/addressAggregator/adapters/risklabs.js +22 -36
- package/dist/cjs/addressAggregator/adapters/risklabs.js.map +1 -1
- package/dist/cjs/addressAggregator/index.js +57 -87
- package/dist/cjs/addressAggregator/index.js.map +1 -1
- package/dist/cjs/apiClient/abstractClient.js +9 -8
- package/dist/cjs/apiClient/abstractClient.js.map +1 -1
- package/dist/cjs/apiClient/index.js +1 -1
- package/dist/cjs/apiClient/mockedClient.js +23 -29
- package/dist/cjs/apiClient/mockedClient.js.map +1 -1
- package/dist/cjs/apiClient/productionClient.js +65 -103
- package/dist/cjs/apiClient/productionClient.js.map +1 -1
- package/dist/cjs/arch/evm/BlockUtils.js +122 -208
- package/dist/cjs/arch/evm/BlockUtils.js.map +1 -1
- package/dist/cjs/arch/evm/MessageUtils.js +1 -1
- package/dist/cjs/arch/evm/MessageUtils.js.map +1 -1
- package/dist/cjs/arch/evm/SpokeUtils.js +134 -288
- package/dist/cjs/arch/evm/SpokeUtils.js.map +1 -1
- package/dist/cjs/arch/evm/index.js +1 -1
- package/dist/cjs/arch/evm/utils/index.js +1 -1
- package/dist/cjs/arch/evm/utils/wait.js +38 -49
- package/dist/cjs/arch/evm/utils/wait.js.map +1 -1
- package/dist/cjs/arch/index.js +1 -1
- package/dist/cjs/arch/svm/BlockUtils.js +102 -158
- package/dist/cjs/arch/svm/BlockUtils.js.map +1 -1
- package/dist/cjs/arch/svm/MessageUtils.js +2 -2
- package/dist/cjs/arch/svm/MessageUtils.js.map +1 -1
- package/dist/cjs/arch/svm/SpokeUtils.js +708 -1147
- package/dist/cjs/arch/svm/SpokeUtils.js.map +1 -1
- package/dist/cjs/arch/svm/encoders.js +1 -1
- package/dist/cjs/arch/svm/encoders.js.map +1 -1
- package/dist/cjs/arch/svm/eventsClient.js +174 -236
- package/dist/cjs/arch/svm/eventsClient.js.map +1 -1
- package/dist/cjs/arch/svm/index.js +1 -1
- package/dist/cjs/arch/svm/provider.js +3 -3
- package/dist/cjs/arch/svm/provider.js.map +1 -1
- package/dist/cjs/arch/svm/utils.js +166 -355
- package/dist/cjs/arch/svm/utils.js.map +1 -1
- package/dist/cjs/caching/Arweave/ArweaveClient.js +168 -246
- package/dist/cjs/caching/Arweave/ArweaveClient.js.map +1 -1
- package/dist/cjs/caching/Arweave/index.js +1 -1
- package/dist/cjs/caching/IPFS/PinataIPFSClient.js +40 -49
- package/dist/cjs/caching/IPFS/PinataIPFSClient.js.map +1 -1
- package/dist/cjs/caching/IPFS/index.js +1 -1
- package/dist/cjs/caching/Memory/MemoryCacheClient.js +13 -18
- package/dist/cjs/caching/Memory/MemoryCacheClient.js.map +1 -1
- package/dist/cjs/caching/Memory/index.js +1 -1
- package/dist/cjs/caching/index.js +1 -1
- package/dist/cjs/clients/AcrossConfigStoreClient/AcrossConfigStoreClient.js +302 -381
- package/dist/cjs/clients/AcrossConfigStoreClient/AcrossConfigStoreClient.js.map +1 -1
- package/dist/cjs/clients/AcrossConfigStoreClient/index.js +1 -1
- package/dist/cjs/clients/BaseAbstractClient.js +58 -83
- package/dist/cjs/clients/BaseAbstractClient.js.map +1 -1
- package/dist/cjs/clients/BundleDataClient/BundleDataClient.js +709 -900
- package/dist/cjs/clients/BundleDataClient/BundleDataClient.js.map +1 -1
- package/dist/cjs/clients/BundleDataClient/index.js +1 -1
- package/dist/cjs/clients/BundleDataClient/utils/DataworkerUtils.js +95 -128
- package/dist/cjs/clients/BundleDataClient/utils/DataworkerUtils.js.map +1 -1
- package/dist/cjs/clients/BundleDataClient/utils/FillUtils.js +48 -53
- package/dist/cjs/clients/BundleDataClient/utils/FillUtils.js.map +1 -1
- package/dist/cjs/clients/BundleDataClient/utils/MerkleTreeUtils.js +10 -8
- package/dist/cjs/clients/BundleDataClient/utils/MerkleTreeUtils.js.map +1 -1
- package/dist/cjs/clients/BundleDataClient/utils/PoolRebalanceUtils.js +67 -90
- package/dist/cjs/clients/BundleDataClient/utils/PoolRebalanceUtils.js.map +1 -1
- package/dist/cjs/clients/BundleDataClient/utils/SuperstructUtils.js +46 -24
- package/dist/cjs/clients/BundleDataClient/utils/SuperstructUtils.js.map +1 -1
- package/dist/cjs/clients/BundleDataClient/utils/index.js +1 -1
- package/dist/cjs/clients/HubPoolClient.js +526 -708
- package/dist/cjs/clients/HubPoolClient.js.map +1 -1
- package/dist/cjs/clients/SpokePoolClient/EVMSpokePoolClient.js +133 -179
- package/dist/cjs/clients/SpokePoolClient/EVMSpokePoolClient.js.map +1 -1
- package/dist/cjs/clients/SpokePoolClient/SVMSpokePoolClient.js +124 -183
- package/dist/cjs/clients/SpokePoolClient/SVMSpokePoolClient.js.map +1 -1
- package/dist/cjs/clients/SpokePoolClient/SpokePoolClient.js +357 -389
- package/dist/cjs/clients/SpokePoolClient/SpokePoolClient.js.map +1 -1
- package/dist/cjs/clients/SpokePoolClient/SpokePoolClientManager.js +9 -8
- package/dist/cjs/clients/SpokePoolClient/SpokePoolClientManager.js.map +1 -1
- package/dist/cjs/clients/SpokePoolClient/index.js +3 -3
- package/dist/cjs/clients/SpokePoolClient/index.js.map +1 -1
- package/dist/cjs/clients/index.js +1 -1
- package/dist/cjs/clients/mocks/MockConfigStoreClient.js +58 -67
- package/dist/cjs/clients/mocks/MockConfigStoreClient.js.map +1 -1
- package/dist/cjs/clients/mocks/MockEvents.js +47 -52
- package/dist/cjs/clients/mocks/MockEvents.js.map +1 -1
- package/dist/cjs/clients/mocks/MockHubPoolClient.js +142 -185
- package/dist/cjs/clients/mocks/MockHubPoolClient.js.map +1 -1
- package/dist/cjs/clients/mocks/MockSpokePoolClient.js +208 -192
- package/dist/cjs/clients/mocks/MockSpokePoolClient.js.map +1 -1
- package/dist/cjs/clients/mocks/MockSvmCpiEventsClient.js +140 -143
- package/dist/cjs/clients/mocks/MockSvmCpiEventsClient.js.map +1 -1
- package/dist/cjs/clients/mocks/MockSvmSpokePoolClient.js +57 -73
- package/dist/cjs/clients/mocks/MockSvmSpokePoolClient.js.map +1 -1
- package/dist/cjs/clients/mocks/index.js +1 -1
- package/dist/cjs/coingecko/Coingecko.js +285 -437
- package/dist/cjs/coingecko/Coingecko.js.map +1 -1
- package/dist/cjs/coingecko/index.js +1 -1
- package/dist/cjs/constants.js +23 -29
- package/dist/cjs/constants.js.map +1 -1
- package/dist/cjs/contracts/acrossConfigStore.js +27 -48
- package/dist/cjs/contracts/acrossConfigStore.js.map +1 -1
- package/dist/cjs/contracts/hubPool.js +36 -20
- package/dist/cjs/contracts/hubPool.js.map +1 -1
- package/dist/cjs/contracts/index.js +1 -1
- package/dist/cjs/contracts/utils.js +6 -8
- package/dist/cjs/contracts/utils.js.map +1 -1
- package/dist/cjs/gasPriceOracle/adapters/arbitrum.js +7 -16
- package/dist/cjs/gasPriceOracle/adapters/arbitrum.js.map +1 -1
- package/dist/cjs/gasPriceOracle/adapters/ethereum.js +26 -45
- package/dist/cjs/gasPriceOracle/adapters/ethereum.js.map +1 -1
- package/dist/cjs/gasPriceOracle/adapters/linea-viem.js +16 -28
- package/dist/cjs/gasPriceOracle/adapters/linea-viem.js.map +1 -1
- package/dist/cjs/gasPriceOracle/adapters/polygon.js +73 -112
- package/dist/cjs/gasPriceOracle/adapters/polygon.js.map +1 -1
- package/dist/cjs/gasPriceOracle/adapters/solana.js +20 -33
- package/dist/cjs/gasPriceOracle/adapters/solana.js.map +1 -1
- package/dist/cjs/gasPriceOracle/oracle.js +77 -103
- package/dist/cjs/gasPriceOracle/oracle.js.map +1 -1
- package/dist/cjs/gasPriceOracle/types.js +3 -3
- package/dist/cjs/gasPriceOracle/types.js.map +1 -1
- package/dist/cjs/gasPriceOracle/util.js +8 -8
- package/dist/cjs/gasPriceOracle/util.js.map +1 -1
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/interfaces/index.js +1 -1
- package/dist/cjs/lpFeeCalculator/index.js +1 -1
- package/dist/cjs/lpFeeCalculator/lpFeeCalculator.js +33 -35
- package/dist/cjs/lpFeeCalculator/lpFeeCalculator.js.map +1 -1
- package/dist/cjs/lpFeeCalculator/rateModel.js +7 -9
- package/dist/cjs/lpFeeCalculator/rateModel.js.map +1 -1
- package/dist/cjs/merkleDistributor/MerkleDistributor.js +20 -18
- package/dist/cjs/merkleDistributor/MerkleDistributor.js.map +1 -1
- package/dist/cjs/merkleDistributor/index.js +1 -1
- package/dist/cjs/merkleDistributor/model/index.js +1 -1
- package/dist/cjs/pool/TransactionManager.js +45 -100
- package/dist/cjs/pool/TransactionManager.js.map +1 -1
- package/dist/cjs/pool/index.js +1 -1
- package/dist/cjs/pool/poolClient.js +464 -731
- package/dist/cjs/pool/poolClient.js.map +1 -1
- package/dist/cjs/pool/uma/across/index.js +1 -1
- package/dist/cjs/pool/uma/across/transactionManager.js +45 -100
- package/dist/cjs/pool/uma/across/transactionManager.js.map +1 -1
- package/dist/cjs/pool/uma/clients/erc20/client.js +18 -16
- package/dist/cjs/pool/uma/clients/erc20/client.js.map +1 -1
- package/dist/cjs/pool/uma/clients/erc20/index.js +1 -1
- package/dist/cjs/pool/uma/clients/index.js +1 -1
- package/dist/cjs/pool/uma/index.js +1 -1
- package/dist/cjs/pool/uma/oracle/index.js +1 -1
- package/dist/cjs/pool/uma/oracle/utils.js +4 -5
- package/dist/cjs/pool/uma/oracle/utils.js.map +1 -1
- package/dist/cjs/pool/uma/utils.js +11 -30
- package/dist/cjs/pool/uma/utils.js.map +1 -1
- package/dist/cjs/priceClient/adapters/acrossApi.js +22 -39
- package/dist/cjs/priceClient/adapters/acrossApi.js.map +1 -1
- package/dist/cjs/priceClient/adapters/baseAdapter.js +49 -73
- package/dist/cjs/priceClient/adapters/baseAdapter.js.map +1 -1
- package/dist/cjs/priceClient/adapters/coingecko.js +34 -61
- package/dist/cjs/priceClient/adapters/coingecko.js.map +1 -1
- package/dist/cjs/priceClient/adapters/default.js +16 -31
- package/dist/cjs/priceClient/adapters/default.js.map +1 -1
- package/dist/cjs/priceClient/adapters/defiLlama.js +40 -74
- package/dist/cjs/priceClient/adapters/defiLlama.js.map +1 -1
- package/dist/cjs/priceClient/adapters/index.js +1 -1
- package/dist/cjs/priceClient/index.js +1 -1
- package/dist/cjs/priceClient/priceClient.js +110 -159
- package/dist/cjs/priceClient/priceClient.js.map +1 -1
- package/dist/cjs/providers/alchemy.js +17 -19
- package/dist/cjs/providers/alchemy.js.map +1 -1
- package/dist/cjs/providers/cachedProvider.js +88 -129
- package/dist/cjs/providers/cachedProvider.js.map +1 -1
- package/dist/cjs/providers/drpc.js +9 -11
- package/dist/cjs/providers/drpc.js.map +1 -1
- package/dist/cjs/providers/index.js +1 -1
- package/dist/cjs/providers/infura.js +10 -12
- package/dist/cjs/providers/infura.js.map +1 -1
- package/dist/cjs/providers/mocks/MockCachedSolanaRpcFactory.js +7 -15
- package/dist/cjs/providers/mocks/MockCachedSolanaRpcFactory.js.map +1 -1
- package/dist/cjs/providers/mocks/MockRateLimitedSolanaRpcFactory.js +6 -14
- package/dist/cjs/providers/mocks/MockRateLimitedSolanaRpcFactory.js.map +1 -1
- package/dist/cjs/providers/mocks/MockRetrySolanaRpcFactory.js +7 -15
- package/dist/cjs/providers/mocks/MockRetrySolanaRpcFactory.js.map +1 -1
- package/dist/cjs/providers/mocks/MockSolanaRpcFactory.js +42 -66
- package/dist/cjs/providers/mocks/MockSolanaRpcFactory.js.map +1 -1
- package/dist/cjs/providers/mocks/index.js +1 -1
- package/dist/cjs/providers/mocks/mockEthersProvider.js +29 -31
- package/dist/cjs/providers/mocks/mockEthersProvider.js.map +1 -1
- package/dist/cjs/providers/quicknode.js +19 -21
- package/dist/cjs/providers/quicknode.js.map +1 -1
- package/dist/cjs/providers/rateLimitedProvider.js +64 -79
- package/dist/cjs/providers/rateLimitedProvider.js.map +1 -1
- package/dist/cjs/providers/retryProvider.js +163 -246
- package/dist/cjs/providers/retryProvider.js.map +1 -1
- package/dist/cjs/providers/solana/baseRpcFactories.js +14 -18
- package/dist/cjs/providers/solana/baseRpcFactories.js.map +1 -1
- package/dist/cjs/providers/solana/cachedRpcFactory.js +70 -112
- package/dist/cjs/providers/solana/cachedRpcFactory.js.map +1 -1
- package/dist/cjs/providers/solana/defaultRpcFactory.js +8 -15
- package/dist/cjs/providers/solana/defaultRpcFactory.js.map +1 -1
- package/dist/cjs/providers/solana/index.js +1 -1
- package/dist/cjs/providers/solana/quorumFallbackRpcFactory.js +135 -191
- package/dist/cjs/providers/solana/quorumFallbackRpcFactory.js.map +1 -1
- package/dist/cjs/providers/solana/rateLimitedRpcFactory.js +67 -90
- package/dist/cjs/providers/solana/rateLimitedRpcFactory.js.map +1 -1
- package/dist/cjs/providers/solana/retryRpcFactory.js +52 -79
- package/dist/cjs/providers/solana/retryRpcFactory.js.map +1 -1
- package/dist/cjs/providers/solana/utils.js +2 -2
- package/dist/cjs/providers/solana/utils.js.map +1 -1
- package/dist/cjs/providers/speedProvider.js +31 -53
- package/dist/cjs/providers/speedProvider.js.map +1 -1
- package/dist/cjs/providers/types.js +1 -1
- package/dist/cjs/providers/types.js.map +1 -1
- package/dist/cjs/providers/utils.js +26 -28
- package/dist/cjs/providers/utils.js.map +1 -1
- package/dist/cjs/relayFeeCalculator/chain-queries/baseQuery.js +108 -162
- package/dist/cjs/relayFeeCalculator/chain-queries/baseQuery.js.map +1 -1
- package/dist/cjs/relayFeeCalculator/chain-queries/customGasToken.js +14 -26
- package/dist/cjs/relayFeeCalculator/chain-queries/customGasToken.js.map +1 -1
- package/dist/cjs/relayFeeCalculator/chain-queries/factory.js +20 -29
- package/dist/cjs/relayFeeCalculator/chain-queries/factory.js.map +1 -1
- package/dist/cjs/relayFeeCalculator/chain-queries/index.js +1 -1
- package/dist/cjs/relayFeeCalculator/chain-queries/svmQuery.js +88 -137
- package/dist/cjs/relayFeeCalculator/chain-queries/svmQuery.js.map +1 -1
- package/dist/cjs/relayFeeCalculator/index.js +1 -1
- package/dist/cjs/relayFeeCalculator/relayFeeCalculator.js +199 -297
- package/dist/cjs/relayFeeCalculator/relayFeeCalculator.js.map +1 -1
- package/dist/cjs/typeguards/error.js +5 -7
- package/dist/cjs/typeguards/error.js.map +1 -1
- package/dist/cjs/typeguards/index.js +1 -1
- package/dist/cjs/utils/AddressUtils.js +117 -144
- package/dist/cjs/utils/AddressUtils.js.map +1 -1
- package/dist/cjs/utils/ArrayUtils.js +21 -78
- package/dist/cjs/utils/ArrayUtils.js.map +1 -1
- package/dist/cjs/utils/BigNumberUtils.js +9 -10
- package/dist/cjs/utils/BigNumberUtils.js.map +1 -1
- package/dist/cjs/utils/BlockExplorerUtils.js +26 -30
- package/dist/cjs/utils/BlockExplorerUtils.js.map +1 -1
- package/dist/cjs/utils/BlockFinder.js +2 -5
- package/dist/cjs/utils/BlockFinder.js.map +1 -1
- package/dist/cjs/utils/BlockUtils.js +24 -41
- package/dist/cjs/utils/BlockUtils.js.map +1 -1
- package/dist/cjs/utils/BundleUtils.js +21 -24
- package/dist/cjs/utils/BundleUtils.js.map +1 -1
- package/dist/cjs/utils/CCTPUtils.js +62 -126
- package/dist/cjs/utils/CCTPUtils.js.map +1 -1
- package/dist/cjs/utils/CachingUtils.js +20 -42
- package/dist/cjs/utils/CachingUtils.js.map +1 -1
- package/dist/cjs/utils/ContractUtils.js +5 -5
- package/dist/cjs/utils/ContractUtils.js.map +1 -1
- package/dist/cjs/utils/DepositUtils.js +122 -99
- package/dist/cjs/utils/DepositUtils.js.map +1 -1
- package/dist/cjs/utils/EventUtils.js +49 -70
- package/dist/cjs/utils/EventUtils.js.map +1 -1
- package/dist/cjs/utils/FormattingUtils.js +26 -32
- package/dist/cjs/utils/FormattingUtils.js.map +1 -1
- package/dist/cjs/utils/HyperLiquidUtils.js +10 -23
- package/dist/cjs/utils/HyperLiquidUtils.js.map +1 -1
- package/dist/cjs/utils/IPFSUtils.js +16 -34
- package/dist/cjs/utils/IPFSUtils.js.map +1 -1
- package/dist/cjs/utils/JSONUtils.js +6 -6
- package/dist/cjs/utils/JSONUtils.js.map +1 -1
- package/dist/cjs/utils/LogUtils.js +10 -12
- package/dist/cjs/utils/LogUtils.js.map +1 -1
- package/dist/cjs/utils/Multicall.js +56 -114
- package/dist/cjs/utils/Multicall.js.map +1 -1
- package/dist/cjs/utils/NetworkUtils.js +12 -21
- package/dist/cjs/utils/NetworkUtils.js.map +1 -1
- package/dist/cjs/utils/NumberUtils.js +1 -3
- package/dist/cjs/utils/NumberUtils.js.map +1 -1
- package/dist/cjs/utils/ObjectUtils.js +27 -41
- package/dist/cjs/utils/ObjectUtils.js.map +1 -1
- package/dist/cjs/utils/Profiler.js +80 -83
- package/dist/cjs/utils/Profiler.js.map +1 -1
- package/dist/cjs/utils/ReviverUtils.js +5 -9
- package/dist/cjs/utils/ReviverUtils.js.map +1 -1
- package/dist/cjs/utils/SpokeUtils.js +84 -84
- package/dist/cjs/utils/SpokeUtils.js.map +1 -1
- package/dist/cjs/utils/TokenUtils.js +41 -64
- package/dist/cjs/utils/TokenUtils.js.map +1 -1
- package/dist/cjs/utils/TypeGuards.js +1 -1
- package/dist/cjs/utils/TypeGuards.js.map +1 -1
- package/dist/cjs/utils/ValidatorUtils.js +7 -7
- package/dist/cjs/utils/ValidatorUtils.js.map +1 -1
- package/dist/cjs/utils/abi/contracts/index.js +1 -1
- package/dist/cjs/utils/abi/index.js +12 -22
- package/dist/cjs/utils/abi/index.js.map +1 -1
- package/dist/cjs/utils/abi/typechain/factories/Multicall3__factory.js +9 -12
- package/dist/cjs/utils/abi/typechain/factories/Multicall3__factory.js.map +1 -1
- package/dist/cjs/utils/abi/typechain/index.js +1 -1
- package/dist/cjs/utils/common.js +40 -53
- package/dist/cjs/utils/common.js.map +1 -1
- package/dist/cjs/utils/index.js +1 -1
- package/dist/esm/addressAggregator/adapters/abstract.js +48 -64
- package/dist/esm/addressAggregator/adapters/abstract.js.map +1 -1
- package/dist/esm/addressAggregator/adapters/bybit.js +15 -29
- package/dist/esm/addressAggregator/adapters/bybit.js.map +1 -1
- package/dist/esm/addressAggregator/adapters/env.js +9 -14
- package/dist/esm/addressAggregator/adapters/env.js.map +1 -1
- package/dist/esm/addressAggregator/adapters/file.js +29 -43
- package/dist/esm/addressAggregator/adapters/file.js.map +1 -1
- package/dist/esm/addressAggregator/adapters/risklabs.js +20 -35
- package/dist/esm/addressAggregator/adapters/risklabs.js.map +1 -1
- package/dist/esm/addressAggregator/index.js +52 -83
- package/dist/esm/addressAggregator/index.js.map +1 -1
- package/dist/esm/addressAggregator/types.js +1 -1
- package/dist/esm/addressAggregator/types.js.map +1 -1
- package/dist/esm/apiClient/abstractClient.js +15 -9
- package/dist/esm/apiClient/abstractClient.js.map +1 -1
- package/dist/esm/apiClient/mockedClient.js +21 -26
- package/dist/esm/apiClient/mockedClient.js.map +1 -1
- package/dist/esm/apiClient/productionClient.js +61 -101
- package/dist/esm/apiClient/productionClient.js.map +1 -1
- package/dist/esm/arch/evm/BlockUtils.js +139 -217
- package/dist/esm/arch/evm/BlockUtils.js.map +1 -1
- package/dist/esm/arch/evm/SpokeUtils.js +146 -289
- package/dist/esm/arch/evm/SpokeUtils.js.map +1 -1
- package/dist/esm/arch/evm/utils/wait.js +34 -46
- package/dist/esm/arch/evm/utils/wait.js.map +1 -1
- package/dist/esm/arch/svm/BlockUtils.js +118 -166
- package/dist/esm/arch/svm/BlockUtils.js.map +1 -1
- package/dist/esm/arch/svm/SpokeUtils.js +738 -1150
- package/dist/esm/arch/svm/SpokeUtils.js.map +1 -1
- package/dist/esm/arch/svm/constants.js +1 -1
- package/dist/esm/arch/svm/constants.js.map +1 -1
- package/dist/esm/arch/svm/eventsClient.js +172 -232
- package/dist/esm/arch/svm/eventsClient.js.map +1 -1
- package/dist/esm/arch/svm/provider.js +1 -1
- package/dist/esm/arch/svm/provider.js.map +1 -1
- package/dist/esm/arch/svm/utils.js +155 -345
- package/dist/esm/arch/svm/utils.js.map +1 -1
- package/dist/esm/caching/Arweave/ArweaveClient.js +182 -256
- package/dist/esm/caching/Arweave/ArweaveClient.js.map +1 -1
- package/dist/esm/caching/IPFS/PinataIPFSClient.js +47 -48
- package/dist/esm/caching/IPFS/PinataIPFSClient.js.map +1 -1
- package/dist/esm/caching/Memory/MemoryCacheClient.js +13 -19
- package/dist/esm/caching/Memory/MemoryCacheClient.js.map +1 -1
- package/dist/esm/clients/AcrossConfigStoreClient/AcrossConfigStoreClient.js +333 -408
- package/dist/esm/clients/AcrossConfigStoreClient/AcrossConfigStoreClient.js.map +1 -1
- package/dist/esm/clients/BaseAbstractClient.js +66 -92
- package/dist/esm/clients/BaseAbstractClient.js.map +1 -1
- package/dist/esm/clients/BundleDataClient/BundleDataClient.js +927 -1054
- package/dist/esm/clients/BundleDataClient/BundleDataClient.js.map +1 -1
- package/dist/esm/clients/BundleDataClient/utils/DataworkerUtils.js +102 -131
- package/dist/esm/clients/BundleDataClient/utils/DataworkerUtils.js.map +1 -1
- package/dist/esm/clients/BundleDataClient/utils/FillUtils.js +57 -59
- package/dist/esm/clients/BundleDataClient/utils/FillUtils.js.map +1 -1
- package/dist/esm/clients/BundleDataClient/utils/MerkleTreeUtils.js +7 -5
- package/dist/esm/clients/BundleDataClient/utils/MerkleTreeUtils.js.map +1 -1
- package/dist/esm/clients/BundleDataClient/utils/PoolRebalanceUtils.js +75 -94
- package/dist/esm/clients/BundleDataClient/utils/PoolRebalanceUtils.js.map +1 -1
- package/dist/esm/clients/BundleDataClient/utils/SuperstructUtils.js +45 -23
- package/dist/esm/clients/BundleDataClient/utils/SuperstructUtils.js.map +1 -1
- package/dist/esm/clients/HubPoolClient.js +581 -740
- package/dist/esm/clients/HubPoolClient.js.map +1 -1
- package/dist/esm/clients/SpokePoolClient/EVMSpokePoolClient.js +133 -178
- package/dist/esm/clients/SpokePoolClient/EVMSpokePoolClient.js.map +1 -1
- package/dist/esm/clients/SpokePoolClient/SVMSpokePoolClient.js +126 -183
- package/dist/esm/clients/SpokePoolClient/SVMSpokePoolClient.js.map +1 -1
- package/dist/esm/clients/SpokePoolClient/SpokePoolClient.js +372 -399
- package/dist/esm/clients/SpokePoolClient/SpokePoolClient.js.map +1 -1
- package/dist/esm/clients/SpokePoolClient/SpokePoolClientManager.js +9 -9
- package/dist/esm/clients/SpokePoolClient/SpokePoolClientManager.js.map +1 -1
- package/dist/esm/clients/SpokePoolClient/index.js +2 -2
- package/dist/esm/clients/SpokePoolClient/index.js.map +1 -1
- package/dist/esm/clients/SpokePoolClient/types.js +2 -2
- package/dist/esm/clients/SpokePoolClient/types.js.map +1 -1
- package/dist/esm/clients/mocks/MockConfigStoreClient.js +53 -64
- package/dist/esm/clients/mocks/MockConfigStoreClient.js.map +1 -1
- package/dist/esm/clients/mocks/MockEvents.js +42 -49
- package/dist/esm/clients/mocks/MockEvents.js.map +1 -1
- package/dist/esm/clients/mocks/MockHubPoolClient.js +138 -182
- package/dist/esm/clients/mocks/MockHubPoolClient.js.map +1 -1
- package/dist/esm/clients/mocks/MockSpokePoolClient.js +202 -188
- package/dist/esm/clients/mocks/MockSpokePoolClient.js.map +1 -1
- package/dist/esm/clients/mocks/MockSvmCpiEventsClient.js +127 -132
- package/dist/esm/clients/mocks/MockSvmCpiEventsClient.js.map +1 -1
- package/dist/esm/clients/mocks/MockSvmSpokePoolClient.js +53 -69
- package/dist/esm/clients/mocks/MockSvmSpokePoolClient.js.map +1 -1
- package/dist/esm/coingecko/Coingecko.js +298 -443
- package/dist/esm/coingecko/Coingecko.js.map +1 -1
- package/dist/esm/constants.js +40 -46
- package/dist/esm/constants.js.map +1 -1
- package/dist/esm/contracts/acrossConfigStore.js +24 -46
- package/dist/esm/contracts/acrossConfigStore.js.map +1 -1
- package/dist/esm/contracts/hubPool.js +34 -18
- package/dist/esm/contracts/hubPool.js.map +1 -1
- package/dist/esm/contracts/utils.js +3 -5
- package/dist/esm/contracts/utils.js.map +1 -1
- package/dist/esm/gasPriceOracle/adapters/arbitrum.js +6 -14
- package/dist/esm/gasPriceOracle/adapters/arbitrum.js.map +1 -1
- package/dist/esm/gasPriceOracle/adapters/ethereum.js +22 -42
- package/dist/esm/gasPriceOracle/adapters/ethereum.js.map +1 -1
- package/dist/esm/gasPriceOracle/adapters/linea-viem.js +13 -25
- package/dist/esm/gasPriceOracle/adapters/linea-viem.js.map +1 -1
- package/dist/esm/gasPriceOracle/adapters/polygon.js +72 -108
- package/dist/esm/gasPriceOracle/adapters/polygon.js.map +1 -1
- package/dist/esm/gasPriceOracle/adapters/solana.js +22 -31
- package/dist/esm/gasPriceOracle/adapters/solana.js.map +1 -1
- package/dist/esm/gasPriceOracle/oracle.js +70 -95
- package/dist/esm/gasPriceOracle/oracle.js.map +1 -1
- package/dist/esm/gasPriceOracle/types.js +2 -2
- package/dist/esm/gasPriceOracle/types.js.map +1 -1
- package/dist/esm/gasPriceOracle/util.js +4 -4
- package/dist/esm/gasPriceOracle/util.js.map +1 -1
- package/dist/esm/lpFeeCalculator/lpFeeCalculator.js +30 -33
- package/dist/esm/lpFeeCalculator/lpFeeCalculator.js.map +1 -1
- package/dist/esm/lpFeeCalculator/rateModel.js +7 -9
- package/dist/esm/lpFeeCalculator/rateModel.js.map +1 -1
- package/dist/esm/merkleDistributor/MerkleDistributor.js +18 -17
- package/dist/esm/merkleDistributor/MerkleDistributor.js.map +1 -1
- package/dist/esm/pool/TransactionManager.js +45 -100
- package/dist/esm/pool/TransactionManager.js.map +1 -1
- package/dist/esm/pool/poolClient.js +479 -740
- package/dist/esm/pool/poolClient.js.map +1 -1
- package/dist/esm/pool/uma/across/constants.js +2 -2
- package/dist/esm/pool/uma/across/constants.js.map +1 -1
- package/dist/esm/pool/uma/across/transactionManager.js +45 -100
- package/dist/esm/pool/uma/across/transactionManager.js.map +1 -1
- package/dist/esm/pool/uma/clients/erc20/client.js +15 -13
- package/dist/esm/pool/uma/clients/erc20/client.js.map +1 -1
- package/dist/esm/pool/uma/oracle/utils.js +2 -3
- package/dist/esm/pool/uma/oracle/utils.js.map +1 -1
- package/dist/esm/pool/uma/utils.js +9 -28
- package/dist/esm/pool/uma/utils.js.map +1 -1
- package/dist/esm/priceClient/adapters/acrossApi.js +21 -40
- package/dist/esm/priceClient/adapters/acrossApi.js.map +1 -1
- package/dist/esm/priceClient/adapters/baseAdapter.js +46 -72
- package/dist/esm/priceClient/adapters/baseAdapter.js.map +1 -1
- package/dist/esm/priceClient/adapters/coingecko.js +33 -61
- package/dist/esm/priceClient/adapters/coingecko.js.map +1 -1
- package/dist/esm/priceClient/adapters/default.js +15 -31
- package/dist/esm/priceClient/adapters/default.js.map +1 -1
- package/dist/esm/priceClient/adapters/defiLlama.js +38 -73
- package/dist/esm/priceClient/adapters/defiLlama.js.map +1 -1
- package/dist/esm/priceClient/priceClient.js +109 -158
- package/dist/esm/priceClient/priceClient.js.map +1 -1
- package/dist/esm/providers/alchemy.js +16 -18
- package/dist/esm/providers/alchemy.js.map +1 -1
- package/dist/esm/providers/cachedProvider.js +99 -134
- package/dist/esm/providers/cachedProvider.js.map +1 -1
- package/dist/esm/providers/constants.js +3 -3
- package/dist/esm/providers/constants.js.map +1 -1
- package/dist/esm/providers/drpc.js +8 -10
- package/dist/esm/providers/drpc.js.map +1 -1
- package/dist/esm/providers/infura.js +9 -11
- package/dist/esm/providers/infura.js.map +1 -1
- package/dist/esm/providers/mocks/MockCachedSolanaRpcFactory.js +6 -15
- package/dist/esm/providers/mocks/MockCachedSolanaRpcFactory.js.map +1 -1
- package/dist/esm/providers/mocks/MockRateLimitedSolanaRpcFactory.js +5 -14
- package/dist/esm/providers/mocks/MockRateLimitedSolanaRpcFactory.js.map +1 -1
- package/dist/esm/providers/mocks/MockRetrySolanaRpcFactory.js +6 -15
- package/dist/esm/providers/mocks/MockRetrySolanaRpcFactory.js.map +1 -1
- package/dist/esm/providers/mocks/MockSolanaRpcFactory.js +41 -66
- package/dist/esm/providers/mocks/MockSolanaRpcFactory.js.map +1 -1
- package/dist/esm/providers/mocks/mockEthersProvider.js +27 -30
- package/dist/esm/providers/mocks/mockEthersProvider.js.map +1 -1
- package/dist/esm/providers/quicknode.js +18 -20
- package/dist/esm/providers/quicknode.js.map +1 -1
- package/dist/esm/providers/rateLimitedProvider.js +68 -80
- package/dist/esm/providers/rateLimitedProvider.js.map +1 -1
- package/dist/esm/providers/retryProvider.js +186 -259
- package/dist/esm/providers/retryProvider.js.map +1 -1
- package/dist/esm/providers/solana/baseRpcFactories.js +13 -19
- package/dist/esm/providers/solana/baseRpcFactories.js.map +1 -1
- package/dist/esm/providers/solana/cachedRpcFactory.js +75 -112
- package/dist/esm/providers/solana/cachedRpcFactory.js.map +1 -1
- package/dist/esm/providers/solana/defaultRpcFactory.js +6 -14
- package/dist/esm/providers/solana/defaultRpcFactory.js.map +1 -1
- package/dist/esm/providers/solana/quorumFallbackRpcFactory.js +149 -202
- package/dist/esm/providers/solana/quorumFallbackRpcFactory.js.map +1 -1
- package/dist/esm/providers/solana/rateLimitedRpcFactory.js +70 -90
- package/dist/esm/providers/solana/rateLimitedRpcFactory.js.map +1 -1
- package/dist/esm/providers/solana/retryRpcFactory.js +50 -74
- package/dist/esm/providers/solana/retryRpcFactory.js.map +1 -1
- package/dist/esm/providers/solana/utils.js +1 -1
- package/dist/esm/providers/solana/utils.js.map +1 -1
- package/dist/esm/providers/speedProvider.js +28 -51
- package/dist/esm/providers/speedProvider.js.map +1 -1
- package/dist/esm/providers/types.js +2 -2
- package/dist/esm/providers/types.js.map +1 -1
- package/dist/esm/providers/utils.js +17 -20
- package/dist/esm/providers/utils.js.map +1 -1
- package/dist/esm/relayFeeCalculator/chain-queries/baseQuery.js +98 -152
- package/dist/esm/relayFeeCalculator/chain-queries/baseQuery.js.map +1 -1
- package/dist/esm/relayFeeCalculator/chain-queries/customGasToken.js +13 -26
- package/dist/esm/relayFeeCalculator/chain-queries/customGasToken.js.map +1 -1
- package/dist/esm/relayFeeCalculator/chain-queries/factory.js +9 -19
- package/dist/esm/relayFeeCalculator/chain-queries/factory.js.map +1 -1
- package/dist/esm/relayFeeCalculator/chain-queries/svmQuery.js +83 -128
- package/dist/esm/relayFeeCalculator/chain-queries/svmQuery.js.map +1 -1
- package/dist/esm/relayFeeCalculator/relayFeeCalculator.js +211 -299
- package/dist/esm/relayFeeCalculator/relayFeeCalculator.js.map +1 -1
- package/dist/esm/typeguards/error.js +3 -5
- package/dist/esm/typeguards/error.js.map +1 -1
- package/dist/esm/utils/AddressUtils.js +115 -147
- package/dist/esm/utils/AddressUtils.js.map +1 -1
- package/dist/esm/utils/ArrayUtils.js +21 -78
- package/dist/esm/utils/ArrayUtils.js.map +1 -1
- package/dist/esm/utils/BigNumberUtils.js +11 -12
- package/dist/esm/utils/BigNumberUtils.js.map +1 -1
- package/dist/esm/utils/BlockExplorerUtils.js +19 -23
- package/dist/esm/utils/BlockExplorerUtils.js.map +1 -1
- package/dist/esm/utils/BlockFinder.js +2 -6
- package/dist/esm/utils/BlockFinder.js.map +1 -1
- package/dist/esm/utils/BlockUtils.js +31 -40
- package/dist/esm/utils/BlockUtils.js.map +1 -1
- package/dist/esm/utils/BundleUtils.js +21 -24
- package/dist/esm/utils/BundleUtils.js.map +1 -1
- package/dist/esm/utils/CCTPUtils.js +62 -123
- package/dist/esm/utils/CCTPUtils.js.map +1 -1
- package/dist/esm/utils/CachingUtils.js +17 -38
- package/dist/esm/utils/CachingUtils.js.map +1 -1
- package/dist/esm/utils/ContractUtils.js +3 -3
- package/dist/esm/utils/ContractUtils.js.map +1 -1
- package/dist/esm/utils/DepositUtils.js +121 -98
- package/dist/esm/utils/DepositUtils.js.map +1 -1
- package/dist/esm/utils/EventUtils.js +52 -69
- package/dist/esm/utils/EventUtils.js.map +1 -1
- package/dist/esm/utils/FormattingUtils.js +20 -26
- package/dist/esm/utils/FormattingUtils.js.map +1 -1
- package/dist/esm/utils/HyperLiquidUtils.js +8 -22
- package/dist/esm/utils/HyperLiquidUtils.js.map +1 -1
- package/dist/esm/utils/IPFSUtils.js +16 -35
- package/dist/esm/utils/IPFSUtils.js.map +1 -1
- package/dist/esm/utils/JSONUtils.js +4 -4
- package/dist/esm/utils/JSONUtils.js.map +1 -1
- package/dist/esm/utils/LogUtils.js +8 -12
- package/dist/esm/utils/LogUtils.js.map +1 -1
- package/dist/esm/utils/Multicall.js +50 -109
- package/dist/esm/utils/Multicall.js.map +1 -1
- package/dist/esm/utils/NetworkUtils.js +12 -21
- package/dist/esm/utils/NetworkUtils.js.map +1 -1
- package/dist/esm/utils/NumberUtils.js +1 -3
- package/dist/esm/utils/NumberUtils.js.map +1 -1
- package/dist/esm/utils/ObjectUtils.js +27 -41
- package/dist/esm/utils/ObjectUtils.js.map +1 -1
- package/dist/esm/utils/Profiler.js +77 -82
- package/dist/esm/utils/Profiler.js.map +1 -1
- package/dist/esm/utils/ReviverUtils.js +3 -7
- package/dist/esm/utils/ReviverUtils.js.map +1 -1
- package/dist/esm/utils/SpokeUtils.js +83 -78
- package/dist/esm/utils/SpokeUtils.js.map +1 -1
- package/dist/esm/utils/TokenUtils.js +33 -57
- package/dist/esm/utils/TokenUtils.js.map +1 -1
- package/dist/esm/utils/ValidatorUtils.js +4 -4
- package/dist/esm/utils/ValidatorUtils.js.map +1 -1
- package/dist/esm/utils/abi/index.js +10 -20
- package/dist/esm/utils/abi/index.js.map +1 -1
- package/dist/esm/utils/abi/typechain/factories/Multicall3__factory.js +8 -12
- package/dist/esm/utils/abi/typechain/factories/Multicall3__factory.js.map +1 -1
- package/dist/esm/utils/common.js +38 -52
- package/dist/esm/utils/common.js.map +1 -1
- package/package.json +2 -2
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { __assign, __awaiter, __generator, __rest, __spreadArray } from "tslib";
|
|
2
1
|
import { MessageTransmitterClient, SvmSpokeClient, TokenMessengerMinterClient } from "@across-protocol/contracts";
|
|
3
2
|
import { decodeFillStatusAccount, fetchState } from "@across-protocol/contracts/dist/src/svm/clients/SvmSpoke";
|
|
4
3
|
import { decodeMessageHeader } from "@across-protocol/contracts/dist/src/svm/web3-v1";
|
|
@@ -18,85 +17,63 @@ import { getEmergencyDeleteRootBundleRootBundleId, getNearestSlotTime, isEmergen
|
|
|
18
17
|
* @note: Average Solana slot duration is about 400-500ms. We can be conservative
|
|
19
18
|
* and choose 400 to ensure that the most slots get included in our ranges
|
|
20
19
|
*/
|
|
21
|
-
export
|
|
20
|
+
export const SLOT_DURATION_MS = 400;
|
|
22
21
|
export function getSlot(provider, commitment, logger) {
|
|
23
22
|
return _callGetSlotWithRetry(provider, commitment, logger);
|
|
24
23
|
}
|
|
25
|
-
function _callGetSlotWithRetry(provider, commitment, logger) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
commitment: commitment,
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
// TODO: Implement retry logic once we better understand how these errors look:
|
|
46
|
-
throw err_1;
|
|
47
|
-
case 3: return [2 /*return*/];
|
|
48
|
-
}
|
|
49
|
-
});
|
|
50
|
-
});
|
|
24
|
+
async function _callGetSlotWithRetry(provider, commitment, logger) {
|
|
25
|
+
try {
|
|
26
|
+
return await provider.getSlot({ commitment }).send();
|
|
27
|
+
}
|
|
28
|
+
catch (err) {
|
|
29
|
+
if (isSolanaError(err)) {
|
|
30
|
+
const { __code: code } = err.context;
|
|
31
|
+
logger?.debug({
|
|
32
|
+
at: "_getSlotWithRetry",
|
|
33
|
+
message: "Caught error from getSlot()",
|
|
34
|
+
code,
|
|
35
|
+
commitment,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
// TODO: Implement retry logic once we better understand how these errors look:
|
|
39
|
+
throw err;
|
|
40
|
+
}
|
|
51
41
|
}
|
|
52
42
|
/**
|
|
53
43
|
* Retrieves the chain time at a particular slot.
|
|
54
44
|
*/
|
|
55
|
-
export function getTimestampForSlot(provider, slotNumber, maxRetries, logger) {
|
|
56
|
-
if (maxRetries === void 0) { maxRetries = 2; }
|
|
45
|
+
export function getTimestampForSlot(provider, slotNumber, maxRetries = 2, logger) {
|
|
57
46
|
return _callGetTimestampForSlotWithRetry(provider, slotNumber, 0, maxRetries, logger);
|
|
58
47
|
}
|
|
59
|
-
function _callGetTimestampForSlotWithRetry(provider, slotNumber, retryAttempt, maxRetries, logger) {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
switch (code) {
|
|
82
|
-
case SVM_SLOT_SKIPPED:
|
|
83
|
-
case SVM_LONG_TERM_STORAGE_SLOT_SKIPPED:
|
|
84
|
-
// No block available for this slot; caller must decide on how to handle this.
|
|
85
|
-
return [2 /*return*/, undefined];
|
|
86
|
-
default: {
|
|
87
|
-
message = "Caught error from getBlockTime()";
|
|
88
|
-
logger === null || logger === void 0 ? void 0 : logger.debug({ at: at, message: message, errorCode: code, slot: slot, retryAttempt: retryAttempt, maxRetries: maxRetries });
|
|
89
|
-
throw new Error("Unhandled SVM getBlockTime() error for slot ".concat(slot, ": ").concat(code), { cause: err_2 });
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
return [3 /*break*/, 4];
|
|
93
|
-
case 4:
|
|
94
|
-
timestamp = Number(_timestamp);
|
|
95
|
-
assert(!isDefined(_timestamp) || BigInt(timestamp) === _timestamp, "Unexpected block timestamp for SVM slot ".concat(slot, ": ").concat(_timestamp));
|
|
96
|
-
return [2 /*return*/, timestamp];
|
|
48
|
+
async function _callGetTimestampForSlotWithRetry(provider, slotNumber, retryAttempt, maxRetries, logger) {
|
|
49
|
+
const slot = slotNumber.toString();
|
|
50
|
+
let _timestamp;
|
|
51
|
+
try {
|
|
52
|
+
// @note: getBlockTime receives a slot number, not a block number.
|
|
53
|
+
_timestamp = await provider.getBlockTime(slotNumber).send();
|
|
54
|
+
}
|
|
55
|
+
catch (err) {
|
|
56
|
+
if (!isSolanaError(err)) {
|
|
57
|
+
throw err;
|
|
58
|
+
}
|
|
59
|
+
const at = "getTimestampForSlot";
|
|
60
|
+
const { __code: code } = err.context;
|
|
61
|
+
switch (code) {
|
|
62
|
+
case SVM_SLOT_SKIPPED:
|
|
63
|
+
case SVM_LONG_TERM_STORAGE_SLOT_SKIPPED:
|
|
64
|
+
// No block available for this slot; caller must decide on how to handle this.
|
|
65
|
+
return undefined;
|
|
66
|
+
default: {
|
|
67
|
+
const message = "Caught error from getBlockTime()";
|
|
68
|
+
logger?.debug({ at, message, errorCode: code, slot, retryAttempt, maxRetries });
|
|
69
|
+
throw new Error(`Unhandled SVM getBlockTime() error for slot ${slot}: ${code}`, { cause: err });
|
|
97
70
|
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// _timestamp should be a BigInt or undefined. If not undefined, ensure that conversion to number does not truncate.
|
|
74
|
+
const timestamp = Number(_timestamp);
|
|
75
|
+
assert(!isDefined(_timestamp) || BigInt(timestamp) === _timestamp, `Unexpected block timestamp for SVM slot ${slot}: ${_timestamp}`);
|
|
76
|
+
return timestamp;
|
|
100
77
|
}
|
|
101
78
|
/**
|
|
102
79
|
* Returns the current fill deadline buffer.
|
|
@@ -104,18 +81,9 @@ function _callGetTimestampForSlotWithRetry(provider, slotNumber, retryAttempt, m
|
|
|
104
81
|
* @param statePda Spoke Pool's State PDA
|
|
105
82
|
* @returns fill deadline buffer
|
|
106
83
|
*/
|
|
107
|
-
export function getFillDeadline(provider, statePda) {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
return __generator(this, function (_a) {
|
|
111
|
-
switch (_a.label) {
|
|
112
|
-
case 0: return [4 /*yield*/, fetchState(provider, statePda)];
|
|
113
|
-
case 1:
|
|
114
|
-
state = _a.sent();
|
|
115
|
-
return [2 /*return*/, state.data.fillDeadlineBuffer];
|
|
116
|
-
}
|
|
117
|
-
});
|
|
118
|
-
});
|
|
84
|
+
export async function getFillDeadline(provider, statePda) {
|
|
85
|
+
const state = await fetchState(provider, statePda);
|
|
86
|
+
return state.data.fillDeadlineBuffer;
|
|
119
87
|
}
|
|
120
88
|
/**
|
|
121
89
|
* Finds the deposit id at a specific block number.
|
|
@@ -155,46 +123,36 @@ export function getDepositIdAtBlock(_contract, _blockTag) {
|
|
|
155
123
|
* @param secondsLookback - The number of seconds to look back for deposits (defaults to 2 days).
|
|
156
124
|
* @returns The deposit if found within the slot window, undefined otherwise
|
|
157
125
|
*/
|
|
158
|
-
export function findDeposit(
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
txnIndex = 0;
|
|
189
|
-
logIndex = 0;
|
|
190
|
-
blockNumber = Number(depositEvent.slot);
|
|
191
|
-
txnRef = depositEvent.signature.toString();
|
|
192
|
-
rawData = unwrapEventData(depositEvent.data, ["depositId", "outputAmount"]);
|
|
193
|
-
_a = unpackDepositEvent(__assign(__assign({}, rawData), { blockNumber: blockNumber, txnRef: txnRef, txnIndex: txnIndex, logIndex: logIndex }), CHAIN_IDs.SOLANA), originChainId = _a.originChainId, deposit = __rest(_a, ["originChainId"]);
|
|
194
|
-
return [2 /*return*/, __assign({}, deposit)];
|
|
195
|
-
}
|
|
196
|
-
});
|
|
197
|
-
});
|
|
126
|
+
export async function findDeposit(eventClient, depositId, logger, slot, secondsLookback = 2 * 24 * 60 * 60 // 2 days
|
|
127
|
+
) {
|
|
128
|
+
// We can only perform this search when we have a safe deposit ID.
|
|
129
|
+
if (isUnsafeDepositId(depositId)) {
|
|
130
|
+
throw new Error(`Cannot binary search for depositId ${depositId}`);
|
|
131
|
+
}
|
|
132
|
+
const provider = eventClient.getRpc();
|
|
133
|
+
const opts = undefined;
|
|
134
|
+
const { slot: currentSlot } = await getNearestSlotTime(provider, opts, logger);
|
|
135
|
+
// If no slot is provided, use the current slot
|
|
136
|
+
// If a slot is provided, ensure it's not in the future
|
|
137
|
+
const endSlot = slot !== undefined ? BigInt(Math.min(Number(slot), Number(currentSlot))) : currentSlot;
|
|
138
|
+
// Calculate start slot (approximately secondsLookback seconds earlier)
|
|
139
|
+
const slotsInElapsed = BigInt(Math.round((secondsLookback * 1000) / SLOT_DURATION_MS));
|
|
140
|
+
const startSlot = endSlot - slotsInElapsed;
|
|
141
|
+
// Query for the deposit events with this limited slot range. Filter by deposit id.
|
|
142
|
+
const depositEvent = (await eventClient.queryEvents("FundsDeposited", startSlot, endSlot))?.find((event) => depositId.eq(event.data.depositId));
|
|
143
|
+
// If no deposit event is found, return undefined
|
|
144
|
+
if (!depositEvent) {
|
|
145
|
+
return undefined;
|
|
146
|
+
}
|
|
147
|
+
const txnIndex = 0;
|
|
148
|
+
const logIndex = 0;
|
|
149
|
+
const blockNumber = Number(depositEvent.slot);
|
|
150
|
+
const txnRef = depositEvent.signature.toString();
|
|
151
|
+
const rawData = unwrapEventData(depositEvent.data, ["depositId", "outputAmount"]);
|
|
152
|
+
const { originChainId, ...deposit } = unpackDepositEvent({ ...rawData, blockNumber, txnRef, txnIndex, logIndex }, CHAIN_IDs.SOLANA);
|
|
153
|
+
return {
|
|
154
|
+
...deposit,
|
|
155
|
+
};
|
|
198
156
|
}
|
|
199
157
|
/**
|
|
200
158
|
* Resolves the fill status of a deposit at a specific slot or at the current confirmed one.
|
|
@@ -209,44 +167,33 @@ export function findDeposit(eventClient_1, depositId_1, logger_1, slot_1) {
|
|
|
209
167
|
* @param atHeight - (Optional) Specific slot number to query. Defaults to the latest confirmed slot.
|
|
210
168
|
* @returns The fill status for the deposit at the specified or current slot.
|
|
211
169
|
*/
|
|
212
|
-
export function relayFillStatus(programId, relayData, destinationChainId, svmEventsClient, logger, atHeight) {
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
// since PDAs can't be closed before the fill deadline.
|
|
240
|
-
else if (timestamp < relayData.fillDeadline) {
|
|
241
|
-
return [2 /*return*/, FillStatus.Unfilled];
|
|
242
|
-
}
|
|
243
|
-
_c.label = 3;
|
|
244
|
-
case 3:
|
|
245
|
-
// If status couldn't be determined from the PDA, or if a specific slot was requested, reconstruct from events.
|
|
246
|
-
return [2 /*return*/, resolveFillStatusFromPdaEvents(fillStatusPda, toSlot, svmEventsClient)];
|
|
247
|
-
}
|
|
248
|
-
});
|
|
249
|
-
});
|
|
170
|
+
export async function relayFillStatus(programId, relayData, destinationChainId, svmEventsClient, logger, atHeight) {
|
|
171
|
+
assert(chainIsSvm(destinationChainId), "Destination chain must be an SVM chain");
|
|
172
|
+
const provider = svmEventsClient.getRpc();
|
|
173
|
+
// Get fill status PDA using relayData
|
|
174
|
+
const fillStatusPda = await getFillStatusPda(programId, relayData, destinationChainId);
|
|
175
|
+
let toSlot = BigInt(atHeight ?? 0);
|
|
176
|
+
// If no specific slot is requested, try fetching the current status from the PDA
|
|
177
|
+
if (atHeight === undefined) {
|
|
178
|
+
const commitment = "confirmed";
|
|
179
|
+
const [fillStatusAccount, { slot: currentSlot, timestamp }] = await Promise.all([
|
|
180
|
+
fetchEncodedAccount(provider, fillStatusPda, { commitment }),
|
|
181
|
+
getNearestSlotTime(provider, { commitment }, logger),
|
|
182
|
+
]);
|
|
183
|
+
toSlot = currentSlot;
|
|
184
|
+
// If the PDA exists, return the stored fill status
|
|
185
|
+
if (fillStatusAccount.exists) {
|
|
186
|
+
const decodedAccountData = decodeFillStatusAccount(fillStatusAccount);
|
|
187
|
+
return decodedAccountData.data.status;
|
|
188
|
+
}
|
|
189
|
+
// If the PDA doesn't exist and the deadline hasn't passed yet, the deposit must be unfilled,
|
|
190
|
+
// since PDAs can't be closed before the fill deadline.
|
|
191
|
+
else if (timestamp < relayData.fillDeadline) {
|
|
192
|
+
return FillStatus.Unfilled;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
// If status couldn't be determined from the PDA, or if a specific slot was requested, reconstruct from events.
|
|
196
|
+
return resolveFillStatusFromPdaEvents(fillStatusPda, toSlot, svmEventsClient);
|
|
250
197
|
}
|
|
251
198
|
/**
|
|
252
199
|
* Resolves fill statuses for multiple deposits at a specific or latest confirmed slot,
|
|
@@ -260,92 +207,53 @@ export function relayFillStatus(programId, relayData, destinationChainId, svmEve
|
|
|
260
207
|
* @param atHeight (Optional) The slot number to query at. If omitted, queries the latest confirmed slot.
|
|
261
208
|
* @returns An array of fill statuses for the specified deposits at the requested slot (or at the current confirmed slot).
|
|
262
209
|
*/
|
|
263
|
-
export function fillStatusArray(programId, relayData, destinationChainId, svmEventsClient, logger, atHeight) {
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
return [4 /*yield*/, Promise.all(chunkedRelayData.map(function (relayDataChunk) {
|
|
275
|
-
return Promise.all(relayDataChunk.map(function (relayData) { return getFillStatusPda(programId, relayData, destinationChainId); }));
|
|
276
|
-
}))];
|
|
277
|
-
case 1:
|
|
278
|
-
fillStatusPdas = (_c.sent()).flat();
|
|
279
|
-
if (atHeight !== undefined && logger) {
|
|
280
|
-
logger.warn({
|
|
281
|
-
at: "SvmSpokeUtils#fillStatusArray",
|
|
282
|
-
message: "Querying specific slots for large arrays is slow. For current status, omit 'atHeight' param to use latest confirmed slot instead.",
|
|
283
|
-
});
|
|
284
|
-
}
|
|
285
|
-
if (!(atHeight === undefined)) return [3 /*break*/, 3];
|
|
286
|
-
return [4 /*yield*/, fetchBatchFillStatusFromPdaAccounts(provider, fillStatusPdas, relayData, logger)];
|
|
287
|
-
case 2:
|
|
288
|
-
_a = _c.sent();
|
|
289
|
-
return [3 /*break*/, 4];
|
|
290
|
-
case 3:
|
|
291
|
-
_a = new Array(relayData.length).fill(undefined);
|
|
292
|
-
_c.label = 4;
|
|
293
|
-
case 4:
|
|
294
|
-
fillStatuses = _a;
|
|
295
|
-
missingStatuses = fillStatuses.reduce(function (acc, status, index) {
|
|
296
|
-
if (status === undefined) {
|
|
297
|
-
acc.push(index);
|
|
298
|
-
}
|
|
299
|
-
return acc;
|
|
300
|
-
}, []);
|
|
301
|
-
missingChunked = chunk(missingStatuses, chunkSize);
|
|
302
|
-
missingResults = [];
|
|
303
|
-
opts = undefined;
|
|
304
|
-
if (!atHeight) return [3 /*break*/, 5];
|
|
305
|
-
_b = BigInt(atHeight);
|
|
306
|
-
return [3 /*break*/, 7];
|
|
307
|
-
case 5: return [4 /*yield*/, getNearestSlotTime(provider, opts, logger)];
|
|
308
|
-
case 6:
|
|
309
|
-
_b = (_c.sent()).slot;
|
|
310
|
-
_c.label = 7;
|
|
311
|
-
case 7:
|
|
312
|
-
toSlot = _b;
|
|
313
|
-
_i = 0, missingChunked_1 = missingChunked;
|
|
314
|
-
_c.label = 8;
|
|
315
|
-
case 8:
|
|
316
|
-
if (!(_i < missingChunked_1.length)) return [3 /*break*/, 11];
|
|
317
|
-
chunk_1 = missingChunked_1[_i];
|
|
318
|
-
return [4 /*yield*/, Promise.all(chunk_1.map(function (missingIndex) { return __awaiter(_this, void 0, void 0, function () {
|
|
319
|
-
var _a;
|
|
320
|
-
return __generator(this, function (_b) {
|
|
321
|
-
switch (_b.label) {
|
|
322
|
-
case 0:
|
|
323
|
-
_a = {
|
|
324
|
-
index: missingIndex
|
|
325
|
-
};
|
|
326
|
-
return [4 /*yield*/, resolveFillStatusFromPdaEvents(fillStatusPdas[missingIndex], toSlot, svmEventsClient)];
|
|
327
|
-
case 1: return [2 /*return*/, (_a.fillStatus = _b.sent(),
|
|
328
|
-
_a)];
|
|
329
|
-
}
|
|
330
|
-
});
|
|
331
|
-
}); }))];
|
|
332
|
-
case 9:
|
|
333
|
-
chunkResults = _c.sent();
|
|
334
|
-
missingResults.push.apply(missingResults, chunkResults);
|
|
335
|
-
_c.label = 10;
|
|
336
|
-
case 10:
|
|
337
|
-
_i++;
|
|
338
|
-
return [3 /*break*/, 8];
|
|
339
|
-
case 11:
|
|
340
|
-
// Fill in missing statuses back to the result array
|
|
341
|
-
missingResults.forEach(function (_a) {
|
|
342
|
-
var index = _a.index, fillStatus = _a.fillStatus;
|
|
343
|
-
fillStatuses[index] = fillStatus;
|
|
344
|
-
});
|
|
345
|
-
return [2 /*return*/, fillStatuses];
|
|
346
|
-
}
|
|
210
|
+
export async function fillStatusArray(programId, relayData, destinationChainId, svmEventsClient, logger, atHeight) {
|
|
211
|
+
assert(chainIsSvm(destinationChainId), "Destination chain must be an SVM chain");
|
|
212
|
+
const provider = svmEventsClient.getRpc();
|
|
213
|
+
const chunkSize = 100;
|
|
214
|
+
const chunkedRelayData = chunk(relayData, chunkSize);
|
|
215
|
+
// Get all PDAs
|
|
216
|
+
const fillStatusPdas = (await Promise.all(chunkedRelayData.map((relayDataChunk) => Promise.all(relayDataChunk.map((relayData) => getFillStatusPda(programId, relayData, destinationChainId)))))).flat();
|
|
217
|
+
if (atHeight !== undefined && logger) {
|
|
218
|
+
logger.warn({
|
|
219
|
+
at: "SvmSpokeUtils#fillStatusArray",
|
|
220
|
+
message: "Querying specific slots for large arrays is slow. For current status, omit 'atHeight' param to use latest confirmed slot instead.",
|
|
347
221
|
});
|
|
222
|
+
}
|
|
223
|
+
// If no specific slot is requested, try fetching current statuses from PDAs
|
|
224
|
+
// Otherwise, initialize all statuses as undefined
|
|
225
|
+
const fillStatuses = atHeight === undefined
|
|
226
|
+
? await fetchBatchFillStatusFromPdaAccounts(provider, fillStatusPdas, relayData, logger)
|
|
227
|
+
: new Array(relayData.length).fill(undefined);
|
|
228
|
+
// Collect indices of deposits that still need their status resolved
|
|
229
|
+
const missingStatuses = fillStatuses.reduce((acc, status, index) => {
|
|
230
|
+
if (status === undefined) {
|
|
231
|
+
acc.push(index);
|
|
232
|
+
}
|
|
233
|
+
return acc;
|
|
234
|
+
}, []);
|
|
235
|
+
// Chunk the missing deposits for batch processing
|
|
236
|
+
const missingChunked = chunk(missingStatuses, chunkSize);
|
|
237
|
+
const missingResults = [];
|
|
238
|
+
// Determine the toSlot to use for event reconstruction
|
|
239
|
+
const opts = undefined;
|
|
240
|
+
const toSlot = atHeight ? BigInt(atHeight) : (await getNearestSlotTime(provider, opts, logger)).slot;
|
|
241
|
+
// @note: This path is mostly used for deposits past their fill deadline.
|
|
242
|
+
// If it becomes a bottleneck, consider returning an "Unknown" status that can be handled downstream.
|
|
243
|
+
for (const chunk of missingChunked) {
|
|
244
|
+
const chunkResults = await Promise.all(chunk.map(async (missingIndex) => {
|
|
245
|
+
return {
|
|
246
|
+
index: missingIndex,
|
|
247
|
+
fillStatus: await resolveFillStatusFromPdaEvents(fillStatusPdas[missingIndex], toSlot, svmEventsClient),
|
|
248
|
+
};
|
|
249
|
+
}));
|
|
250
|
+
missingResults.push(...chunkResults);
|
|
251
|
+
}
|
|
252
|
+
// Fill in missing statuses back to the result array
|
|
253
|
+
missingResults.forEach(({ index, fillStatus }) => {
|
|
254
|
+
fillStatuses[index] = fillStatus;
|
|
348
255
|
});
|
|
256
|
+
return fillStatuses;
|
|
349
257
|
}
|
|
350
258
|
/**
|
|
351
259
|
* Finds the `FilledRelay` event for a given deposit within the provided slot range.
|
|
@@ -357,43 +265,23 @@ export function fillStatusArray(programId, relayData, destinationChainId, svmEve
|
|
|
357
265
|
* @param toSlot (Optional) Ending slot to search. If not provided, the current confirmed slot will be used.
|
|
358
266
|
* @returns The fill event with block info, or `undefined` if not found.
|
|
359
267
|
*/
|
|
360
|
-
export function findFillEvent(relayData, destinationChainId, svmEventsClient, fromSlot, toSlot, logger) {
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
case 3:
|
|
378
|
-
_a;
|
|
379
|
-
programId = svmEventsClient.getProgramAddress();
|
|
380
|
-
return [4 /*yield*/, getFillStatusPda(programId, relayData, destinationChainId)];
|
|
381
|
-
case 4:
|
|
382
|
-
fillStatusPda = _c.sent();
|
|
383
|
-
return [4 /*yield*/, svmEventsClient.queryDerivedAddressEvents(SVMEventNames.FilledRelay, fillStatusPda, BigInt(fromSlot), BigInt(toSlot), { limit: 10 })];
|
|
384
|
-
case 5:
|
|
385
|
-
fillEvents = _c.sent();
|
|
386
|
-
assert(fillEvents.length <= 1, "Expected at most one fill event for ".concat(fillStatusPda, ", got ").concat(fillEvents.length));
|
|
387
|
-
rawEvent = fillEvents[0];
|
|
388
|
-
if (!isDefined(rawEvent)) {
|
|
389
|
-
return [2 /*return*/];
|
|
390
|
-
}
|
|
391
|
-
rawFill = unwrapEventData(rawEvent.data, ["depositId", "inputAmount"]);
|
|
392
|
-
fill = unpackFillEvent(rawFill, destinationChainId);
|
|
393
|
-
return [2 /*return*/, fill];
|
|
394
|
-
}
|
|
395
|
-
});
|
|
396
|
-
});
|
|
268
|
+
export async function findFillEvent(relayData, destinationChainId, svmEventsClient, fromSlot, toSlot, logger) {
|
|
269
|
+
assert(chainIsSvm(destinationChainId), "Destination chain must be an SVM chain");
|
|
270
|
+
const opts = undefined;
|
|
271
|
+
toSlot ??= Number((await getNearestSlotTime(svmEventsClient.getRpc(), opts, logger)).slot);
|
|
272
|
+
// Get fillStatus PDA using relayData
|
|
273
|
+
const programId = svmEventsClient.getProgramAddress();
|
|
274
|
+
const fillStatusPda = await getFillStatusPda(programId, relayData, destinationChainId);
|
|
275
|
+
// Get fill events from fillStatus PDA
|
|
276
|
+
const fillEvents = await svmEventsClient.queryDerivedAddressEvents(SVMEventNames.FilledRelay, fillStatusPda, BigInt(fromSlot), BigInt(toSlot), { limit: 10 });
|
|
277
|
+
assert(fillEvents.length <= 1, `Expected at most one fill event for ${fillStatusPda}, got ${fillEvents.length}`);
|
|
278
|
+
const [rawEvent] = fillEvents;
|
|
279
|
+
if (!isDefined(rawEvent)) {
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
const rawFill = unwrapEventData(rawEvent.data, ["depositId", "inputAmount"]);
|
|
283
|
+
const fill = unpackFillEvent(rawFill, destinationChainId);
|
|
284
|
+
return fill;
|
|
397
285
|
}
|
|
398
286
|
/**
|
|
399
287
|
* @param spokePool Address (program ID) of the SvmSpoke.
|
|
@@ -402,45 +290,35 @@ export function findFillEvent(relayData, destinationChainId, svmEventsClient, fr
|
|
|
402
290
|
* @param repaymentChainId Optional repaymentChainId (defaults to destinationChainId).
|
|
403
291
|
* @returns An Ethers UnsignedTransaction instance.
|
|
404
292
|
*/
|
|
405
|
-
export function fillRelayInstruction(spokePool, relayData, signer, recipientTokenAccount, repaymentAddress, repaymentChainId) {
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
fillStatus: fillStatusPda,
|
|
435
|
-
eventAuthority: eventAuthority,
|
|
436
|
-
program: program,
|
|
437
|
-
relayHash: relayDataHash,
|
|
438
|
-
relayData: some(svmRelayData),
|
|
439
|
-
repaymentChainId: some(BigInt(repaymentChainId)),
|
|
440
|
-
repaymentAddress: some(toAddress(repaymentAddress)),
|
|
441
|
-
})];
|
|
442
|
-
}
|
|
443
|
-
});
|
|
293
|
+
export async function fillRelayInstruction(spokePool, relayData, signer, recipientTokenAccount, repaymentAddress, repaymentChainId) {
|
|
294
|
+
const program = toAddress(spokePool);
|
|
295
|
+
assert(repaymentAddress.isValidOn(repaymentChainId), `Invalid repayment address for chain ${repaymentChainId}: ${repaymentAddress.toNative()}.`);
|
|
296
|
+
const messageHash = getMessageHash(relayData.message);
|
|
297
|
+
const _relayDataHash = getRelayDataHash({ ...relayData, messageHash }, relayData.destinationChainId);
|
|
298
|
+
const relayDataHash = new Uint8Array(Buffer.from(_relayDataHash.slice(2), "hex"));
|
|
299
|
+
const relayer = SvmAddress.from(signer.address);
|
|
300
|
+
const [statePda, fillStatusPda, eventAuthority, delegatePda, relayerTokenAccount] = await Promise.all([
|
|
301
|
+
getStatePda(program),
|
|
302
|
+
getFillStatusPda(program, relayData, relayData.destinationChainId),
|
|
303
|
+
getEventAuthority(program),
|
|
304
|
+
getFillRelayDelegatePda(relayDataHash, BigInt(repaymentChainId), signer.address, program),
|
|
305
|
+
getAssociatedTokenAddress(relayer, relayData.outputToken),
|
|
306
|
+
]);
|
|
307
|
+
const svmRelayData = toSvmRelayData(relayData);
|
|
308
|
+
return SvmSpokeClient.getFillRelayInstruction({
|
|
309
|
+
signer,
|
|
310
|
+
state: statePda,
|
|
311
|
+
delegate: toAddress(SvmAddress.from(delegatePda.toString())),
|
|
312
|
+
mint: svmRelayData.outputToken,
|
|
313
|
+
relayerTokenAccount: relayerTokenAccount,
|
|
314
|
+
recipientTokenAccount: recipientTokenAccount,
|
|
315
|
+
fillStatus: fillStatusPda,
|
|
316
|
+
eventAuthority,
|
|
317
|
+
program,
|
|
318
|
+
relayHash: relayDataHash,
|
|
319
|
+
relayData: some(svmRelayData),
|
|
320
|
+
repaymentChainId: some(BigInt(repaymentChainId)),
|
|
321
|
+
repaymentAddress: some(toAddress(repaymentAddress)),
|
|
444
322
|
});
|
|
445
323
|
}
|
|
446
324
|
/**
|
|
@@ -464,70 +342,56 @@ export function createTokenAccountsInstruction(mint, relayer) {
|
|
|
464
342
|
* @param repaymentAddress Address to which repayment will go to on repaymentChainId
|
|
465
343
|
* @returns FillRelay transaction
|
|
466
344
|
*/
|
|
467
|
-
export function getFillRelayTx(spokePoolAddr, solanaClient, relayData, signer, repaymentChainId, repaymentAddress) {
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
systemProgram: SYSTEM_PROGRAM_ADDRESS,
|
|
518
|
-
eventAuthority: eventAuthority,
|
|
519
|
-
program: program,
|
|
520
|
-
relayHash: relayDataHash,
|
|
521
|
-
relayData: svmRelayData,
|
|
522
|
-
repaymentChainId: BigInt(repaymentChainId),
|
|
523
|
-
repaymentAddress: toAddress(repaymentAddress),
|
|
524
|
-
};
|
|
525
|
-
// Pass createRecipientAtaIfNeeded =true to the createFillInstruction function to create the recipient token account
|
|
526
|
-
// if it doesn't exist.
|
|
527
|
-
return [2 /*return*/, createFillInstruction(signer, solanaClient, fillInput, svmRelayData, mintInfo.data.decimals, !recipientAtaEncodedAccount.exists, remainingAccounts)];
|
|
528
|
-
}
|
|
529
|
-
});
|
|
530
|
-
});
|
|
345
|
+
export async function getFillRelayTx(spokePoolAddr, solanaClient, relayData, signer, repaymentChainId, repaymentAddress) {
|
|
346
|
+
const svmRelayData = toSvmRelayData(relayData);
|
|
347
|
+
assert(repaymentAddress.isValidOn(repaymentChainId), `getFillRelayTx: repayment address ${repaymentAddress} not valid on chain ${repaymentChainId})`);
|
|
348
|
+
const program = toAddress(spokePoolAddr);
|
|
349
|
+
const messageHash = getMessageHash(relayData.message);
|
|
350
|
+
const _relayDataHash = getRelayDataHash({ ...relayData, messageHash }, relayData.destinationChainId);
|
|
351
|
+
const relayDataHash = new Uint8Array(Buffer.from(_relayDataHash.slice(2), "hex"));
|
|
352
|
+
const [state, delegate, mintInfo, fillStatus, eventAuthority] = await Promise.all([
|
|
353
|
+
getStatePda(program),
|
|
354
|
+
getFillRelayDelegatePda(relayDataHash, BigInt(repaymentChainId), toAddress(repaymentAddress), program),
|
|
355
|
+
getMintInfo(solanaClient, svmRelayData.outputToken),
|
|
356
|
+
getFillStatusPda(program, relayData, relayData.destinationChainId),
|
|
357
|
+
getEventAuthority(program),
|
|
358
|
+
]);
|
|
359
|
+
const [recipientAta, relayerAta] = await Promise.all([
|
|
360
|
+
getAssociatedTokenAddress(relayData.recipient, relayData.outputToken, mintInfo.programAddress),
|
|
361
|
+
getAssociatedTokenAddress(SvmAddress.from(signer.address), relayData.outputToken, mintInfo.programAddress),
|
|
362
|
+
]);
|
|
363
|
+
const recipientAtaEncodedAccount = await fetchEncodedAccount(solanaClient, recipientAta);
|
|
364
|
+
// Add remaining accounts if the relayData has a non-empty message.
|
|
365
|
+
// @dev ! since in the context of creating a `fillRelayTx`, `relayData` must be defined.
|
|
366
|
+
const remainingAccounts = [];
|
|
367
|
+
if (relayData.message !== "0x") {
|
|
368
|
+
const acrossPlusMessage = deserializeMessage(relayData.message);
|
|
369
|
+
// The first `remainingAccount` _must_ be the handler address.
|
|
370
|
+
// https://github.com/across-protocol/contracts/blob/3310f8dc716407a5f97ef5fd2eae63df83251f2f/programs/svm-spoke/src/utils/message_utils.rs#L36.
|
|
371
|
+
remainingAccounts.push(getAccountMeta(acrossPlusMessage.handler, true));
|
|
372
|
+
remainingAccounts.push(...acrossPlusMessage.accounts.map((account, idx) => getAccountMeta(account, idx < acrossPlusMessage.accounts.length - acrossPlusMessage.read_only_len)));
|
|
373
|
+
}
|
|
374
|
+
const fillInput = {
|
|
375
|
+
signer: signer,
|
|
376
|
+
state,
|
|
377
|
+
delegate,
|
|
378
|
+
mint: svmRelayData.outputToken,
|
|
379
|
+
relayerTokenAccount: relayerAta,
|
|
380
|
+
recipientTokenAccount: recipientAta,
|
|
381
|
+
fillStatus,
|
|
382
|
+
tokenProgram: mintInfo.programAddress,
|
|
383
|
+
associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ADDRESS,
|
|
384
|
+
systemProgram: SYSTEM_PROGRAM_ADDRESS,
|
|
385
|
+
eventAuthority,
|
|
386
|
+
program,
|
|
387
|
+
relayHash: relayDataHash,
|
|
388
|
+
relayData: svmRelayData,
|
|
389
|
+
repaymentChainId: BigInt(repaymentChainId),
|
|
390
|
+
repaymentAddress: toAddress(repaymentAddress),
|
|
391
|
+
};
|
|
392
|
+
// Pass createRecipientAtaIfNeeded =true to the createFillInstruction function to create the recipient token account
|
|
393
|
+
// if it doesn't exist.
|
|
394
|
+
return createFillInstruction(signer, solanaClient, fillInput, svmRelayData, mintInfo.data.decimals, !recipientAtaEncodedAccount.exists, remainingAccounts);
|
|
531
395
|
}
|
|
532
396
|
/**
|
|
533
397
|
* Creates a fill instruction with an instruction params PDA as the relayData input.
|
|
@@ -539,69 +403,55 @@ export function getFillRelayTx(spokePoolAddr, solanaClient, relayData, signer, r
|
|
|
539
403
|
* @param repaymentAddress Address to which repayment will go to on repaymentChainId
|
|
540
404
|
* @returns FillRelay transaction
|
|
541
405
|
*/
|
|
542
|
-
export function getIPFillRelayTx(spokePoolAddr, solanaClient, relayData, signer, repaymentChainId, repaymentAddress) {
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
eventAuthority: eventAuthority,
|
|
592
|
-
program: program,
|
|
593
|
-
instructionParams: instructionParams,
|
|
594
|
-
relayHash: relayDataHash,
|
|
595
|
-
relayData: null,
|
|
596
|
-
repaymentChainId: null,
|
|
597
|
-
repaymentAddress: null,
|
|
598
|
-
};
|
|
599
|
-
// Pass createRecipientAtaIfNeeded =true to the createFillInstruction function to create the recipient token account
|
|
600
|
-
// if it doesn't exist.
|
|
601
|
-
return [2 /*return*/, createFillInstruction(signer, solanaClient, fillInput, { outputAmount: relayData.outputAmount.toBigInt(), recipient: toAddress(relayData.recipient) }, mintInfo.data.decimals, true, remainingAccounts)];
|
|
602
|
-
}
|
|
603
|
-
});
|
|
604
|
-
});
|
|
406
|
+
export async function getIPFillRelayTx(spokePoolAddr, solanaClient, relayData, signer, repaymentChainId, repaymentAddress) {
|
|
407
|
+
const program = toAddress(spokePoolAddr);
|
|
408
|
+
const _relayDataHash = getRelayDataHash({ ...relayData, messageHash: getMessageHash(relayData.message) }, relayData.destinationChainId);
|
|
409
|
+
const relayDataHash = new Uint8Array(Buffer.from(_relayDataHash.slice(2), "hex"));
|
|
410
|
+
const [state, delegate, instructionParams] = await Promise.all([
|
|
411
|
+
getStatePda(program),
|
|
412
|
+
getFillRelayDelegatePda(relayDataHash, BigInt(repaymentChainId), toAddress(repaymentAddress), program),
|
|
413
|
+
getInstructionParamsPda(program, signer.address),
|
|
414
|
+
]);
|
|
415
|
+
const mint = toAddress(relayData.outputToken);
|
|
416
|
+
const mintInfo = await getMintInfo(solanaClient, mint);
|
|
417
|
+
const [recipientAta, relayerAta, fillStatus, eventAuthority] = await Promise.all([
|
|
418
|
+
getAssociatedTokenAddress(relayData.recipient, relayData.outputToken, mintInfo.programAddress),
|
|
419
|
+
getAssociatedTokenAddress(SvmAddress.from(signer.address), relayData.outputToken, mintInfo.programAddress),
|
|
420
|
+
getFillStatusPda(program, relayData, relayData.destinationChainId),
|
|
421
|
+
getEventAuthority(program),
|
|
422
|
+
]);
|
|
423
|
+
// Add remaining accounts if the relayData has a non-empty message.
|
|
424
|
+
// @dev ! since in the context of creating a `fillRelayTx`, `relayData` must be defined.
|
|
425
|
+
const remainingAccounts = [];
|
|
426
|
+
if (relayData.message !== "0x") {
|
|
427
|
+
const acrossPlusMessage = deserializeMessage(relayData.message);
|
|
428
|
+
// The first `remainingAccount` _must_ be the handler address.
|
|
429
|
+
// https://github.com/across-protocol/contracts/blob/3310f8dc716407a5f97ef5fd2eae63df83251f2f/programs/svm-spoke/src/utils/message_utils.rs#L36.
|
|
430
|
+
remainingAccounts.push(getAccountMeta(acrossPlusMessage.handler, true));
|
|
431
|
+
remainingAccounts.push(...acrossPlusMessage.accounts.map((account, idx) => getAccountMeta(account, idx < acrossPlusMessage.accounts.length - acrossPlusMessage.read_only_len)));
|
|
432
|
+
}
|
|
433
|
+
const fillInput = {
|
|
434
|
+
signer: signer,
|
|
435
|
+
state,
|
|
436
|
+
delegate,
|
|
437
|
+
mint,
|
|
438
|
+
relayerTokenAccount: relayerAta,
|
|
439
|
+
recipientTokenAccount: recipientAta,
|
|
440
|
+
fillStatus,
|
|
441
|
+
tokenProgram: mintInfo.programAddress,
|
|
442
|
+
associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ADDRESS,
|
|
443
|
+
systemProgram: SYSTEM_PROGRAM_ADDRESS,
|
|
444
|
+
eventAuthority,
|
|
445
|
+
program,
|
|
446
|
+
instructionParams,
|
|
447
|
+
relayHash: relayDataHash,
|
|
448
|
+
relayData: null,
|
|
449
|
+
repaymentChainId: null,
|
|
450
|
+
repaymentAddress: null,
|
|
451
|
+
};
|
|
452
|
+
// Pass createRecipientAtaIfNeeded =true to the createFillInstruction function to create the recipient token account
|
|
453
|
+
// if it doesn't exist.
|
|
454
|
+
return createFillInstruction(signer, solanaClient, fillInput, { outputAmount: relayData.outputAmount.toBigInt(), recipient: toAddress(relayData.recipient) }, mintInfo.data.decimals, true, remainingAccounts);
|
|
605
455
|
}
|
|
606
456
|
/**
|
|
607
457
|
* Creates a fill instruction.
|
|
@@ -612,60 +462,38 @@ export function getIPFillRelayTx(spokePoolAddr, solanaClient, relayData, signer,
|
|
|
612
462
|
* @param createRecipientAta - Whether to create a recipient token account.
|
|
613
463
|
* @returns The fill instruction.
|
|
614
464
|
*/
|
|
615
|
-
export
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
switch (_c.label) {
|
|
627
|
-
case 0: return [4 /*yield*/, getMintInfo(solanaClient, fillInput.mint)];
|
|
628
|
-
case 1:
|
|
629
|
-
mintInfo = _c.sent();
|
|
630
|
-
approveIx = getApproveCheckedInstruction({
|
|
631
|
-
source: fillInput.relayerTokenAccount,
|
|
632
|
-
mint: fillInput.mint,
|
|
633
|
-
delegate: fillInput.delegate,
|
|
634
|
-
owner: fillInput.signer,
|
|
635
|
-
amount: relayData.outputAmount,
|
|
636
|
-
decimals: tokenDecimals,
|
|
637
|
-
}, {
|
|
638
|
-
programAddress: mintInfo.programAddress,
|
|
639
|
-
});
|
|
640
|
-
getCreateAssociatedTokenIx = function () {
|
|
641
|
-
return getCreateAssociatedTokenInstruction({
|
|
642
|
-
payer: signer,
|
|
643
|
-
owner: relayData.recipient,
|
|
644
|
-
mint: fillInput.mint,
|
|
645
|
-
ata: fillInput.recipientTokenAccount,
|
|
646
|
-
systemProgram: SYSTEM_PROGRAM_ADDRESS,
|
|
647
|
-
tokenProgram: fillInput.tokenProgram,
|
|
648
|
-
});
|
|
649
|
-
};
|
|
650
|
-
createFillIx = SvmSpokeClient.getFillRelayInstruction(fillInput);
|
|
651
|
-
// Add remaining accounts.
|
|
652
|
-
(_b = createFillIx.accounts).push.apply(_b, remainingAccounts);
|
|
653
|
-
_a = pipe;
|
|
654
|
-
return [4 /*yield*/, createDefaultTransaction(solanaClient, signer)];
|
|
655
|
-
case 2: return [2 /*return*/, _a.apply(void 0, [_c.sent(), function (tx) { return (createRecipientAta ? appendTransactionMessageInstruction(getCreateAssociatedTokenIx(), tx) : tx); },
|
|
656
|
-
function (tx) { return appendTransactionMessageInstruction(approveIx, tx); },
|
|
657
|
-
function (tx) { return appendTransactionMessageInstruction(createFillIx, tx); }])];
|
|
658
|
-
}
|
|
659
|
-
});
|
|
465
|
+
export const createFillInstruction = async (signer, solanaClient, fillInput, relayData, tokenDecimals, createRecipientAta = false, remainingAccounts = []) => {
|
|
466
|
+
const mintInfo = await getMintInfo(solanaClient, fillInput.mint);
|
|
467
|
+
const approveIx = getApproveCheckedInstruction({
|
|
468
|
+
source: fillInput.relayerTokenAccount,
|
|
469
|
+
mint: fillInput.mint,
|
|
470
|
+
delegate: fillInput.delegate,
|
|
471
|
+
owner: fillInput.signer,
|
|
472
|
+
amount: relayData.outputAmount,
|
|
473
|
+
decimals: tokenDecimals,
|
|
474
|
+
}, {
|
|
475
|
+
programAddress: mintInfo.programAddress,
|
|
660
476
|
});
|
|
477
|
+
const getCreateAssociatedTokenIx = () => getCreateAssociatedTokenInstruction({
|
|
478
|
+
payer: signer,
|
|
479
|
+
owner: relayData.recipient,
|
|
480
|
+
mint: fillInput.mint,
|
|
481
|
+
ata: fillInput.recipientTokenAccount,
|
|
482
|
+
systemProgram: SYSTEM_PROGRAM_ADDRESS,
|
|
483
|
+
tokenProgram: fillInput.tokenProgram,
|
|
484
|
+
});
|
|
485
|
+
const createFillIx = SvmSpokeClient.getFillRelayInstruction(fillInput);
|
|
486
|
+
// Add remaining accounts.
|
|
487
|
+
createFillIx.accounts.push(...remainingAccounts);
|
|
488
|
+
return pipe(await createDefaultTransaction(solanaClient, signer), (tx) => (createRecipientAta ? appendTransactionMessageInstruction(getCreateAssociatedTokenIx(), tx) : tx), (tx) => appendTransactionMessageInstruction(approveIx, tx), (tx) => appendTransactionMessageInstruction(createFillIx, tx));
|
|
661
489
|
};
|
|
662
490
|
export function deserializeMessage(_message) {
|
|
663
|
-
|
|
491
|
+
const message = new Uint8Array(Buffer.from(_message.startsWith("0x") ? _message.slice(2) : _message, "hex"));
|
|
664
492
|
// Add remaining accounts if the relayData has a non-empty message.
|
|
665
493
|
// @dev ! since in the context of creating a `fillRelayTx`, `relayData` must be defined.
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
494
|
+
const acrossPlusMessageDecoder = getAcrossPlusMessageDecoder();
|
|
495
|
+
const deserialized = acrossPlusMessageDecoder.decode(message);
|
|
496
|
+
const valueAmountMethod2 = extractValueAmount(message);
|
|
669
497
|
assert(deserialized.value_amount === valueAmountMethod2, "svm | deserializeMessage: Deserialization mismatch for value_amount");
|
|
670
498
|
return deserialized;
|
|
671
499
|
}
|
|
@@ -678,51 +506,28 @@ export function deserializeMessage(_message) {
|
|
|
678
506
|
* @param createVaultAtaIfNeeded - Whether to create a vault token account.
|
|
679
507
|
* @returns The deposit instruction.
|
|
680
508
|
*/
|
|
681
|
-
export
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
return __generator(this, function (_b) {
|
|
690
|
-
switch (_b.label) {
|
|
691
|
-
case 0:
|
|
692
|
-
getCreateAssociatedTokenIdempotentIx = function () {
|
|
693
|
-
return getCreateAssociatedTokenIdempotentInstruction({
|
|
694
|
-
payer: signer,
|
|
695
|
-
owner: depositInput.state,
|
|
696
|
-
mint: depositInput.mint,
|
|
697
|
-
ata: depositInput.vault,
|
|
698
|
-
systemProgram: depositInput.systemProgram,
|
|
699
|
-
tokenProgram: depositInput.tokenProgram,
|
|
700
|
-
});
|
|
701
|
-
};
|
|
702
|
-
return [4 /*yield*/, getMintInfo(solanaClient, depositInput.mint)];
|
|
703
|
-
case 1:
|
|
704
|
-
mintInfo = _b.sent();
|
|
705
|
-
approveIx = getApproveCheckedInstruction({
|
|
706
|
-
source: depositInput.depositorTokenAccount,
|
|
707
|
-
mint: depositInput.mint,
|
|
708
|
-
delegate: depositInput.delegate,
|
|
709
|
-
owner: depositInput.depositor,
|
|
710
|
-
amount: depositInput.inputAmount,
|
|
711
|
-
decimals: tokenDecimals,
|
|
712
|
-
}, {
|
|
713
|
-
programAddress: mintInfo.programAddress,
|
|
714
|
-
});
|
|
715
|
-
depositIx = SvmSpokeClient.getDepositInstruction(depositInput);
|
|
716
|
-
_a = pipe;
|
|
717
|
-
return [4 /*yield*/, createDefaultTransaction(solanaClient, signer)];
|
|
718
|
-
case 2: return [2 /*return*/, _a.apply(void 0, [_b.sent(), function (tx) {
|
|
719
|
-
return createVaultAtaIfNeeded ? appendTransactionMessageInstruction(getCreateAssociatedTokenIdempotentIx(), tx) : tx;
|
|
720
|
-
},
|
|
721
|
-
function (tx) { return appendTransactionMessageInstruction(approveIx, tx); },
|
|
722
|
-
function (tx) { return appendTransactionMessageInstruction(depositIx, tx); }])];
|
|
723
|
-
}
|
|
724
|
-
});
|
|
509
|
+
export const createDepositInstruction = async (signer, solanaClient, depositInput, tokenDecimals, createVaultAtaIfNeeded = true) => {
|
|
510
|
+
const getCreateAssociatedTokenIdempotentIx = () => getCreateAssociatedTokenIdempotentInstruction({
|
|
511
|
+
payer: signer,
|
|
512
|
+
owner: depositInput.state,
|
|
513
|
+
mint: depositInput.mint,
|
|
514
|
+
ata: depositInput.vault,
|
|
515
|
+
systemProgram: depositInput.systemProgram,
|
|
516
|
+
tokenProgram: depositInput.tokenProgram,
|
|
725
517
|
});
|
|
518
|
+
const mintInfo = await getMintInfo(solanaClient, depositInput.mint);
|
|
519
|
+
const approveIx = getApproveCheckedInstruction({
|
|
520
|
+
source: depositInput.depositorTokenAccount,
|
|
521
|
+
mint: depositInput.mint,
|
|
522
|
+
delegate: depositInput.delegate,
|
|
523
|
+
owner: depositInput.depositor,
|
|
524
|
+
amount: depositInput.inputAmount,
|
|
525
|
+
decimals: tokenDecimals,
|
|
526
|
+
}, {
|
|
527
|
+
programAddress: mintInfo.programAddress,
|
|
528
|
+
});
|
|
529
|
+
const depositIx = SvmSpokeClient.getDepositInstruction(depositInput);
|
|
530
|
+
return pipe(await createDefaultTransaction(solanaClient, signer), (tx) => createVaultAtaIfNeeded ? appendTransactionMessageInstruction(getCreateAssociatedTokenIdempotentIx(), tx) : tx, (tx) => appendTransactionMessageInstruction(approveIx, tx), (tx) => appendTransactionMessageInstruction(depositIx, tx));
|
|
726
531
|
};
|
|
727
532
|
/**
|
|
728
533
|
* Creates a request slow fill instruction.
|
|
@@ -731,20 +536,10 @@ export var createDepositInstruction = function (signer_1, solanaClient_1, deposi
|
|
|
731
536
|
* @param requestSlowFillInput - The input arguments for the `requestSlowFill` instruction.
|
|
732
537
|
* @returns The request slow fill instruction.
|
|
733
538
|
*/
|
|
734
|
-
export
|
|
735
|
-
|
|
736
|
-
return
|
|
737
|
-
|
|
738
|
-
case 0:
|
|
739
|
-
requestSlowFillIx = SvmSpokeClient.getRequestSlowFillInstruction(requestSlowFillInput);
|
|
740
|
-
_a = pipe;
|
|
741
|
-
return [4 /*yield*/, createDefaultTransaction(solanaClient, signer)];
|
|
742
|
-
case 1: return [2 /*return*/, _a.apply(void 0, [_b.sent(), function (tx) {
|
|
743
|
-
return appendTransactionMessageInstruction(requestSlowFillIx, tx);
|
|
744
|
-
}])];
|
|
745
|
-
}
|
|
746
|
-
});
|
|
747
|
-
}); };
|
|
539
|
+
export const createRequestSlowFillInstruction = async (signer, solanaClient, requestSlowFillInput) => {
|
|
540
|
+
const requestSlowFillIx = SvmSpokeClient.getRequestSlowFillInstruction(requestSlowFillInput);
|
|
541
|
+
return pipe(await createDefaultTransaction(solanaClient, signer), (tx) => appendTransactionMessageInstruction(requestSlowFillIx, tx));
|
|
542
|
+
};
|
|
748
543
|
/**
|
|
749
544
|
* @notice Return the requestSlowFill transaction for a given deposit
|
|
750
545
|
* @param spokePoolAddr Address of the spoke pool we're trying to fill through
|
|
@@ -753,37 +548,27 @@ export var createRequestSlowFillInstruction = function (signer, solanaClient, re
|
|
|
753
548
|
* @param signer signer associated with the relayer creating a Fill.
|
|
754
549
|
* @returns requestSlowFill transaction
|
|
755
550
|
*/
|
|
756
|
-
export function getSlowFillRequestTx(spokePoolAddr, solanaClient, relayData, signer) {
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
eventAuthority: eventAuthority,
|
|
778
|
-
program: program,
|
|
779
|
-
relayHash: arrayify(relayDataHash),
|
|
780
|
-
relayData: svmRelayData,
|
|
781
|
-
systemProgram: SYSTEM_PROGRAM_ADDRESS,
|
|
782
|
-
};
|
|
783
|
-
return [2 /*return*/, createRequestSlowFillInstruction(signer, solanaClient, requestSlowFillInput)];
|
|
784
|
-
}
|
|
785
|
-
});
|
|
786
|
-
});
|
|
551
|
+
export async function getSlowFillRequestTx(spokePoolAddr, solanaClient, relayData, signer) {
|
|
552
|
+
const program = toAddress(spokePoolAddr);
|
|
553
|
+
const messageHash = getMessageHash(relayData.message);
|
|
554
|
+
const relayDataHash = getRelayDataHash({ ...relayData, messageHash }, relayData.destinationChainId);
|
|
555
|
+
const [state, fillStatus, eventAuthority] = await Promise.all([
|
|
556
|
+
getStatePda(program),
|
|
557
|
+
getFillStatusPda(program, relayData, relayData.destinationChainId),
|
|
558
|
+
getEventAuthority(program),
|
|
559
|
+
]);
|
|
560
|
+
const svmRelayData = toSvmRelayData(relayData);
|
|
561
|
+
const requestSlowFillInput = {
|
|
562
|
+
signer,
|
|
563
|
+
state,
|
|
564
|
+
fillStatus,
|
|
565
|
+
eventAuthority,
|
|
566
|
+
program,
|
|
567
|
+
relayHash: arrayify(relayDataHash),
|
|
568
|
+
relayData: svmRelayData,
|
|
569
|
+
systemProgram: SYSTEM_PROGRAM_ADDRESS,
|
|
570
|
+
};
|
|
571
|
+
return createRequestSlowFillInstruction(signer, solanaClient, requestSlowFillInput);
|
|
787
572
|
}
|
|
788
573
|
/**
|
|
789
574
|
* Creates a close fill PDA instruction.
|
|
@@ -792,116 +577,71 @@ export function getSlowFillRequestTx(spokePoolAddr, solanaClient, relayData, sig
|
|
|
792
577
|
* @param fillStatusPda - The fill status PDA.
|
|
793
578
|
* @returns The close fill PDA instruction.
|
|
794
579
|
*/
|
|
795
|
-
export
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
case 0:
|
|
801
|
-
_b = (_a = SvmSpokeClient).getCloseFillPdaInstruction;
|
|
802
|
-
_d = {
|
|
803
|
-
signer: signer
|
|
804
|
-
};
|
|
805
|
-
return [4 /*yield*/, getStatePda(SvmSpokeClient.SVM_SPOKE_PROGRAM_ADDRESS)];
|
|
806
|
-
case 1:
|
|
807
|
-
closeFillPdaIx = _b.apply(_a, [(_d.state = _e.sent(),
|
|
808
|
-
_d.fillStatus = fillStatusPda,
|
|
809
|
-
_d)]);
|
|
810
|
-
_c = pipe;
|
|
811
|
-
return [4 /*yield*/, createDefaultTransaction(solanaClient, signer)];
|
|
812
|
-
case 2: return [2 /*return*/, _c.apply(void 0, [_e.sent(), function (tx) {
|
|
813
|
-
return appendTransactionMessageInstruction(closeFillPdaIx, tx);
|
|
814
|
-
}])];
|
|
815
|
-
}
|
|
816
|
-
});
|
|
817
|
-
}); };
|
|
818
|
-
export var createReceiveMessageInstruction = function (signer, solanaClient, input, remainingAccounts) { return __awaiter(void 0, void 0, void 0, function () {
|
|
819
|
-
var receiveMessageIx, _a;
|
|
820
|
-
var _b;
|
|
821
|
-
return __generator(this, function (_c) {
|
|
822
|
-
switch (_c.label) {
|
|
823
|
-
case 0:
|
|
824
|
-
receiveMessageIx = MessageTransmitterClient.getReceiveMessageInstruction(input);
|
|
825
|
-
(_b = receiveMessageIx.accounts).push.apply(_b, remainingAccounts);
|
|
826
|
-
_a = pipe;
|
|
827
|
-
return [4 /*yield*/, createDefaultTransaction(solanaClient, signer)];
|
|
828
|
-
case 1: return [2 /*return*/, _a.apply(void 0, [_c.sent(), function (tx) {
|
|
829
|
-
return appendTransactionMessageInstruction(receiveMessageIx, tx);
|
|
830
|
-
}])];
|
|
831
|
-
}
|
|
580
|
+
export const createCloseFillPdaInstruction = async (signer, solanaClient, fillStatusPda) => {
|
|
581
|
+
const closeFillPdaIx = SvmSpokeClient.getCloseFillPdaInstruction({
|
|
582
|
+
signer,
|
|
583
|
+
state: await getStatePda(SvmSpokeClient.SVM_SPOKE_PROGRAM_ADDRESS),
|
|
584
|
+
fillStatus: fillStatusPda,
|
|
832
585
|
});
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
})];
|
|
846
|
-
case 1:
|
|
847
|
-
associatedToken = (_a.sent())[0];
|
|
848
|
-
return [2 /*return*/, associatedToken];
|
|
849
|
-
}
|
|
850
|
-
});
|
|
586
|
+
return pipe(await createDefaultTransaction(solanaClient, signer), (tx) => appendTransactionMessageInstruction(closeFillPdaIx, tx));
|
|
587
|
+
};
|
|
588
|
+
export const createReceiveMessageInstruction = async (signer, solanaClient, input, remainingAccounts) => {
|
|
589
|
+
const receiveMessageIx = MessageTransmitterClient.getReceiveMessageInstruction(input);
|
|
590
|
+
receiveMessageIx.accounts.push(...remainingAccounts);
|
|
591
|
+
return pipe(await createDefaultTransaction(solanaClient, signer), (tx) => appendTransactionMessageInstruction(receiveMessageIx, tx));
|
|
592
|
+
};
|
|
593
|
+
export async function getAssociatedTokenAddress(owner, mint, tokenProgramId = TOKEN_PROGRAM_ADDRESS) {
|
|
594
|
+
const encoder = getAddressEncoder();
|
|
595
|
+
const [associatedToken] = await getProgramDerivedAddress({
|
|
596
|
+
programAddress: ASSOCIATED_TOKEN_PROGRAM_ADDRESS,
|
|
597
|
+
seeds: [encoder.encode(toAddress(owner)), encoder.encode(tokenProgramId), encoder.encode(toAddress(mint))],
|
|
851
598
|
});
|
|
599
|
+
return associatedToken;
|
|
852
600
|
}
|
|
853
601
|
export function getRelayDataHash(relayData, destinationChainId) {
|
|
854
602
|
assert(relayData.messageHash.startsWith("0x"), "Message hash must be a hex string");
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
603
|
+
const uint64Encoder = getU64Encoder();
|
|
604
|
+
const svmRelayData = toSvmRelayData(relayData);
|
|
605
|
+
const relayDataEncoder = SvmSpokeClient.getRelayDataEncoder();
|
|
606
|
+
const encodedRelayData = relayDataEncoder.encode(svmRelayData);
|
|
607
|
+
const encodedMessage = Buffer.from(relayData.message.slice(2), "hex");
|
|
608
|
+
const encodedMessageHash = Uint8Array.from(Buffer.from(relayData.messageHash.slice(2), "hex"));
|
|
861
609
|
// Reformat the encoded relay data the same way it is done in the SvmSpoke:
|
|
862
610
|
// https://github.com/across-protocol/contracts/blob/3310f8dc716407a5f97ef5fd2eae63df83251f2f/programs/svm-spoke/src/utils/merkle_proof_utils.rs#L5
|
|
863
611
|
// We want to use messageHash always so we can construct the relayDataHash just from the Fill.
|
|
864
612
|
// If we don't have a message, we can just pass an empty message here.
|
|
865
|
-
|
|
866
|
-
|
|
613
|
+
const messageOffset = encodedRelayData.length - 4 - encodedMessage.length;
|
|
614
|
+
const contentToHash = Buffer.concat([
|
|
867
615
|
encodedRelayData.slice(0, messageOffset),
|
|
868
616
|
encodedMessageHash,
|
|
869
617
|
Uint8Array.from(uint64Encoder.encode(BigInt(destinationChainId))),
|
|
870
618
|
]);
|
|
871
619
|
return keccak256(contentToHash);
|
|
872
620
|
}
|
|
873
|
-
function resolveFillStatusFromPdaEvents(fillStatusPda, toSlot, svmEventsClient) {
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
return [2 /*return*/, FillStatus.RequestedSlowFill];
|
|
898
|
-
default:
|
|
899
|
-
throw new Error("Unexpected event name: ".concat(fillStatusEvent.name));
|
|
900
|
-
}
|
|
901
|
-
return [2 /*return*/];
|
|
902
|
-
}
|
|
903
|
-
});
|
|
904
|
-
});
|
|
621
|
+
async function resolveFillStatusFromPdaEvents(fillStatusPda, toSlot, svmEventsClient) {
|
|
622
|
+
// Get fill and requested slow fill events from fillStatus PDA
|
|
623
|
+
const eventsToQuery = [SVMEventNames.FilledRelay, SVMEventNames.RequestedSlowFill];
|
|
624
|
+
const relevantEvents = (await Promise.all(eventsToQuery.map((eventName) =>
|
|
625
|
+
// PDAs should have only a few events, requesting up to 10 should be enough.
|
|
626
|
+
svmEventsClient.queryDerivedAddressEvents(eventName, fillStatusPda, undefined, toSlot, { limit: 10 })))).flat();
|
|
627
|
+
if (relevantEvents.length === 0) {
|
|
628
|
+
// No fill or requested slow fill events found for this PDA
|
|
629
|
+
return FillStatus.Unfilled;
|
|
630
|
+
}
|
|
631
|
+
// Sort events in ascending order of slot number
|
|
632
|
+
relevantEvents.sort((a, b) => Number(a.slot - b.slot));
|
|
633
|
+
// At this point we have an ordered array of only fill and requested slow fill events and
|
|
634
|
+
// since it's not possible to submit a slow fill request once a fill has been submitted,
|
|
635
|
+
// we can use the last event in the list to determine the fill status at the requested slot.
|
|
636
|
+
const fillStatusEvent = relevantEvents.pop();
|
|
637
|
+
switch (fillStatusEvent.name) {
|
|
638
|
+
case SVMEventNames.FilledRelay:
|
|
639
|
+
return FillStatus.Filled;
|
|
640
|
+
case SVMEventNames.RequestedSlowFill:
|
|
641
|
+
return FillStatus.RequestedSlowFill;
|
|
642
|
+
default:
|
|
643
|
+
throw new Error(`Unexpected event name: ${fillStatusEvent.name}`);
|
|
644
|
+
}
|
|
905
645
|
}
|
|
906
646
|
/**
|
|
907
647
|
* Attempts to resolve the fill status for an array of deposits by reading their fillStatus PDAs.
|
|
@@ -916,38 +656,28 @@ function resolveFillStatusFromPdaEvents(fillStatusPda, toSlot, svmEventsClient)
|
|
|
916
656
|
* @param fillStatusPdas An array of fill status PDAs to retrieve the fill status for.
|
|
917
657
|
* @param relayData An array of relay data from which the fill status PDAs were derived.
|
|
918
658
|
*/
|
|
919
|
-
function fetchBatchFillStatusFromPdaAccounts(provider, fillStatusPdas, relayDataArray, logger) {
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
// If the PDA doesn't exist and the deadline hasn't passed yet, the deposit must be unfilled,
|
|
940
|
-
// since PDAs can't be closed before the fill deadline.
|
|
941
|
-
if (timestamp < relayDataArray[index].fillDeadline) {
|
|
942
|
-
return FillStatus.Unfilled;
|
|
943
|
-
}
|
|
944
|
-
// If the PDA doesn't exist and the fill deadline has passed, then the status can't be determined and is set to undefined.
|
|
945
|
-
return undefined;
|
|
946
|
-
});
|
|
947
|
-
return [2 /*return*/, fillStatuses];
|
|
948
|
-
}
|
|
949
|
-
});
|
|
659
|
+
async function fetchBatchFillStatusFromPdaAccounts(provider, fillStatusPdas, relayDataArray, logger) {
|
|
660
|
+
const chunkSize = 100; // SVM method getMultipleAccounts allows a max of 100 addresses per request
|
|
661
|
+
const commitment = "confirmed";
|
|
662
|
+
const [pdaAccounts, { timestamp }] = await Promise.all([
|
|
663
|
+
Promise.all(chunk(fillStatusPdas, chunkSize).map((chunk) => fetchEncodedAccounts(provider, chunk, { commitment }))),
|
|
664
|
+
getNearestSlotTime(provider, { commitment }, logger),
|
|
665
|
+
]);
|
|
666
|
+
const fillStatuses = pdaAccounts.flat().map((account, index) => {
|
|
667
|
+
// If the PDA exists, we can fetch the status directly.
|
|
668
|
+
if (account.exists) {
|
|
669
|
+
const decodedAccount = decodeFillStatusAccount(account);
|
|
670
|
+
return decodedAccount.data.status;
|
|
671
|
+
}
|
|
672
|
+
// If the PDA doesn't exist and the deadline hasn't passed yet, the deposit must be unfilled,
|
|
673
|
+
// since PDAs can't be closed before the fill deadline.
|
|
674
|
+
if (timestamp < relayDataArray[index].fillDeadline) {
|
|
675
|
+
return FillStatus.Unfilled;
|
|
676
|
+
}
|
|
677
|
+
// If the PDA doesn't exist and the fill deadline has passed, then the status can't be determined and is set to undefined.
|
|
678
|
+
return undefined;
|
|
950
679
|
});
|
|
680
|
+
return fillStatuses;
|
|
951
681
|
}
|
|
952
682
|
/**
|
|
953
683
|
* Returns a set of instructions to execute to fill a relay via instruction params.
|
|
@@ -956,149 +686,109 @@ function fetchBatchFillStatusFromPdaAccounts(provider, fillStatusPdas, relayData
|
|
|
956
686
|
* @param signer The transaction signer and authority of the instruction params PDA.
|
|
957
687
|
* @param maxWriteSize The maximum fragment size to write to instruction params.
|
|
958
688
|
*/
|
|
959
|
-
export function getFillRelayViaInstructionParamsInstructions(
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
instructionParams = _a.sent();
|
|
968
|
-
relayDataEncoder = SvmSpokeClient.getFillRelayParamsEncoder();
|
|
969
|
-
svmRelayData = toSvmRelayData(relayData);
|
|
970
|
-
encodedRelayData = relayDataEncoder.encode({
|
|
971
|
-
relayData: svmRelayData,
|
|
972
|
-
repaymentChainId: repaymentChainId,
|
|
973
|
-
repaymentAddress: toAddress(repaymentAddress),
|
|
974
|
-
});
|
|
975
|
-
initInstructionParamsIx = SvmSpokeClient.getInitializeInstructionParamsInstruction({
|
|
976
|
-
signer: signer,
|
|
977
|
-
instructionParams: instructionParams,
|
|
978
|
-
totalSize: encodedRelayData.length,
|
|
979
|
-
});
|
|
980
|
-
instructions = [initInstructionParamsIx];
|
|
981
|
-
for (i = 0; i <= encodedRelayData.length / maxWriteSize; ++i) {
|
|
982
|
-
offset = i * maxWriteSize;
|
|
983
|
-
offsetEnd = Math.min(offset + maxWriteSize, encodedRelayData.length);
|
|
984
|
-
fragment = encodedRelayData.slice(offset, offsetEnd);
|
|
985
|
-
writeInstructionParamsIx = SvmSpokeClient.getWriteInstructionParamsFragmentInstruction({
|
|
986
|
-
signer: signer,
|
|
987
|
-
instructionParams: instructionParams,
|
|
988
|
-
offset: offset,
|
|
989
|
-
fragment: fragment,
|
|
990
|
-
});
|
|
991
|
-
instructions.push(writeInstructionParamsIx);
|
|
992
|
-
}
|
|
993
|
-
return [2 /*return*/, instructions];
|
|
994
|
-
}
|
|
995
|
-
});
|
|
689
|
+
export async function getFillRelayViaInstructionParamsInstructions(spokePool, relayData, repaymentChainId, repaymentAddress, signer, maxWriteSize = 450) {
|
|
690
|
+
const instructionParams = await getInstructionParamsPda(spokePool, signer.address);
|
|
691
|
+
const relayDataEncoder = SvmSpokeClient.getFillRelayParamsEncoder();
|
|
692
|
+
const svmRelayData = toSvmRelayData(relayData);
|
|
693
|
+
const encodedRelayData = relayDataEncoder.encode({
|
|
694
|
+
relayData: svmRelayData,
|
|
695
|
+
repaymentChainId,
|
|
696
|
+
repaymentAddress: toAddress(repaymentAddress),
|
|
996
697
|
});
|
|
698
|
+
const initInstructionParamsIx = SvmSpokeClient.getInitializeInstructionParamsInstruction({
|
|
699
|
+
signer,
|
|
700
|
+
instructionParams,
|
|
701
|
+
totalSize: encodedRelayData.length,
|
|
702
|
+
});
|
|
703
|
+
const instructions = [initInstructionParamsIx];
|
|
704
|
+
for (let i = 0; i <= encodedRelayData.length / maxWriteSize; ++i) {
|
|
705
|
+
const offset = i * maxWriteSize;
|
|
706
|
+
const offsetEnd = Math.min(offset + maxWriteSize, encodedRelayData.length);
|
|
707
|
+
const fragment = encodedRelayData.slice(offset, offsetEnd);
|
|
708
|
+
const writeInstructionParamsIx = SvmSpokeClient.getWriteInstructionParamsFragmentInstruction({
|
|
709
|
+
signer,
|
|
710
|
+
instructionParams,
|
|
711
|
+
offset,
|
|
712
|
+
fragment,
|
|
713
|
+
});
|
|
714
|
+
instructions.push(writeInstructionParamsIx);
|
|
715
|
+
}
|
|
716
|
+
return instructions;
|
|
997
717
|
}
|
|
998
718
|
/**
|
|
999
719
|
* Returns the delegate PDA for deposit.
|
|
1000
720
|
*/
|
|
1001
|
-
export function getDepositDelegatePda(depositData, programId) {
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
];
|
|
1025
|
-
seedHash = Buffer.from(keccak256(Buffer.concat(parts)).slice(2), "hex");
|
|
1026
|
-
return [4 /*yield*/, getProgramDerivedAddress({
|
|
1027
|
-
programAddress: programId,
|
|
1028
|
-
seeds: [Buffer.from("delegate"), seedHash],
|
|
1029
|
-
})];
|
|
1030
|
-
case 1:
|
|
1031
|
-
pda = (_a.sent())[0];
|
|
1032
|
-
return [2 /*return*/, pda];
|
|
1033
|
-
}
|
|
1034
|
-
});
|
|
721
|
+
export async function getDepositDelegatePda(depositData, programId) {
|
|
722
|
+
const addrEnc = getAddressEncoder();
|
|
723
|
+
const u64 = getU64Encoder();
|
|
724
|
+
const u32 = getU32Encoder();
|
|
725
|
+
const parts = [
|
|
726
|
+
Uint8Array.from(addrEnc.encode(depositData.depositor)),
|
|
727
|
+
Uint8Array.from(addrEnc.encode(depositData.recipient)),
|
|
728
|
+
Uint8Array.from(addrEnc.encode(depositData.inputToken)),
|
|
729
|
+
Uint8Array.from(addrEnc.encode(depositData.outputToken)),
|
|
730
|
+
Uint8Array.from(u64.encode(depositData.inputAmount)),
|
|
731
|
+
Uint8Array.from(depositData.outputAmount),
|
|
732
|
+
Uint8Array.from(u64.encode(depositData.destinationChainId)),
|
|
733
|
+
Uint8Array.from(addrEnc.encode(depositData.exclusiveRelayer)),
|
|
734
|
+
Uint8Array.from(u32.encode(depositData.quoteTimestamp)),
|
|
735
|
+
Uint8Array.from(u32.encode(depositData.fillDeadline)),
|
|
736
|
+
Uint8Array.from(u32.encode(depositData.exclusivityParameter)),
|
|
737
|
+
Uint8Array.from(u32.encode(BigInt(depositData.message.length))),
|
|
738
|
+
depositData.message,
|
|
739
|
+
];
|
|
740
|
+
const seedHash = Buffer.from(keccak256(Buffer.concat(parts)).slice(2), "hex");
|
|
741
|
+
const [pda] = await getProgramDerivedAddress({
|
|
742
|
+
programAddress: programId,
|
|
743
|
+
seeds: [Buffer.from("delegate"), seedHash],
|
|
1035
744
|
});
|
|
745
|
+
return pda;
|
|
1036
746
|
}
|
|
1037
747
|
/**
|
|
1038
748
|
* Returns the delegate PDA for depositNow.
|
|
1039
749
|
*/
|
|
1040
|
-
export function getDepositNowDelegatePda(depositData, programId) {
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
];
|
|
1063
|
-
seedHash = Buffer.from(keccak256(Buffer.concat(parts)).slice(2), "hex");
|
|
1064
|
-
return [4 /*yield*/, getProgramDerivedAddress({
|
|
1065
|
-
programAddress: programId,
|
|
1066
|
-
seeds: [Buffer.from("delegate"), seedHash],
|
|
1067
|
-
})];
|
|
1068
|
-
case 1:
|
|
1069
|
-
pda = (_a.sent())[0];
|
|
1070
|
-
return [2 /*return*/, pda];
|
|
1071
|
-
}
|
|
1072
|
-
});
|
|
750
|
+
export async function getDepositNowDelegatePda(depositData, programId) {
|
|
751
|
+
const addrEnc = getAddressEncoder();
|
|
752
|
+
const u64 = getU64Encoder();
|
|
753
|
+
const u32 = getU32Encoder();
|
|
754
|
+
const parts = [
|
|
755
|
+
Uint8Array.from(addrEnc.encode(depositData.depositor)),
|
|
756
|
+
Uint8Array.from(addrEnc.encode(depositData.recipient)),
|
|
757
|
+
Uint8Array.from(addrEnc.encode(depositData.inputToken)),
|
|
758
|
+
Uint8Array.from(addrEnc.encode(depositData.outputToken)),
|
|
759
|
+
Uint8Array.from(u64.encode(depositData.inputAmount)),
|
|
760
|
+
Uint8Array.from(depositData.outputAmount),
|
|
761
|
+
Uint8Array.from(u64.encode(depositData.destinationChainId)),
|
|
762
|
+
Uint8Array.from(addrEnc.encode(depositData.exclusiveRelayer)),
|
|
763
|
+
Uint8Array.from(u32.encode(depositData.fillDeadlineOffset)),
|
|
764
|
+
Uint8Array.from(u32.encode(depositData.exclusivityPeriod)),
|
|
765
|
+
Uint8Array.from(u32.encode(BigInt(depositData.message.length))),
|
|
766
|
+
depositData.message,
|
|
767
|
+
];
|
|
768
|
+
const seedHash = Buffer.from(keccak256(Buffer.concat(parts)).slice(2), "hex");
|
|
769
|
+
const [pda] = await getProgramDerivedAddress({
|
|
770
|
+
programAddress: programId,
|
|
771
|
+
seeds: [Buffer.from("delegate"), seedHash],
|
|
1073
772
|
});
|
|
773
|
+
return pda;
|
|
1074
774
|
}
|
|
1075
775
|
/**
|
|
1076
776
|
* Returns the fill-delegate PDA for fillRelay.
|
|
1077
777
|
*/
|
|
1078
|
-
export function getFillRelayDelegatePda(relayHash, repaymentChainId, repaymentAddress, programId) {
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
];
|
|
1091
|
-
seedHash = Buffer.from(keccak256(Buffer.concat(parts)).slice(2), "hex");
|
|
1092
|
-
return [4 /*yield*/, getProgramDerivedAddress({
|
|
1093
|
-
programAddress: programId,
|
|
1094
|
-
seeds: [Buffer.from("delegate"), seedHash],
|
|
1095
|
-
})];
|
|
1096
|
-
case 1:
|
|
1097
|
-
pda = (_a.sent())[0];
|
|
1098
|
-
return [2 /*return*/, pda];
|
|
1099
|
-
}
|
|
1100
|
-
});
|
|
778
|
+
export async function getFillRelayDelegatePda(relayHash, repaymentChainId, repaymentAddress, programId) {
|
|
779
|
+
const addrEnc = getAddressEncoder();
|
|
780
|
+
const u64 = getU64Encoder();
|
|
781
|
+
const parts = [
|
|
782
|
+
relayHash,
|
|
783
|
+
Uint8Array.from(u64.encode(repaymentChainId)),
|
|
784
|
+
Uint8Array.from(addrEnc.encode(repaymentAddress)),
|
|
785
|
+
];
|
|
786
|
+
const seedHash = Buffer.from(keccak256(Buffer.concat(parts)).slice(2), "hex");
|
|
787
|
+
const [pda] = await getProgramDerivedAddress({
|
|
788
|
+
programAddress: programId,
|
|
789
|
+
seeds: [Buffer.from("delegate"), seedHash],
|
|
1101
790
|
});
|
|
791
|
+
return pda;
|
|
1102
792
|
}
|
|
1103
793
|
/**
|
|
1104
794
|
* Checks if a CCTP message has been processed.
|
|
@@ -1111,91 +801,67 @@ export function getFillRelayDelegatePda(relayHash, repaymentChainId, repaymentAd
|
|
|
1111
801
|
* the error handling would have to account for the asynchronous opening/closing of PDAs, which is better handled downstream,
|
|
1112
802
|
* where the caller of this function has more context.
|
|
1113
803
|
*/
|
|
1114
|
-
export
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
case 1:
|
|
1120
|
-
noncePda = _a.sent();
|
|
1121
|
-
isNonceUsedIx = MessageTransmitterClient.getIsNonceUsedInstruction({
|
|
1122
|
-
nonce: nonce,
|
|
1123
|
-
usedNonces: noncePda,
|
|
1124
|
-
});
|
|
1125
|
-
parserFunction = function (buf) {
|
|
1126
|
-
if (buf.length != 1) {
|
|
1127
|
-
throw new Error("Invalid buffer length for isNonceUsedIx");
|
|
1128
|
-
}
|
|
1129
|
-
return Boolean(buf[0]);
|
|
1130
|
-
};
|
|
1131
|
-
return [4 /*yield*/, simulateAndDecode(solanaClient, isNonceUsedIx, signer, parserFunction, latestBlockhash)];
|
|
1132
|
-
case 2: return [2 /*return*/, _a.sent()];
|
|
1133
|
-
}
|
|
804
|
+
export const hasCCTPV1MessageBeenProcessed = async (solanaClient, signer, nonce, sourceDomain, latestBlockhash) => {
|
|
805
|
+
const noncePda = await getCCTPNoncePda(solanaClient, signer, nonce, sourceDomain);
|
|
806
|
+
const isNonceUsedIx = MessageTransmitterClient.getIsNonceUsedInstruction({
|
|
807
|
+
nonce: nonce,
|
|
808
|
+
usedNonces: noncePda,
|
|
1134
809
|
});
|
|
1135
|
-
|
|
810
|
+
const parserFunction = (buf) => {
|
|
811
|
+
if (buf.length != 1) {
|
|
812
|
+
throw new Error("Invalid buffer length for isNonceUsedIx");
|
|
813
|
+
}
|
|
814
|
+
return Boolean(buf[0]);
|
|
815
|
+
};
|
|
816
|
+
return await simulateAndDecode(solanaClient, isNonceUsedIx, signer, parserFunction, latestBlockhash);
|
|
817
|
+
};
|
|
1136
818
|
/**
|
|
1137
819
|
* Returns the account metas for a tokenless message.
|
|
1138
820
|
* @returns The account metas for a tokenless message.
|
|
1139
821
|
*/
|
|
1140
|
-
export function getAccountMetasForTokenlessMessage(solanaClient, signer, messageBytes) {
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
rootBundle = _a.sent();
|
|
1184
|
-
return [2 /*return*/, __spreadArray(__spreadArray([], base, true), [
|
|
1185
|
-
{ address: signer.address, role: AccountRole.READONLY },
|
|
1186
|
-
{ address: statePda, role: AccountRole.READONLY },
|
|
1187
|
-
{ address: rootBundle, role: AccountRole.WRITABLE },
|
|
1188
|
-
{ address: eventAuthority, role: AccountRole.READONLY },
|
|
1189
|
-
{ address: programAddress, role: AccountRole.READONLY },
|
|
1190
|
-
], false)];
|
|
1191
|
-
case 8: return [2 /*return*/, __spreadArray(__spreadArray([], base, true), [
|
|
1192
|
-
{ address: statePda, role: AccountRole.WRITABLE },
|
|
1193
|
-
{ address: eventAuthority, role: AccountRole.READONLY },
|
|
1194
|
-
{ address: programAddress, role: AccountRole.READONLY },
|
|
1195
|
-
], false)];
|
|
1196
|
-
}
|
|
1197
|
-
});
|
|
1198
|
-
});
|
|
822
|
+
export async function getAccountMetasForTokenlessMessage(solanaClient, signer, messageBytes) {
|
|
823
|
+
const messageHex = messageBytes.slice(2);
|
|
824
|
+
const messageHeader = decodeMessageHeader(Buffer.from(messageHex, "hex"));
|
|
825
|
+
const programAddress = SvmSpokeClient.SVM_SPOKE_PROGRAM_ADDRESS;
|
|
826
|
+
const statePda = await getStatePda(programAddress);
|
|
827
|
+
const selfAuthority = await getSelfAuthority();
|
|
828
|
+
const eventAuthority = await getEventAuthority(programAddress);
|
|
829
|
+
const base = [
|
|
830
|
+
{ address: statePda, role: AccountRole.READONLY },
|
|
831
|
+
{ address: selfAuthority, role: AccountRole.READONLY },
|
|
832
|
+
{ address: programAddress, role: AccountRole.READONLY },
|
|
833
|
+
];
|
|
834
|
+
if (isRelayRootBundleMessageBody(messageHeader.messageBody)) {
|
|
835
|
+
const { data: { rootBundleId }, } = await SvmSpokeClient.fetchState(solanaClient, statePda);
|
|
836
|
+
const rootBundle = await getRootBundlePda(programAddress, rootBundleId);
|
|
837
|
+
return [
|
|
838
|
+
...base,
|
|
839
|
+
{ address: signer.address, role: AccountRole.WRITABLE },
|
|
840
|
+
{ address: statePda, role: AccountRole.WRITABLE },
|
|
841
|
+
{ address: rootBundle, role: AccountRole.WRITABLE },
|
|
842
|
+
{ address: SYSTEM_PROGRAM_ADDRESS, role: AccountRole.READONLY },
|
|
843
|
+
{ address: eventAuthority, role: AccountRole.READONLY },
|
|
844
|
+
{ address: programAddress, role: AccountRole.READONLY },
|
|
845
|
+
];
|
|
846
|
+
}
|
|
847
|
+
if (isEmergencyDeleteRootBundleMessageBody(messageHeader.messageBody)) {
|
|
848
|
+
const rootBundleId = getEmergencyDeleteRootBundleRootBundleId(messageHeader.messageBody);
|
|
849
|
+
const rootBundle = await getRootBundlePda(programAddress, rootBundleId);
|
|
850
|
+
return [
|
|
851
|
+
...base,
|
|
852
|
+
{ address: signer.address, role: AccountRole.READONLY },
|
|
853
|
+
{ address: statePda, role: AccountRole.READONLY },
|
|
854
|
+
{ address: rootBundle, role: AccountRole.WRITABLE },
|
|
855
|
+
{ address: eventAuthority, role: AccountRole.READONLY },
|
|
856
|
+
{ address: programAddress, role: AccountRole.READONLY },
|
|
857
|
+
];
|
|
858
|
+
}
|
|
859
|
+
return [
|
|
860
|
+
...base,
|
|
861
|
+
{ address: statePda, role: AccountRole.WRITABLE },
|
|
862
|
+
{ address: eventAuthority, role: AccountRole.READONLY },
|
|
863
|
+
{ address: programAddress, role: AccountRole.READONLY },
|
|
864
|
+
];
|
|
1199
865
|
}
|
|
1200
866
|
/**
|
|
1201
867
|
* Returns the required PDAs for a deposit message.
|
|
@@ -1204,57 +870,47 @@ export function getAccountMetasForTokenlessMessage(solanaClient, signer, message
|
|
|
1204
870
|
* @param tokenMessengerMinter The token messenger minter address.
|
|
1205
871
|
* @param messageTransmitterAddress The message transmitter address.
|
|
1206
872
|
*/
|
|
1207
|
-
export function getCCTPDepositAccounts(hubChainId, cctpDestinationDomainId, tokenMessengerMinterAddress, messageTransmitterAddress) {
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
tokenMinter: tokenMinter,
|
|
1249
|
-
localToken: localToken,
|
|
1250
|
-
cctpEventAuthority: cctpEventAuthority,
|
|
1251
|
-
remoteTokenMessenger: remoteTokenMessenger,
|
|
1252
|
-
tokenMessengerMinterSenderAuthority: tokenMessengerMinterSenderAuthority,
|
|
1253
|
-
messageTransmitter: messageTransmitter,
|
|
1254
|
-
}];
|
|
1255
|
-
}
|
|
1256
|
-
});
|
|
1257
|
-
});
|
|
873
|
+
export async function getCCTPDepositAccounts(hubChainId, cctpDestinationDomainId, tokenMessengerMinterAddress, messageTransmitterAddress) {
|
|
874
|
+
const l2Usdc = SvmAddress.from(TOKEN_SYMBOLS_MAP.USDC.addresses[chainIsProd(hubChainId) ? CHAIN_IDs.SOLANA : CHAIN_IDs.SOLANA_DEVNET]);
|
|
875
|
+
const [[tokenMessenger], [tokenMinter], [localToken], [cctpEventAuthority], [remoteTokenMessenger], [tokenMessengerMinterSenderAuthority], [messageTransmitter],] = await Promise.all([
|
|
876
|
+
getProgramDerivedAddress({
|
|
877
|
+
programAddress: tokenMessengerMinterAddress,
|
|
878
|
+
seeds: ["token_messenger"],
|
|
879
|
+
}),
|
|
880
|
+
getProgramDerivedAddress({
|
|
881
|
+
programAddress: tokenMessengerMinterAddress,
|
|
882
|
+
seeds: ["token_minter"],
|
|
883
|
+
}),
|
|
884
|
+
getProgramDerivedAddress({
|
|
885
|
+
programAddress: tokenMessengerMinterAddress,
|
|
886
|
+
seeds: ["local_token", bs58.decode(l2Usdc.toBase58())],
|
|
887
|
+
}),
|
|
888
|
+
getProgramDerivedAddress({
|
|
889
|
+
programAddress: tokenMessengerMinterAddress,
|
|
890
|
+
seeds: ["__event_authority"],
|
|
891
|
+
}),
|
|
892
|
+
getProgramDerivedAddress({
|
|
893
|
+
programAddress: tokenMessengerMinterAddress,
|
|
894
|
+
seeds: ["remote_token_messenger", String(cctpDestinationDomainId)],
|
|
895
|
+
}),
|
|
896
|
+
getProgramDerivedAddress({
|
|
897
|
+
programAddress: tokenMessengerMinterAddress,
|
|
898
|
+
seeds: ["sender_authority"],
|
|
899
|
+
}),
|
|
900
|
+
getProgramDerivedAddress({
|
|
901
|
+
programAddress: messageTransmitterAddress,
|
|
902
|
+
seeds: ["message_transmitter"],
|
|
903
|
+
}),
|
|
904
|
+
]);
|
|
905
|
+
return {
|
|
906
|
+
tokenMessenger,
|
|
907
|
+
tokenMinter,
|
|
908
|
+
localToken,
|
|
909
|
+
cctpEventAuthority,
|
|
910
|
+
remoteTokenMessenger,
|
|
911
|
+
tokenMessengerMinterSenderAuthority,
|
|
912
|
+
messageTransmitter,
|
|
913
|
+
};
|
|
1258
914
|
}
|
|
1259
915
|
/**
|
|
1260
916
|
* Returns the account metas for a deposit message.
|
|
@@ -1264,75 +920,54 @@ export function getCCTPDepositAccounts(hubChainId, cctpDestinationDomainId, toke
|
|
|
1264
920
|
* @param recipientAta The ATA of the recipient address.
|
|
1265
921
|
* @returns The account metas for a deposit message.
|
|
1266
922
|
*/
|
|
1267
|
-
function getAccountMetasForDepositMessage(message, hubChainId, tokenMessengerMinter, recipientAta) {
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
seeds: ["token_messenger"],
|
|
1278
|
-
})];
|
|
1279
|
-
case 1:
|
|
1280
|
-
tokenMessengerPda = (_a.sent())[0];
|
|
1281
|
-
return [4 /*yield*/, getProgramDerivedAddress({
|
|
1282
|
-
programAddress: tokenMessengerMinter,
|
|
1283
|
-
seeds: ["token_minter"],
|
|
1284
|
-
})];
|
|
1285
|
-
case 2:
|
|
1286
|
-
tokenMinterPda = (_a.sent())[0];
|
|
1287
|
-
return [4 /*yield*/, getProgramDerivedAddress({
|
|
1288
|
-
programAddress: tokenMessengerMinter,
|
|
1289
|
-
seeds: ["local_token", bs58.decode(l2Usdc.toBase58())],
|
|
1290
|
-
})];
|
|
1291
|
-
case 3:
|
|
1292
|
-
localTokenPda = (_a.sent())[0];
|
|
1293
|
-
return [4 /*yield*/, getProgramDerivedAddress({
|
|
1294
|
-
programAddress: tokenMessengerMinter,
|
|
1295
|
-
seeds: ["__event_authority"],
|
|
1296
|
-
})];
|
|
1297
|
-
case 4:
|
|
1298
|
-
tokenMessengerEventAuthorityPda = (_a.sent())[0];
|
|
1299
|
-
return [4 /*yield*/, getProgramDerivedAddress({
|
|
1300
|
-
programAddress: tokenMessengerMinter,
|
|
1301
|
-
seeds: ["custody", bs58.decode(l2Usdc.toBase58())],
|
|
1302
|
-
})];
|
|
1303
|
-
case 5:
|
|
1304
|
-
custodyTokenAccountPda = (_a.sent())[0];
|
|
1305
|
-
return [4 /*yield*/, getProgramDerivedAddress({
|
|
1306
|
-
programAddress: tokenMessengerMinter,
|
|
1307
|
-
seeds: [
|
|
1308
|
-
new Uint8Array(Buffer.from("token_pair")),
|
|
1309
|
-
new Uint8Array(Buffer.from(String(message.sourceDomain))),
|
|
1310
|
-
new Uint8Array(Buffer.from(l1Usdc.toBytes32().slice(2), "hex")),
|
|
1311
|
-
],
|
|
1312
|
-
})];
|
|
1313
|
-
case 6:
|
|
1314
|
-
tokenPairPda = (_a.sent())[0];
|
|
1315
|
-
return [4 /*yield*/, getProgramDerivedAddress({
|
|
1316
|
-
programAddress: tokenMessengerMinter,
|
|
1317
|
-
seeds: ["remote_token_messenger", String(message.sourceDomain)],
|
|
1318
|
-
})];
|
|
1319
|
-
case 7:
|
|
1320
|
-
remoteTokenMessengerPda = (_a.sent())[0];
|
|
1321
|
-
return [2 /*return*/, [
|
|
1322
|
-
{ address: tokenMessengerPda, role: AccountRole.READONLY },
|
|
1323
|
-
{ address: remoteTokenMessengerPda, role: AccountRole.READONLY },
|
|
1324
|
-
{ address: tokenMinterPda, role: AccountRole.WRITABLE },
|
|
1325
|
-
{ address: localTokenPda, role: AccountRole.WRITABLE },
|
|
1326
|
-
{ address: tokenPairPda, role: AccountRole.READONLY },
|
|
1327
|
-
{ address: toAddress(recipientAta), role: AccountRole.WRITABLE },
|
|
1328
|
-
{ address: custodyTokenAccountPda, role: AccountRole.WRITABLE },
|
|
1329
|
-
{ address: TOKEN_PROGRAM_ADDRESS, role: AccountRole.READONLY },
|
|
1330
|
-
{ address: tokenMessengerEventAuthorityPda, role: AccountRole.READONLY },
|
|
1331
|
-
{ address: tokenMessengerMinter, role: AccountRole.READONLY },
|
|
1332
|
-
]];
|
|
1333
|
-
}
|
|
1334
|
-
});
|
|
923
|
+
async function getAccountMetasForDepositMessage(message, hubChainId, tokenMessengerMinter, recipientAta) {
|
|
924
|
+
const l1Usdc = EvmAddress.from(TOKEN_SYMBOLS_MAP.USDC.addresses[hubChainId]);
|
|
925
|
+
const l2Usdc = SvmAddress.from(TOKEN_SYMBOLS_MAP.USDC.addresses[chainIsProd(hubChainId) ? CHAIN_IDs.SOLANA : CHAIN_IDs.SOLANA_DEVNET]);
|
|
926
|
+
const [tokenMessengerPda] = await getProgramDerivedAddress({
|
|
927
|
+
programAddress: tokenMessengerMinter,
|
|
928
|
+
seeds: ["token_messenger"],
|
|
929
|
+
});
|
|
930
|
+
const [tokenMinterPda] = await getProgramDerivedAddress({
|
|
931
|
+
programAddress: tokenMessengerMinter,
|
|
932
|
+
seeds: ["token_minter"],
|
|
1335
933
|
});
|
|
934
|
+
const [localTokenPda] = await getProgramDerivedAddress({
|
|
935
|
+
programAddress: tokenMessengerMinter,
|
|
936
|
+
seeds: ["local_token", bs58.decode(l2Usdc.toBase58())],
|
|
937
|
+
});
|
|
938
|
+
const [tokenMessengerEventAuthorityPda] = await getProgramDerivedAddress({
|
|
939
|
+
programAddress: tokenMessengerMinter,
|
|
940
|
+
seeds: ["__event_authority"],
|
|
941
|
+
});
|
|
942
|
+
const [custodyTokenAccountPda] = await getProgramDerivedAddress({
|
|
943
|
+
programAddress: tokenMessengerMinter,
|
|
944
|
+
seeds: ["custody", bs58.decode(l2Usdc.toBase58())],
|
|
945
|
+
});
|
|
946
|
+
// Define accounts dependent on deposit information.
|
|
947
|
+
const [tokenPairPda] = await getProgramDerivedAddress({
|
|
948
|
+
programAddress: tokenMessengerMinter,
|
|
949
|
+
seeds: [
|
|
950
|
+
new Uint8Array(Buffer.from("token_pair")),
|
|
951
|
+
new Uint8Array(Buffer.from(String(message.sourceDomain))),
|
|
952
|
+
new Uint8Array(Buffer.from(l1Usdc.toBytes32().slice(2), "hex")),
|
|
953
|
+
],
|
|
954
|
+
});
|
|
955
|
+
const [remoteTokenMessengerPda] = await getProgramDerivedAddress({
|
|
956
|
+
programAddress: tokenMessengerMinter,
|
|
957
|
+
seeds: ["remote_token_messenger", String(message.sourceDomain)],
|
|
958
|
+
});
|
|
959
|
+
return [
|
|
960
|
+
{ address: tokenMessengerPda, role: AccountRole.READONLY },
|
|
961
|
+
{ address: remoteTokenMessengerPda, role: AccountRole.READONLY },
|
|
962
|
+
{ address: tokenMinterPda, role: AccountRole.WRITABLE },
|
|
963
|
+
{ address: localTokenPda, role: AccountRole.WRITABLE },
|
|
964
|
+
{ address: tokenPairPda, role: AccountRole.READONLY },
|
|
965
|
+
{ address: toAddress(recipientAta), role: AccountRole.WRITABLE },
|
|
966
|
+
{ address: custodyTokenAccountPda, role: AccountRole.WRITABLE },
|
|
967
|
+
{ address: TOKEN_PROGRAM_ADDRESS, role: AccountRole.READONLY },
|
|
968
|
+
{ address: tokenMessengerEventAuthorityPda, role: AccountRole.READONLY },
|
|
969
|
+
{ address: tokenMessengerMinter, role: AccountRole.READONLY },
|
|
970
|
+
];
|
|
1336
971
|
}
|
|
1337
972
|
/**
|
|
1338
973
|
* Returns the CCTP v1 receive message transaction.
|
|
@@ -1343,66 +978,45 @@ function getAccountMetasForDepositMessage(message, hubChainId, tokenMessengerMin
|
|
|
1343
978
|
* @param recipientAta The ATA of the recipient address (used for token finalizations only).
|
|
1344
979
|
* @returns The CCTP v1 receive message transaction.
|
|
1345
980
|
*/
|
|
1346
|
-
export function getCCTPV1ReceiveMessageTx(solanaClient, signer, message, hubChainId, recipientAta) {
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
})];
|
|
1355
|
-
case 1:
|
|
1356
|
-
messageTransmitterPda = (_b.sent())[0];
|
|
1357
|
-
return [4 /*yield*/, getProgramDerivedAddress({
|
|
1358
|
-
programAddress: MessageTransmitterClient.MESSAGE_TRANSMITTER_PROGRAM_ADDRESS,
|
|
1359
|
-
seeds: ["__event_authority"],
|
|
1360
|
-
})];
|
|
1361
|
-
case 2:
|
|
1362
|
-
eventAuthorityPda = (_b.sent())[0];
|
|
1363
|
-
cctpMessageReceiver = isDepositForBurnEvent(message)
|
|
1364
|
-
? TokenMessengerMinterClient.TOKEN_MESSENGER_MINTER_PROGRAM_ADDRESS
|
|
1365
|
-
: SvmSpokeClient.SVM_SPOKE_PROGRAM_ADDRESS;
|
|
1366
|
-
return [4 /*yield*/, getProgramDerivedAddress({
|
|
1367
|
-
programAddress: MessageTransmitterClient.MESSAGE_TRANSMITTER_PROGRAM_ADDRESS,
|
|
1368
|
-
seeds: ["message_transmitter_authority", bs58.decode(cctpMessageReceiver)],
|
|
1369
|
-
})];
|
|
1370
|
-
case 3:
|
|
1371
|
-
authorityPda = (_b.sent())[0];
|
|
1372
|
-
return [4 /*yield*/, getCCTPNoncePda(solanaClient, signer, message.nonce, message.sourceDomain)];
|
|
1373
|
-
case 4:
|
|
1374
|
-
usedNonces = _b.sent();
|
|
1375
|
-
if (!isDepositForBurnEvent(message)) return [3 /*break*/, 6];
|
|
1376
|
-
return [4 /*yield*/, getAccountMetasForDepositMessage(message, hubChainId, TokenMessengerMinterClient.TOKEN_MESSENGER_MINTER_PROGRAM_ADDRESS, recipientAta)];
|
|
1377
|
-
case 5:
|
|
1378
|
-
_a = _b.sent();
|
|
1379
|
-
return [3 /*break*/, 8];
|
|
1380
|
-
case 6: return [4 /*yield*/, getAccountMetasForTokenlessMessage(solanaClient, signer, message.messageBytes)];
|
|
1381
|
-
case 7:
|
|
1382
|
-
_a = _b.sent();
|
|
1383
|
-
_b.label = 8;
|
|
1384
|
-
case 8:
|
|
1385
|
-
accountMetas = _a;
|
|
1386
|
-
messageBytes = message.messageBytes.startsWith("0x")
|
|
1387
|
-
? Buffer.from(message.messageBytes.slice(2), "hex")
|
|
1388
|
-
: Buffer.from(message.messageBytes, "hex");
|
|
1389
|
-
input = {
|
|
1390
|
-
program: MessageTransmitterClient.MESSAGE_TRANSMITTER_PROGRAM_ADDRESS,
|
|
1391
|
-
payer: signer,
|
|
1392
|
-
caller: signer,
|
|
1393
|
-
authorityPda: authorityPda,
|
|
1394
|
-
messageTransmitter: messageTransmitterPda,
|
|
1395
|
-
eventAuthority: eventAuthorityPda,
|
|
1396
|
-
usedNonces: usedNonces,
|
|
1397
|
-
receiver: cctpMessageReceiver,
|
|
1398
|
-
systemProgram: SYSTEM_PROGRAM_ADDRESS,
|
|
1399
|
-
message: messageBytes,
|
|
1400
|
-
attestation: Buffer.from(message.attestation.slice(2), "hex"),
|
|
1401
|
-
};
|
|
1402
|
-
return [2 /*return*/, createReceiveMessageInstruction(signer, solanaClient, input, accountMetas)];
|
|
1403
|
-
}
|
|
1404
|
-
});
|
|
981
|
+
export async function getCCTPV1ReceiveMessageTx(solanaClient, signer, message, hubChainId, recipientAta) {
|
|
982
|
+
const [messageTransmitterPda] = await getProgramDerivedAddress({
|
|
983
|
+
programAddress: MessageTransmitterClient.MESSAGE_TRANSMITTER_PROGRAM_ADDRESS,
|
|
984
|
+
seeds: ["message_transmitter"],
|
|
985
|
+
});
|
|
986
|
+
const [eventAuthorityPda] = await getProgramDerivedAddress({
|
|
987
|
+
programAddress: MessageTransmitterClient.MESSAGE_TRANSMITTER_PROGRAM_ADDRESS,
|
|
988
|
+
seeds: ["__event_authority"],
|
|
1405
989
|
});
|
|
990
|
+
const cctpMessageReceiver = isDepositForBurnEvent(message)
|
|
991
|
+
? TokenMessengerMinterClient.TOKEN_MESSENGER_MINTER_PROGRAM_ADDRESS
|
|
992
|
+
: SvmSpokeClient.SVM_SPOKE_PROGRAM_ADDRESS;
|
|
993
|
+
const [authorityPda] = await getProgramDerivedAddress({
|
|
994
|
+
programAddress: MessageTransmitterClient.MESSAGE_TRANSMITTER_PROGRAM_ADDRESS,
|
|
995
|
+
seeds: ["message_transmitter_authority", bs58.decode(cctpMessageReceiver)],
|
|
996
|
+
});
|
|
997
|
+
// Notice: message.nonce is only valid for v1 messages
|
|
998
|
+
const usedNonces = await getCCTPNoncePda(solanaClient, signer, message.nonce, message.sourceDomain);
|
|
999
|
+
// Notice: for Svm tokenless messages, we currently only support very specific finalizations: Hub -> Spoke relayRootBundle calls
|
|
1000
|
+
const accountMetas = isDepositForBurnEvent(message)
|
|
1001
|
+
? await getAccountMetasForDepositMessage(message, hubChainId, TokenMessengerMinterClient.TOKEN_MESSENGER_MINTER_PROGRAM_ADDRESS, recipientAta)
|
|
1002
|
+
: await getAccountMetasForTokenlessMessage(solanaClient, signer, message.messageBytes);
|
|
1003
|
+
const messageBytes = message.messageBytes.startsWith("0x")
|
|
1004
|
+
? Buffer.from(message.messageBytes.slice(2), "hex")
|
|
1005
|
+
: Buffer.from(message.messageBytes, "hex");
|
|
1006
|
+
const input = {
|
|
1007
|
+
program: MessageTransmitterClient.MESSAGE_TRANSMITTER_PROGRAM_ADDRESS,
|
|
1008
|
+
payer: signer,
|
|
1009
|
+
caller: signer,
|
|
1010
|
+
authorityPda,
|
|
1011
|
+
messageTransmitter: messageTransmitterPda,
|
|
1012
|
+
eventAuthority: eventAuthorityPda,
|
|
1013
|
+
usedNonces,
|
|
1014
|
+
receiver: cctpMessageReceiver,
|
|
1015
|
+
systemProgram: SYSTEM_PROGRAM_ADDRESS,
|
|
1016
|
+
message: messageBytes,
|
|
1017
|
+
attestation: Buffer.from(message.attestation.slice(2), "hex"),
|
|
1018
|
+
};
|
|
1019
|
+
return createReceiveMessageInstruction(signer, solanaClient, input, accountMetas);
|
|
1406
1020
|
}
|
|
1407
1021
|
/**
|
|
1408
1022
|
* Finalizes CCTP deposits and messages on Solana.
|
|
@@ -1415,58 +1029,32 @@ export function getCCTPV1ReceiveMessageTx(solanaClient, signer, message, hubChai
|
|
|
1415
1029
|
* @param hubChainId The chain ID of the hub.
|
|
1416
1030
|
* @returns A list of executed transaction signatures.
|
|
1417
1031
|
*/
|
|
1418
|
-
export function finalizeCCTPV1Messages(solanaClient, attestedMessages, signer, recipientAta, simulate, hubChainId) {
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
if (!simulate) return [3 /*break*/, 4];
|
|
1430
|
-
_b = (_a = solanaClient)
|
|
1431
|
-
.simulateTransaction;
|
|
1432
|
-
_c = getBase64EncodedWireTransaction;
|
|
1433
|
-
return [4 /*yield*/, signTransactionMessageWithSigners(receiveMessageIx)];
|
|
1434
|
-
case 2: return [4 /*yield*/, _b.apply(_a, [_c.apply(void 0, [_d.sent()]),
|
|
1435
|
-
{
|
|
1436
|
-
encoding: "base64",
|
|
1437
|
-
}])
|
|
1438
|
-
.send()];
|
|
1439
|
-
case 3:
|
|
1440
|
-
result = _d.sent();
|
|
1441
|
-
if (result.value.err) {
|
|
1442
|
-
throw new Error(result.value.err.toString());
|
|
1443
|
-
}
|
|
1444
|
-
return [2 /*return*/, ""];
|
|
1445
|
-
case 4: return [4 /*yield*/, signTransactionMessageWithSigners(receiveMessageIx)];
|
|
1446
|
-
case 5:
|
|
1447
|
-
signedTransaction = _d.sent();
|
|
1448
|
-
signature = getSignatureFromTransaction(signedTransaction);
|
|
1449
|
-
encodedTransaction = getBase64EncodedWireTransaction(signedTransaction);
|
|
1450
|
-
return [4 /*yield*/, solanaClient
|
|
1451
|
-
.sendTransaction(encodedTransaction, { preflightCommitment: "confirmed", encoding: "base64" })
|
|
1452
|
-
.send()];
|
|
1453
|
-
case 6:
|
|
1454
|
-
_d.sent();
|
|
1455
|
-
return [2 /*return*/, signature];
|
|
1456
|
-
}
|
|
1457
|
-
});
|
|
1458
|
-
}); });
|
|
1459
|
-
}
|
|
1460
|
-
export function getMintInfo(solanaClient, mint, config) {
|
|
1461
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1462
|
-
return __generator(this, function (_a) {
|
|
1463
|
-
switch (_a.label) {
|
|
1464
|
-
case 0: return [4 /*yield*/, fetchMint(solanaClient, mint, config)];
|
|
1465
|
-
case 1: return [2 /*return*/, _a.sent()];
|
|
1032
|
+
export function finalizeCCTPV1Messages(solanaClient, attestedMessages, signer, recipientAta, simulate = false, hubChainId = 1) {
|
|
1033
|
+
return mapAsync(attestedMessages, async (message) => {
|
|
1034
|
+
const receiveMessageIx = await getCCTPV1ReceiveMessageTx(solanaClient, signer, message, hubChainId, recipientAta);
|
|
1035
|
+
if (simulate) {
|
|
1036
|
+
const result = await solanaClient
|
|
1037
|
+
.simulateTransaction(getBase64EncodedWireTransaction(await signTransactionMessageWithSigners(receiveMessageIx)), {
|
|
1038
|
+
encoding: "base64",
|
|
1039
|
+
})
|
|
1040
|
+
.send();
|
|
1041
|
+
if (result.value.err) {
|
|
1042
|
+
throw new Error(result.value.err.toString());
|
|
1466
1043
|
}
|
|
1467
|
-
|
|
1044
|
+
return "";
|
|
1045
|
+
}
|
|
1046
|
+
const signedTransaction = await signTransactionMessageWithSigners(receiveMessageIx);
|
|
1047
|
+
const signature = getSignatureFromTransaction(signedTransaction);
|
|
1048
|
+
const encodedTransaction = getBase64EncodedWireTransaction(signedTransaction);
|
|
1049
|
+
await solanaClient
|
|
1050
|
+
.sendTransaction(encodedTransaction, { preflightCommitment: "confirmed", encoding: "base64" })
|
|
1051
|
+
.send();
|
|
1052
|
+
return signature;
|
|
1468
1053
|
});
|
|
1469
1054
|
}
|
|
1055
|
+
export async function getMintInfo(solanaClient, mint, config) {
|
|
1056
|
+
return await fetchMint(solanaClient, mint, config);
|
|
1057
|
+
}
|
|
1470
1058
|
// Extracts value_amount from the AcrossPlusMessage bytes. This serves as a 2nd method of deserializing the value, as
|
|
1471
1059
|
// a way to protect us against potential bugs in the deserialization logic.
|
|
1472
1060
|
function extractValueAmount(acrossPlusMessageBytes) {
|
|
@@ -1479,19 +1067,19 @@ function extractValueAmount(acrossPlusMessageBytes) {
|
|
|
1479
1067
|
// pub accounts: Vec<Pubkey>,
|
|
1480
1068
|
// pub handler_message: Vec<u8>,
|
|
1481
1069
|
// }
|
|
1482
|
-
|
|
1483
|
-
|
|
1070
|
+
const VALUE_OFFSET = 32 + 1; // 33
|
|
1071
|
+
const VALUE_END = VALUE_OFFSET + 8; // 41
|
|
1484
1072
|
if (acrossPlusMessageBytes.length < VALUE_END) {
|
|
1485
|
-
throw new Error(
|
|
1073
|
+
throw new Error(`svm | extractValueAmount: Message too short, need at least ${VALUE_END} bytes, got ${acrossPlusMessageBytes.length}`);
|
|
1486
1074
|
}
|
|
1487
1075
|
return readU64LEExact(acrossPlusMessageBytes.subarray(VALUE_OFFSET, VALUE_END));
|
|
1488
1076
|
}
|
|
1489
1077
|
// Reads exactly 8 bytes as a little-endian u64 and returns bigint
|
|
1490
1078
|
function readU64LEExact(bytes) {
|
|
1491
1079
|
if (bytes.length !== 8) {
|
|
1492
|
-
throw new Error(
|
|
1080
|
+
throw new Error(`readU64LEExact expected 8 bytes, received ${bytes.length}`);
|
|
1493
1081
|
}
|
|
1494
|
-
|
|
1082
|
+
const view = new DataView(bytes.buffer, bytes.byteOffset, 8);
|
|
1495
1083
|
return view.getBigUint64(0, true); // little-endian
|
|
1496
1084
|
}
|
|
1497
1085
|
//# sourceMappingURL=SpokeUtils.js.map
|