Merge branch 'main' of github.com:hyperlane-xyz/hyperlane-monorepo into xeno/core-deploy-apply-admin-proxy-ownership-fixes

xeno/ica-router-management
xeno097 1 month ago
commit 7fc834df1c
  1. 5
      .changeset/dirty-clocks-repeat.md
  2. 5
      .changeset/dirty-months-buy.md
  3. 6
      .changeset/dry-foxes-battle.md
  4. 5
      .changeset/few-goats-add.md
  5. 5
      .changeset/fluffy-ducks-buy.md
  6. 6
      .changeset/grumpy-ears-relate.md
  7. 5
      .changeset/itchy-singers-hang.md
  8. 5
      .changeset/long-swans-drive.md
  9. 6
      .changeset/plenty-chicken-clean.md
  10. 7
      .changeset/poor-coins-accept.md
  11. 5
      .changeset/red-actors-shop.md
  12. 5
      .changeset/silver-dancers-rhyme.md
  13. 5
      .changeset/sweet-humans-argue.md
  14. 5
      .changeset/tender-spiders-deny.md
  15. 5
      .changeset/tidy-hornets-beam.md
  16. 5
      .changeset/tricky-mangos-sin.md
  17. 5
      .changeset/wise-camels-repair.md
  18. 16
      .github/actions/yarn-build-with-cache/action.yml
  19. 26
      .github/workflows/test.yml
  20. 2
      .registryrc
  21. 8
      rust/main/agents/scraper/migration/src/m20230309_000001_create_table_domain.rs
  22. 32
      rust/main/agents/scraper/src/chain_scraper/mod.rs
  23. 12
      rust/main/agents/validator/src/settings.rs
  24. 26
      rust/main/agents/validator/src/submit.rs
  25. 17
      rust/main/agents/validator/src/validator.rs
  26. 9
      rust/main/chains/hyperlane-cosmos/src/mailbox/contract.rs
  27. 22
      rust/main/chains/hyperlane-cosmos/src/merkle_tree_hook.rs
  28. 33
      rust/main/chains/hyperlane-cosmos/src/providers/cosmos/provider.rs
  29. 25
      rust/main/chains/hyperlane-cosmos/src/utils.rs
  30. 54
      rust/main/chains/hyperlane-ethereum/src/config.rs
  31. 28
      rust/main/chains/hyperlane-ethereum/src/contracts/interchain_gas.rs
  32. 37
      rust/main/chains/hyperlane-ethereum/src/contracts/mailbox.rs
  33. 51
      rust/main/chains/hyperlane-ethereum/src/contracts/merkle_tree_hook.rs
  34. 2
      rust/main/chains/hyperlane-ethereum/src/contracts/mod.rs
  35. 35
      rust/main/chains/hyperlane-ethereum/src/contracts/utils.rs
  36. 65
      rust/main/chains/hyperlane-ethereum/src/rpc_clients/provider.rs
  37. 24
      rust/main/chains/hyperlane-ethereum/src/tx.rs
  38. 9
      rust/main/chains/hyperlane-fuel/src/mailbox.rs
  39. 35
      rust/main/chains/hyperlane-fuel/src/provider.rs
  40. 3
      rust/main/chains/hyperlane-sealevel/src/error.rs
  41. 12
      rust/main/chains/hyperlane-sealevel/src/mailbox.rs
  42. 18
      rust/main/chains/hyperlane-sealevel/src/merkle_tree_hook.rs
  43. 27
      rust/main/chains/hyperlane-sealevel/src/provider.rs
  44. 25
      rust/main/chains/hyperlane-sealevel/src/rpc/client.rs
  45. 224
      rust/main/config/mainnet_config.json
  46. 17
      rust/main/hyperlane-base/src/contract_sync/mod.rs
  47. 42
      rust/main/hyperlane-base/src/settings/chains.rs
  48. 8
      rust/main/hyperlane-base/src/settings/checkpoint_syncer.rs
  49. 10
      rust/main/hyperlane-base/src/settings/parser/mod.rs
  50. 116
      rust/main/hyperlane-core/src/chain.rs
  51. 12
      rust/main/hyperlane-core/src/error.rs
  52. 7
      rust/main/hyperlane-core/src/traits/mailbox.rs
  53. 14
      rust/main/hyperlane-core/src/traits/merkle_tree_hook.rs
  54. 22
      rust/main/hyperlane-core/src/traits/provider.rs
  55. 17
      rust/main/hyperlane-core/src/types/block_id.rs
  56. 2
      rust/main/hyperlane-core/src/types/mod.rs
  57. 6
      rust/main/hyperlane-core/src/types/reorg.rs
  58. 12
      rust/main/hyperlane-test/src/mocks/mailbox.rs
  59. 1
      rust/sealevel/environments/mainnet2/.gitignore
  60. 350
      rust/sealevel/environments/mainnet2/chain-config.json
  61. 20
      rust/sealevel/environments/mainnet2/gas-oracle-configs.json
  62. 30
      rust/sealevel/environments/mainnet2/helloworld/hyperlane/helloworld-config.json
  63. 42
      rust/sealevel/environments/mainnet2/helloworld/hyperlane/program-ids.json
  64. 32
      rust/sealevel/environments/mainnet2/helloworld/rc/helloworld-config.json
  65. 42
      rust/sealevel/environments/mainnet2/helloworld/rc/program-ids.json
  66. 106
      rust/sealevel/environments/mainnet2/multisig-ism-message-id/solana/hyperlane/multisig-config.json
  67. 18
      rust/sealevel/environments/mainnet2/multisig-ism-message-id/solana/nautilus/multisig-config.json
  68. 3
      rust/sealevel/environments/mainnet2/multisig-ism-message-id/solana/nautilus/program-ids.json
  69. 65
      rust/sealevel/environments/mainnet2/multisig-ism-message-id/solana/rc/multisig-config.json
  70. 3
      rust/sealevel/environments/mainnet2/multisig-ism-message-id/solana/rc/program-ids.json
  71. 8
      rust/sealevel/environments/mainnet2/solana/core/program-ids.json
  72. 10
      rust/sealevel/environments/mainnet2/warp-routes/zbc/program-ids.json
  73. 16
      rust/sealevel/environments/mainnet2/warp-routes/zbc/token-config.json
  74. 705
      rust/sealevel/environments/mainnet3/chain-config.json
  75. 228
      rust/sealevel/environments/mainnet3/multisig-ism-message-id/eclipsemainnet/hyperlane/multisig-config.json
  76. 26
      solidity/CHANGELOG.md
  77. 2
      solidity/contracts/PackageVersioned.sol
  78. 16
      solidity/contracts/client/GasRouter.sol
  79. 4
      solidity/contracts/libs/TypeCasts.sol
  80. 16
      solidity/contracts/token/HypERC20Collateral.sol
  81. 16
      solidity/contracts/token/extensions/HypERC4626Collateral.sol
  82. 113
      solidity/contracts/token/extensions/WHypERC4626.sol
  83. 4
      solidity/package.json
  84. 2
      solidity/test/GasRouter.t.sol
  85. 2
      solidity/test/isms/RateLimitedIsm.t.sol
  86. 5
      solidity/test/token/HypERC20.t.sol
  87. 68
      solidity/test/token/HypERC4626Test.t.sol
  88. 116
      solidity/test/token/WHypERC4626.t.sol
  89. 4
      typescript/ccip-server/CHANGELOG.md
  90. 2
      typescript/ccip-server/package.json
  91. 8
      typescript/cli/.mocharc-e2e.json
  92. 2
      typescript/cli/.mocharc.json
  93. 41
      typescript/cli/CHANGELOG.md
  94. 11
      typescript/cli/package.json
  95. 12
      typescript/cli/scripts/run-e2e-test.sh
  96. 105
      typescript/cli/src/commands/core.ts
  97. 2
      typescript/cli/src/commands/options.ts
  98. 22
      typescript/cli/src/config/chain.ts
  99. 36
      typescript/cli/src/read/core.ts
  100. 2
      typescript/cli/src/version.ts
  101. Some files were not shown because too many files have changed in this diff Show More

@ -1,5 +0,0 @@
---
'@hyperlane-xyz/utils': patch
---
Fix objMerge implementation

@ -1,5 +0,0 @@
---
'@hyperlane-xyz/sdk': minor
---
Deploy to odysseytestnet

@ -1,6 +0,0 @@
---
'@hyperlane-xyz/cli': minor
---
Add strategyUrl detect and validation in the beginning of `warp apply`
Remove yaml transactions print from `warp apply`

@ -1,5 +0,0 @@
---
'@hyperlane-xyz/sdk': minor
---
Enroll new validators. Add tx overrides when deploying ICA accounts. Core checker now surfaces owner violations for defaultHook and requiredHook. App checker temporarily ignores bytecode mismatch violations.

@ -1,5 +0,0 @@
---
'@hyperlane-xyz/sdk': minor
---
Add override to some transactions to fix warp apply

@ -1,6 +0,0 @@
---
'@hyperlane-xyz/cli': minor
'@hyperlane-xyz/sdk': minor
---
Adds the warp check command to compare warp routes config files with on chain warp route deployments

@ -1,5 +0,0 @@
---
'@hyperlane-xyz/core': patch
---
Patched OPL2ToL1Ism to check for correct messageId for external call in verify

@ -1,5 +0,0 @@
---
'@hyperlane-xyz/cli': minor
---
Add prompt in `warp init` command to choose if a trusted relayer should be used instead of making the choice by default for the user and enable the `--yes` flag to default to a trusted ISM

@ -1,6 +0,0 @@
---
'@hyperlane-xyz/cli': minor
'@hyperlane-xyz/sdk': minor
---
Add rebasing yield route support into CLI/SDK

@ -1,7 +0,0 @@
---
'@hyperlane-xyz/helloworld': patch
'@hyperlane-xyz/widgets': patch
'@hyperlane-xyz/cli': patch
---
Update registry to v4.7.0

@ -1,5 +0,0 @@
---
'@hyperlane-xyz/core': patch
---
Added nonce to HypERC4626

@ -1,5 +0,0 @@
---
'@hyperlane-xyz/infra': minor
---
Updates the warpIds for Renzo's latest deployment to Sei and Taiko to be used by the Checker

@ -1,5 +0,0 @@
---
'@hyperlane-xyz/core': minor
---
Added PRECISION and rateUpdateNonce to ensure compatibility of HypERC4626

@ -1,5 +0,0 @@
---
'@hyperlane-xyz/cli': minor
---
Update `warp apply` such that it updates in place AND extends in a single call

@ -1,5 +0,0 @@
---
'@hyperlane-xyz/sdk': minor
---
Add deployments for mainnets: flow, metall2, polynomial

@ -1,5 +0,0 @@
---
'@hyperlane-xyz/cli': minor
---
updates the multi chain selection prompt by adding search functionality and an optional confirmation prompt for the current selection

@ -1,5 +0,0 @@
---
'@hyperlane-xyz/sdk': patch
---
Set transaction overrides and add 10% gas limit buffer when sending message through HyperlaneCore.

@ -11,12 +11,26 @@ runs:
steps: steps:
- name: Cache - name: Cache
uses: buildjet/cache@v4 uses: buildjet/cache@v4
id: cache
with: with:
path: | path: |
**/node_modules **/node_modules
.yarn .yarn
key: ${{ runner.os }}-yarn-cache-${{ hashFiles('./yarn.lock') }} key: ${{ runner.os }}-yarn-cache-${{ hashFiles('./yarn.lock') }}
fail-on-cache-miss: true
# Typically, the cache will be hit, but if there's a network error when
# restoring the cache, let's run the install step ourselves.
- name: Install dependencies
if: steps.cache.outputs.cache-hit != 'true'
shell: bash
run: |
yarn install
CHANGES=$(git status -s --ignore-submodules)
if [[ ! -z $CHANGES ]]; then
echo "Changes found: $CHANGES"
git diff
exit 1
fi
- name: Build - name: Build
shell: bash shell: bash

@ -109,6 +109,30 @@ jobs:
- name: Unit Tests - name: Unit Tests
run: yarn test:ci run: yarn test:ci
cli-e2e:
runs-on: ubuntu-latest
needs: [yarn-install]
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
submodules: recursive
fetch-depth: 0
- name: foundry-install
uses: foundry-rs/foundry-toolchain@v1
- name: yarn-build
uses: ./.github/actions/yarn-build-with-cache
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- name: Checkout registry
uses: ./.github/actions/checkout-registry
- name: CLI e2e tests
run: yarn --cwd typescript/cli test:e2e
agent-configs: agent-configs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: [yarn-install] needs: [yarn-install]
@ -218,7 +242,7 @@ jobs:
run: | run: |
if [[ -n "$(git diff ${{ github.event.pull_request.head.sha || github.sha }} ${{ github.event.pull_request.base.sha }} -- ./rust)" ]]; then if [[ -n "$(git diff ${{ github.event.pull_request.head.sha || github.sha }} ${{ github.event.pull_request.base.sha }} -- ./rust)" ]]; then
echo "rust_changes=true" >> $GITHUB_OUTPUT echo "rust_changes=true" >> $GITHUB_OUTPUT
echo "$(git diff ${{ github.event.pull_request.head.sha || github.sha }} ${{ github.event.pull_request.base.sha }} -- ./rust)" echo "$(git diff ${{ github.event.pull_request.head.sha || github.sha }} ${{ github.event.pull_request.base.sha }} -- ./rust)"
else else
echo "rust_changes=false" >> $GITHUB_OUTPUT echo "rust_changes=false" >> $GITHUB_OUTPUT
fi fi

@ -1 +1 @@
8583d0841615313c8c880e765eba760378e061cd 18666269e99ad8d2ba45579c4be783478e50e936

@ -438,6 +438,14 @@ const DOMAINS: &[RawDomain] = &[
is_test_net: false, is_test_net: false,
is_deprecated: false, is_deprecated: false,
}, },
RawDomain {
name: "stride",
token: "STRD",
domain: 745,
chain_id: 745,
is_test_net: false,
is_deprecated: false,
},
RawDomain { RawDomain {
name: "cosmostest99990", name: "cosmostest99990",
token: "OSMO", token: "OSMO",

@ -9,7 +9,7 @@ use async_trait::async_trait;
use eyre::Result; use eyre::Result;
use hyperlane_base::settings::IndexSettings; use hyperlane_base::settings::IndexSettings;
use hyperlane_core::{ use hyperlane_core::{
unwrap_or_none_result, BlockInfo, Delivery, HyperlaneDomain, HyperlaneLogStore, unwrap_or_none_result, BlockId, BlockInfo, Delivery, HyperlaneDomain, HyperlaneLogStore,
HyperlaneMessage, HyperlaneProvider, HyperlaneSequenceAwareIndexerStoreReader, HyperlaneMessage, HyperlaneProvider, HyperlaneSequenceAwareIndexerStoreReader,
HyperlaneWatermarkedLogStore, Indexed, InterchainGasPayment, LogMeta, H256, HyperlaneWatermarkedLogStore, Indexed, InterchainGasPayment, LogMeta, H256,
}; };
@ -78,13 +78,13 @@ impl HyperlaneSqlDb {
&self, &self,
log_meta: impl Iterator<Item = &LogMeta>, log_meta: impl Iterator<Item = &LogMeta>,
) -> Result<impl Iterator<Item = TxnWithId>> { ) -> Result<impl Iterator<Item = TxnWithId>> {
let block_hash_by_txn_hash: HashMap<H256, H256> = log_meta let block_id_by_txn_hash: HashMap<H256, BlockId> = log_meta
.map(|meta| { .map(|meta| {
( (
meta.transaction_id meta.transaction_id
.try_into() .try_into()
.expect("256-bit transaction ids are the maximum supported at this time"), .expect("256-bit transaction ids are the maximum supported at this time"),
meta.block_hash, BlockId::new(meta.block_hash, meta.block_number),
) )
}) })
.collect(); .collect();
@ -92,16 +92,16 @@ impl HyperlaneSqlDb {
// all blocks we care about // all blocks we care about
// hash of block maps to the block id and timestamp // hash of block maps to the block id and timestamp
let blocks: HashMap<_, _> = self let blocks: HashMap<_, _> = self
.ensure_blocks(block_hash_by_txn_hash.values().copied()) .ensure_blocks(block_id_by_txn_hash.values().copied())
.await? .await?
.map(|block| (block.hash, block)) .map(|block| (block.hash, block))
.collect(); .collect();
trace!(?blocks, "Ensured blocks"); trace!(?blocks, "Ensured blocks");
// We ensure transactions only from blocks which are inserted into database // We ensure transactions only from blocks which are inserted into database
let txn_hash_with_block_ids = block_hash_by_txn_hash let txn_hash_with_block_ids = block_id_by_txn_hash
.into_iter() .into_iter()
.filter_map(move |(txn, block)| blocks.get(&block).map(|b| (txn, b.id))) .filter_map(move |(txn, block)| blocks.get(&block.hash).map(|b| (txn, b.id)))
.map(|(txn_hash, block_id)| TxnWithBlockId { txn_hash, block_id }); .map(|(txn_hash, block_id)| TxnWithBlockId { txn_hash, block_id });
let txns_with_ids = self.ensure_txns(txn_hash_with_block_ids).await?; let txns_with_ids = self.ensure_txns(txn_hash_with_block_ids).await?;
@ -195,11 +195,17 @@ impl HyperlaneSqlDb {
/// this method. /// this method.
async fn ensure_blocks( async fn ensure_blocks(
&self, &self,
block_hashes: impl Iterator<Item = H256>, block_ids: impl Iterator<Item = BlockId>,
) -> Result<impl Iterator<Item = BasicBlock>> { ) -> Result<impl Iterator<Item = BasicBlock>> {
// Mapping from block hash to block ids (hash and height)
let block_hash_to_block_id_map: HashMap<H256, BlockId> =
block_ids.map(|b| (b.hash, b)).collect();
// Mapping of block hash to `BasicBlock` which contains database block id and block hash. // Mapping of block hash to `BasicBlock` which contains database block id and block hash.
let mut blocks: HashMap<H256, Option<BasicBlock>> = let mut blocks: HashMap<H256, Option<BasicBlock>> = block_hash_to_block_id_map
block_hashes.map(|b| (b, None)).collect(); .keys()
.map(|hash| (*hash, None))
.collect();
let db_blocks: Vec<BasicBlock> = if !blocks.is_empty() { let db_blocks: Vec<BasicBlock> = if !blocks.is_empty() {
// check database to see which blocks we already know and fetch their IDs // check database to see which blocks we already know and fetch their IDs
@ -230,10 +236,14 @@ impl HyperlaneSqlDb {
for chunk in as_chunks(blocks_to_fetch, CHUNK_SIZE) { for chunk in as_chunks(blocks_to_fetch, CHUNK_SIZE) {
debug_assert!(!chunk.is_empty()); debug_assert!(!chunk.is_empty());
for (hash, block_info) in chunk { for (hash, block_info) in chunk {
let info = match self.provider.get_block_by_hash(hash).await { // We should have block_id in this map for every hashes
let block_id = block_hash_to_block_id_map[hash];
let block_height = block_id.height;
let info = match self.provider.get_block_by_height(block_height).await {
Ok(info) => info, Ok(info) => info,
Err(e) => { Err(e) => {
warn!(?hash, ?e, "error fetching and parsing block"); warn!(block_hash = ?hash, ?block_height, ?e, "error fetching and parsing block");
continue; continue;
} }
}; };

@ -15,7 +15,9 @@ use hyperlane_base::{
CheckpointSyncerConf, Settings, SignerConf, CheckpointSyncerConf, Settings, SignerConf,
}, },
}; };
use hyperlane_core::{cfg_unwrap_all, config::*, HyperlaneDomain, HyperlaneDomainProtocol}; use hyperlane_core::{
cfg_unwrap_all, config::*, HyperlaneDomain, HyperlaneDomainProtocol, ReorgPeriod,
};
use serde::Deserialize; use serde::Deserialize;
use serde_json::Value; use serde_json::Value;
@ -36,8 +38,8 @@ pub struct ValidatorSettings {
pub validator: SignerConf, pub validator: SignerConf,
/// The checkpoint syncer configuration /// The checkpoint syncer configuration
pub checkpoint_syncer: CheckpointSyncerConf, pub checkpoint_syncer: CheckpointSyncerConf,
/// The reorg_period in blocks /// The reorg configuration
pub reorg_period: u64, pub reorg_period: ReorgPeriod,
/// How frequently to check for new checkpoints /// How frequently to check for new checkpoints
pub interval: Duration, pub interval: Duration,
} }
@ -122,8 +124,8 @@ impl FromRawConf<RawValidatorSettings> for ValidatorSettings {
.get_key(origin_chain_name) .get_key(origin_chain_name)
.get_opt_key("blocks") .get_opt_key("blocks")
.get_opt_key("reorgPeriod") .get_opt_key("reorgPeriod")
.parse_u64() .parse_value("Invalid reorgPeriod")
.unwrap_or(1); .unwrap_or(ReorgPeriod::from_blocks(1));
cfg_unwrap_all!(cwp, err: [base, origin_chain, validator, checkpoint_syncer]); cfg_unwrap_all!(cwp, err: [base, origin_chain, validator, checkpoint_syncer]);

@ -1,4 +1,3 @@
use std::num::NonZeroU64;
use std::sync::Arc; use std::sync::Arc;
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
use std::vec; use std::vec;
@ -14,13 +13,13 @@ use hyperlane_core::{
accumulator::incremental::IncrementalMerkle, Checkpoint, CheckpointWithMessageId, accumulator::incremental::IncrementalMerkle, Checkpoint, CheckpointWithMessageId,
HyperlaneChain, HyperlaneContract, HyperlaneDomain, HyperlaneSignerExt, HyperlaneChain, HyperlaneContract, HyperlaneDomain, HyperlaneSignerExt,
}; };
use hyperlane_core::{ChainResult, MerkleTreeHook, ReorgEvent}; use hyperlane_core::{ChainResult, MerkleTreeHook, ReorgEvent, ReorgPeriod};
use hyperlane_ethereum::SingletonSignerHandle; use hyperlane_ethereum::SingletonSignerHandle;
#[derive(Clone)] #[derive(Clone)]
pub(crate) struct ValidatorSubmitter { pub(crate) struct ValidatorSubmitter {
interval: Duration, interval: Duration,
reorg_period: Option<NonZeroU64>, reorg_period: ReorgPeriod,
signer: SingletonSignerHandle, signer: SingletonSignerHandle,
merkle_tree_hook: Arc<dyn MerkleTreeHook>, merkle_tree_hook: Arc<dyn MerkleTreeHook>,
checkpoint_syncer: Arc<dyn CheckpointSyncer>, checkpoint_syncer: Arc<dyn CheckpointSyncer>,
@ -31,7 +30,7 @@ pub(crate) struct ValidatorSubmitter {
impl ValidatorSubmitter { impl ValidatorSubmitter {
pub(crate) fn new( pub(crate) fn new(
interval: Duration, interval: Duration,
reorg_period: u64, reorg_period: ReorgPeriod,
merkle_tree_hook: Arc<dyn MerkleTreeHook>, merkle_tree_hook: Arc<dyn MerkleTreeHook>,
signer: SingletonSignerHandle, signer: SingletonSignerHandle,
checkpoint_syncer: Arc<dyn CheckpointSyncer>, checkpoint_syncer: Arc<dyn CheckpointSyncer>,
@ -39,7 +38,7 @@ impl ValidatorSubmitter {
metrics: ValidatorSubmitterMetrics, metrics: ValidatorSubmitterMetrics,
) -> Self { ) -> Self {
Self { Self {
reorg_period: NonZeroU64::new(reorg_period), reorg_period,
interval, interval,
merkle_tree_hook, merkle_tree_hook,
signer, signer,
@ -94,7 +93,8 @@ impl ValidatorSubmitter {
// Lag by reorg period because this is our correctness checkpoint. // Lag by reorg period because this is our correctness checkpoint.
let latest_checkpoint = call_and_retry_indefinitely(|| { let latest_checkpoint = call_and_retry_indefinitely(|| {
let merkle_tree_hook = self.merkle_tree_hook.clone(); let merkle_tree_hook = self.merkle_tree_hook.clone();
Box::pin(async move { merkle_tree_hook.latest_checkpoint(self.reorg_period).await }) let reorg_period = self.reorg_period.clone();
Box::pin(async move { merkle_tree_hook.latest_checkpoint(&reorg_period).await })
}) })
.await; .await;
@ -211,7 +211,7 @@ impl ValidatorSubmitter {
correctness_checkpoint.root, correctness_checkpoint.root,
checkpoint.index, checkpoint.index,
chrono::Utc::now().timestamp() as u64, chrono::Utc::now().timestamp() as u64,
self.reorg_period.map(|x| x.get()).unwrap_or(0), self.reorg_period.clone(),
); );
error!( error!(
?checkpoint, ?checkpoint,
@ -486,9 +486,9 @@ mod test {
#[async_trait] #[async_trait]
impl MerkleTreeHook for MerkleTreeHook { impl MerkleTreeHook for MerkleTreeHook {
async fn tree(&self, lag: Option<NonZeroU64>) -> ChainResult<IncrementalMerkle>; async fn tree(&self, reorg_period: &ReorgPeriod) -> ChainResult<IncrementalMerkle>;
async fn count(&self, lag: Option<NonZeroU64>) -> ChainResult<u32>; async fn count(&self, reorg_period: &ReorgPeriod) -> ChainResult<u32>;
async fn latest_checkpoint(&self, lag: Option<NonZeroU64>) -> ChainResult<Checkpoint>; async fn latest_checkpoint(&self, reorg_period: &ReorgPeriod) -> ChainResult<Checkpoint>;
} }
} }
@ -532,7 +532,7 @@ mod test {
expected_local_merkle_tree: &IncrementalMerkle, expected_local_merkle_tree: &IncrementalMerkle,
mock_onchain_merkle_tree: &IncrementalMerkle, mock_onchain_merkle_tree: &IncrementalMerkle,
unix_timestamp: u64, unix_timestamp: u64,
expected_reorg_period: u64, expected_reorg_period: ReorgPeriod,
) { ) {
assert_eq!( assert_eq!(
reorg_event.canonical_merkle_root, reorg_event.canonical_merkle_root,
@ -617,7 +617,7 @@ mod test {
&expected_local_merkle_tree, &expected_local_merkle_tree,
&mock_onchain_merkle_tree_clone, &mock_onchain_merkle_tree_clone,
unix_timestamp, unix_timestamp,
expected_reorg_period, ReorgPeriod::from_blocks(expected_reorg_period),
); );
Ok(()) Ok(())
}); });
@ -625,7 +625,7 @@ mod test {
// instantiate the validator submitter // instantiate the validator submitter
let validator_submitter = ValidatorSubmitter::new( let validator_submitter = ValidatorSubmitter::new(
Duration::from_secs(1), Duration::from_secs(1),
expected_reorg_period, ReorgPeriod::from_blocks(expected_reorg_period),
Arc::new(mock_merkle_tree_hook), Arc::new(mock_merkle_tree_hook),
dummy_singleton_handle(), dummy_singleton_handle(),
Arc::new(mock_checkpoint_syncer), Arc::new(mock_checkpoint_syncer),

@ -1,4 +1,4 @@
use std::{num::NonZeroU64, sync::Arc, time::Duration}; use std::{sync::Arc, time::Duration};
use crate::server as validator_server; use crate::server as validator_server;
use async_trait::async_trait; use async_trait::async_trait;
@ -19,8 +19,8 @@ use hyperlane_base::{
use hyperlane_core::{ use hyperlane_core::{
Announcement, ChainResult, HyperlaneChain, HyperlaneContract, HyperlaneDomain, HyperlaneSigner, Announcement, ChainResult, HyperlaneChain, HyperlaneContract, HyperlaneDomain, HyperlaneSigner,
HyperlaneSignerExt, Mailbox, MerkleTreeHook, MerkleTreeInsertion, TxOutcome, ValidatorAnnounce, HyperlaneSignerExt, Mailbox, MerkleTreeHook, MerkleTreeInsertion, ReorgPeriod, TxOutcome,
H256, U256, ValidatorAnnounce, H256, U256,
}; };
use hyperlane_ethereum::{SingletonSigner, SingletonSignerHandle}; use hyperlane_ethereum::{SingletonSigner, SingletonSignerHandle};
@ -44,7 +44,7 @@ pub struct Validator {
signer: SingletonSignerHandle, signer: SingletonSignerHandle,
// temporary holder until `run` is called // temporary holder until `run` is called
signer_instance: Option<Box<SingletonSigner>>, signer_instance: Option<Box<SingletonSigner>>,
reorg_period: u64, reorg_period: ReorgPeriod,
interval: Duration, interval: Duration,
checkpoint_syncer: Arc<dyn CheckpointSyncer>, checkpoint_syncer: Arc<dyn CheckpointSyncer>,
core_metrics: Arc<CoreMetrics>, core_metrics: Arc<CoreMetrics>,
@ -184,12 +184,10 @@ impl BaseAgent for Validator {
// announce the validator after spawning the signer task // announce the validator after spawning the signer task
self.announce().await.expect("Failed to announce validator"); self.announce().await.expect("Failed to announce validator");
let reorg_period = NonZeroU64::new(self.reorg_period);
// Ensure that the merkle tree hook has count > 0 before we begin indexing // Ensure that the merkle tree hook has count > 0 before we begin indexing
// messages or submitting checkpoints. // messages or submitting checkpoints.
loop { loop {
match self.merkle_tree_hook.count(reorg_period).await { match self.merkle_tree_hook.count(&self.reorg_period).await {
Ok(0) => { Ok(0) => {
info!("Waiting for first message in merkle tree hook"); info!("Waiting for first message in merkle tree hook");
sleep(self.interval).await; sleep(self.interval).await;
@ -241,7 +239,7 @@ impl Validator {
async fn run_checkpoint_submitters(&self) -> Vec<Instrumented<JoinHandle<()>>> { async fn run_checkpoint_submitters(&self) -> Vec<Instrumented<JoinHandle<()>>> {
let submitter = ValidatorSubmitter::new( let submitter = ValidatorSubmitter::new(
self.interval, self.interval,
self.reorg_period, self.reorg_period.clone(),
self.merkle_tree_hook.clone(), self.merkle_tree_hook.clone(),
self.signer.clone(), self.signer.clone(),
self.checkpoint_syncer.clone(), self.checkpoint_syncer.clone(),
@ -249,10 +247,9 @@ impl Validator {
ValidatorSubmitterMetrics::new(&self.core.metrics, &self.origin_chain), ValidatorSubmitterMetrics::new(&self.core.metrics, &self.origin_chain),
); );
let reorg_period = NonZeroU64::new(self.reorg_period);
let tip_tree = self let tip_tree = self
.merkle_tree_hook .merkle_tree_hook
.tree(reorg_period) .tree(&self.reorg_period)
.await .await
.expect("failed to get merkle tree"); .expect("failed to get merkle tree");
// This function is only called after we have already checked that the // This function is only called after we have already checked that the

@ -8,7 +8,7 @@ use tracing::instrument;
use hyperlane_core::{ use hyperlane_core::{
utils::bytes_to_hex, ChainResult, ContractLocator, HyperlaneChain, HyperlaneContract, utils::bytes_to_hex, ChainResult, ContractLocator, HyperlaneChain, HyperlaneContract,
HyperlaneDomain, HyperlaneMessage, HyperlaneProvider, Mailbox, RawHyperlaneMessage, HyperlaneDomain, HyperlaneMessage, HyperlaneProvider, Mailbox, RawHyperlaneMessage,
TxCostEstimate, TxOutcome, H256, U256, ReorgPeriod, TxCostEstimate, TxOutcome, H256, U256,
}; };
use crate::grpc::WasmProvider; use crate::grpc::WasmProvider;
@ -17,7 +17,7 @@ use crate::payloads::mailbox::{
GeneralMailboxQuery, ProcessMessageRequest, ProcessMessageRequestInner, GeneralMailboxQuery, ProcessMessageRequest, ProcessMessageRequestInner,
}; };
use crate::types::tx_response_to_outcome; use crate::types::tx_response_to_outcome;
use crate::utils::get_block_height_for_lag; use crate::utils::get_block_height_for_reorg_period;
use crate::{payloads, ConnectionConf, CosmosAddress, CosmosProvider, Signer}; use crate::{payloads, ConnectionConf, CosmosAddress, CosmosProvider, Signer};
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
@ -82,8 +82,9 @@ impl HyperlaneChain for CosmosMailbox {
impl Mailbox for CosmosMailbox { impl Mailbox for CosmosMailbox {
#[instrument(level = "debug", err, ret, skip(self))] #[instrument(level = "debug", err, ret, skip(self))]
#[allow(clippy::blocks_in_conditions)] // TODO: `rustc` 1.80.1 clippy issue #[allow(clippy::blocks_in_conditions)] // TODO: `rustc` 1.80.1 clippy issue
async fn count(&self, lag: Option<NonZeroU64>) -> ChainResult<u32> { async fn count(&self, reorg_period: &ReorgPeriod) -> ChainResult<u32> {
let block_height = get_block_height_for_lag(self.provider.grpc(), lag).await?; let block_height =
get_block_height_for_reorg_period(self.provider.grpc(), reorg_period).await?;
self.nonce_at_block(block_height).await self.nonce_at_block(block_height).await
} }

@ -10,15 +10,15 @@ use hyperlane_core::accumulator::incremental::IncrementalMerkle;
use hyperlane_core::{ use hyperlane_core::{
ChainCommunicationError, ChainResult, Checkpoint, ContractLocator, HyperlaneChain, ChainCommunicationError, ChainResult, Checkpoint, ContractLocator, HyperlaneChain,
HyperlaneContract, HyperlaneDomain, HyperlaneProvider, Indexed, Indexer, LogMeta, HyperlaneContract, HyperlaneDomain, HyperlaneProvider, Indexed, Indexer, LogMeta,
MerkleTreeHook, MerkleTreeInsertion, SequenceAwareIndexer, H256, H512, MerkleTreeHook, MerkleTreeInsertion, ReorgPeriod, SequenceAwareIndexer, H256, H512,
}; };
use crate::grpc::WasmProvider; use crate::grpc::WasmProvider;
use crate::payloads::{general, merkle_tree_hook}; use crate::payloads::{general, merkle_tree_hook};
use crate::rpc::{CosmosWasmRpcProvider, ParsedEvent, WasmRpcProvider}; use crate::rpc::{CosmosWasmRpcProvider, ParsedEvent, WasmRpcProvider};
use crate::utils::{ use crate::utils::{
execute_and_parse_log_futures, get_block_height_for_lag, parse_logs_in_range, parse_logs_in_tx, execute_and_parse_log_futures, get_block_height_for_reorg_period, parse_logs_in_range,
CONTRACT_ADDRESS_ATTRIBUTE_KEY, CONTRACT_ADDRESS_ATTRIBUTE_KEY_BASE64, parse_logs_in_tx, CONTRACT_ADDRESS_ATTRIBUTE_KEY, CONTRACT_ADDRESS_ATTRIBUTE_KEY_BASE64,
}; };
use crate::{ConnectionConf, CosmosProvider, HyperlaneCosmosError, Signer}; use crate::{ConnectionConf, CosmosProvider, HyperlaneCosmosError, Signer};
@ -76,12 +76,13 @@ impl MerkleTreeHook for CosmosMerkleTreeHook {
/// Return the incremental merkle tree in storage /// Return the incremental merkle tree in storage
#[instrument(level = "debug", err, ret, skip(self))] #[instrument(level = "debug", err, ret, skip(self))]
#[allow(clippy::blocks_in_conditions)] // TODO: `rustc` 1.80.1 clippy issue #[allow(clippy::blocks_in_conditions)] // TODO: `rustc` 1.80.1 clippy issue
async fn tree(&self, lag: Option<NonZeroU64>) -> ChainResult<IncrementalMerkle> { async fn tree(&self, reorg_period: &ReorgPeriod) -> ChainResult<IncrementalMerkle> {
let payload = merkle_tree_hook::MerkleTreeRequest { let payload = merkle_tree_hook::MerkleTreeRequest {
tree: general::EmptyStruct {}, tree: general::EmptyStruct {},
}; };
let block_height = get_block_height_for_lag(self.provider.grpc(), lag).await?; let block_height =
get_block_height_for_reorg_period(self.provider.grpc(), reorg_period).await?;
let data = self let data = self
.provider .provider
@ -110,23 +111,26 @@ impl MerkleTreeHook for CosmosMerkleTreeHook {
} }
/// Gets the current leaf count of the merkle tree /// Gets the current leaf count of the merkle tree
async fn count(&self, lag: Option<NonZeroU64>) -> ChainResult<u32> { async fn count(&self, reorg_period: &ReorgPeriod) -> ChainResult<u32> {
let payload = merkle_tree_hook::MerkleTreeCountRequest { let payload = merkle_tree_hook::MerkleTreeCountRequest {
count: general::EmptyStruct {}, count: general::EmptyStruct {},
}; };
let block_height = get_block_height_for_lag(self.provider.grpc(), lag).await?; let block_height =
get_block_height_for_reorg_period(self.provider.grpc(), reorg_period).await?;
self.count_at_block(block_height).await self.count_at_block(block_height).await
} }
#[instrument(level = "debug", err, ret, skip(self))] #[instrument(level = "debug", err, ret, skip(self))]
#[allow(clippy::blocks_in_conditions)] // TODO: `rustc` 1.80.1 clippy issue #[allow(clippy::blocks_in_conditions)] // TODO: `rustc` 1.80.1 clippy issue
async fn latest_checkpoint(&self, lag: Option<NonZeroU64>) -> ChainResult<Checkpoint> { async fn latest_checkpoint(&self, reorg_period: &ReorgPeriod) -> ChainResult<Checkpoint> {
let payload = merkle_tree_hook::CheckPointRequest { let payload = merkle_tree_hook::CheckPointRequest {
check_point: general::EmptyStruct {}, check_point: general::EmptyStruct {},
}; };
let block_height = get_block_height_for_lag(self.provider.grpc(), lag).await?; let block_height =
get_block_height_for_reorg_period(self.provider.grpc(), reorg_period).await?;
let data = self let data = self
.provider .provider

@ -18,8 +18,8 @@ use tracing::{error, warn};
use crypto::decompress_public_key; use crypto::decompress_public_key;
use hyperlane_core::{ use hyperlane_core::{
AccountAddressType, BlockInfo, ChainCommunicationError, ChainInfo, ChainResult, AccountAddressType, BlockInfo, ChainCommunicationError, ChainInfo, ChainResult,
ContractLocator, HyperlaneChain, HyperlaneDomain, HyperlaneProvider, TxnInfo, TxnReceiptInfo, ContractLocator, HyperlaneChain, HyperlaneDomain, HyperlaneProvider, HyperlaneProviderError,
H256, U256, TxnInfo, TxnReceiptInfo, H256, U256,
}; };
use crate::grpc::{WasmGrpcProvider, WasmProvider}; use crate::grpc::{WasmGrpcProvider, WasmProvider};
@ -367,33 +367,26 @@ impl HyperlaneChain for CosmosProvider {
#[async_trait] #[async_trait]
impl HyperlaneProvider for CosmosProvider { impl HyperlaneProvider for CosmosProvider {
async fn get_block_by_hash(&self, hash: &H256) -> ChainResult<BlockInfo> { async fn get_block_by_height(&self, height: u64) -> ChainResult<BlockInfo> {
let tendermint_hash = Hash::from_bytes(Algorithm::Sha256, hash.as_bytes()) let response = self.rpc_client.get_block(height as u32).await?;
.expect("block hash should be of correct size");
let response = self.rpc_client.get_block_by_hash(tendermint_hash).await?;
let received_hash = H256::from_slice(response.block_id.hash.as_bytes()); let block = response.block;
let block_height = block.header.height.value();
if &received_hash != hash { if block_height != height {
return Err(ChainCommunicationError::from_other_str( Err(HyperlaneProviderError::IncorrectBlockByHeight(
&format!("received incorrect block, expected hash: {hash:?}, received hash: {received_hash:?}") height,
)); block_height,
))?
} }
let block = response.block.ok_or_else(|| { let hash = H256::from_slice(response.block_id.hash.as_bytes());
ChainCommunicationError::from_other_str(&format!(
"empty block info for block: {:?}",
hash
))
})?;
let time: OffsetDateTime = block.header.time.into(); let time: OffsetDateTime = block.header.time.into();
let block_info = BlockInfo { let block_info = BlockInfo {
hash: hash.to_owned(), hash: hash.to_owned(),
timestamp: time.unix_timestamp() as u64, timestamp: time.unix_timestamp() as u64,
number: block.header.height.value(), number: block_height,
}; };
Ok(block_info) Ok(block_info)

@ -11,7 +11,7 @@ use tendermint::Hash;
use tokio::task::JoinHandle; use tokio::task::JoinHandle;
use tracing::warn; use tracing::warn;
use hyperlane_core::{ChainCommunicationError, ChainResult, Indexed, LogMeta, H256}; use hyperlane_core::{ChainCommunicationError, ChainResult, Indexed, LogMeta, ReorgPeriod, H256};
use crate::grpc::{WasmGrpcProvider, WasmProvider}; use crate::grpc::{WasmGrpcProvider, WasmProvider};
use crate::rpc::{CosmosWasmRpcProvider, ParsedEvent, WasmRpcProvider}; use crate::rpc::{CosmosWasmRpcProvider, ParsedEvent, WasmRpcProvider};
@ -24,20 +24,25 @@ pub(crate) const CONTRACT_ADDRESS_ATTRIBUTE_KEY: &str = "_contract_address";
pub(crate) static CONTRACT_ADDRESS_ATTRIBUTE_KEY_BASE64: Lazy<String> = pub(crate) static CONTRACT_ADDRESS_ATTRIBUTE_KEY_BASE64: Lazy<String> =
Lazy::new(|| BASE64.encode(CONTRACT_ADDRESS_ATTRIBUTE_KEY)); Lazy::new(|| BASE64.encode(CONTRACT_ADDRESS_ATTRIBUTE_KEY));
/// Given a lag, returns the block height at the moment. /// Given a `reorg_period`, returns the block height at the moment.
/// If the lag is None, a block height of None is given, indicating that the /// If the `reorg_period` is None, a block height of None is given,
/// tip directly can be used. /// indicating that the tip directly can be used.
pub(crate) async fn get_block_height_for_lag( pub(crate) async fn get_block_height_for_reorg_period(
provider: &WasmGrpcProvider, provider: &WasmGrpcProvider,
lag: Option<NonZeroU64>, reorg_period: &ReorgPeriod,
) -> ChainResult<Option<u64>> { ) -> ChainResult<Option<u64>> {
let block_height = match lag { let block_height = match reorg_period {
Some(lag) => { ReorgPeriod::Blocks(blocks) => {
let tip = provider.latest_block_height().await?; let tip = provider.latest_block_height().await?;
let block_height = tip - lag.get(); let block_height = tip - blocks.get() as u64;
Some(block_height) Some(block_height)
} }
None => None, ReorgPeriod::None => None,
ReorgPeriod::Tag(_) => {
return Err(ChainCommunicationError::InvalidReorgPeriod(
reorg_period.clone(),
))
}
}; };
Ok(block_height) Ok(block_height)

@ -1,4 +1,8 @@
use hyperlane_core::{config::OperationBatchConfig, U256}; use ethers::providers::Middleware;
use ethers_core::types::{BlockId, BlockNumber};
use hyperlane_core::{
config::OperationBatchConfig, ChainCommunicationError, ChainResult, ReorgPeriod, U256,
};
use url::Url; use url::Url;
/// Ethereum RPC connection configuration /// Ethereum RPC connection configuration
@ -52,3 +56,51 @@ pub struct TransactionOverrides {
/// Max priority fee per gas to use for EIP-1559 transactions. /// Max priority fee per gas to use for EIP-1559 transactions.
pub max_priority_fee_per_gas: Option<U256>, pub max_priority_fee_per_gas: Option<U256>,
} }
/// Ethereum reorg period
#[derive(Copy, Clone, Debug)]
pub enum EthereumReorgPeriod {
/// Number of blocks
Blocks(u32),
/// A block tag
Tag(BlockId),
}
impl TryFrom<&ReorgPeriod> for EthereumReorgPeriod {
type Error = ChainCommunicationError;
fn try_from(value: &ReorgPeriod) -> Result<Self, Self::Error> {
match value {
ReorgPeriod::None => Ok(EthereumReorgPeriod::Blocks(0)),
ReorgPeriod::Blocks(blocks) => Ok(EthereumReorgPeriod::Blocks(blocks.get())),
ReorgPeriod::Tag(tag) => {
let tag = match tag.as_str() {
"latest" => BlockNumber::Latest,
"finalized" => BlockNumber::Finalized,
"safe" => BlockNumber::Safe,
"earliest" => BlockNumber::Earliest,
"pending" => BlockNumber::Pending,
_ => return Err(ChainCommunicationError::InvalidReorgPeriod(value.clone())),
};
Ok(EthereumReorgPeriod::Tag(tag.into()))
}
}
}
}
impl EthereumReorgPeriod {
/// Converts the reorg period into a block id
pub async fn into_block_id<M: Middleware + 'static>(
&self,
provider: &M,
) -> ChainResult<BlockId> {
let block_id = match self {
EthereumReorgPeriod::Blocks(_) => {
(crate::get_finalized_block_number(provider, self).await? as u64).into()
}
// no need to fetch the block number for the `tag`
EthereumReorgPeriod::Tag(tag) => *tag,
};
Ok(block_id)
}
}

@ -9,18 +9,18 @@ use async_trait::async_trait;
use ethers::prelude::Middleware; use ethers::prelude::Middleware;
use hyperlane_core::rpc_clients::call_and_retry_indefinitely; use hyperlane_core::rpc_clients::call_and_retry_indefinitely;
use hyperlane_core::{ use hyperlane_core::{
ChainCommunicationError, ChainResult, ContractLocator, HyperlaneAbi, HyperlaneChain, ChainResult, ContractLocator, HyperlaneAbi, HyperlaneChain, HyperlaneContract, HyperlaneDomain,
HyperlaneContract, HyperlaneDomain, HyperlaneProvider, Indexed, Indexer, HyperlaneProvider, Indexed, Indexer, InterchainGasPaymaster, InterchainGasPayment, LogMeta,
InterchainGasPaymaster, InterchainGasPayment, LogMeta, SequenceAwareIndexer, H160, H256, H512, SequenceAwareIndexer, H160, H256, H512,
}; };
use tracing::instrument; use tracing::instrument;
use super::utils::fetch_raw_logs_and_meta; use super::utils::{fetch_raw_logs_and_meta, get_finalized_block_number};
use crate::interfaces::i_interchain_gas_paymaster::{ use crate::interfaces::i_interchain_gas_paymaster::{
GasPaymentFilter, IInterchainGasPaymaster as EthereumInterchainGasPaymasterInternal, GasPaymentFilter, IInterchainGasPaymaster as EthereumInterchainGasPaymasterInternal,
IINTERCHAINGASPAYMASTER_ABI, IINTERCHAINGASPAYMASTER_ABI,
}; };
use crate::{BuildableWithProvider, ConnectionConf, EthereumProvider}; use crate::{BuildableWithProvider, ConnectionConf, EthereumProvider, EthereumReorgPeriod};
impl<M> Display for EthereumInterchainGasPaymasterInternal<M> impl<M> Display for EthereumInterchainGasPaymasterInternal<M>
where where
@ -33,7 +33,7 @@ where
pub struct InterchainGasPaymasterIndexerBuilder { pub struct InterchainGasPaymasterIndexerBuilder {
pub mailbox_address: H160, pub mailbox_address: H160,
pub reorg_period: u32, pub reorg_period: EthereumReorgPeriod,
} }
#[async_trait] #[async_trait]
@ -63,7 +63,7 @@ where
{ {
contract: Arc<EthereumInterchainGasPaymasterInternal<M>>, contract: Arc<EthereumInterchainGasPaymasterInternal<M>>,
provider: Arc<M>, provider: Arc<M>,
reorg_period: u32, reorg_period: EthereumReorgPeriod,
} }
impl<M> EthereumInterchainGasPaymasterIndexer<M> impl<M> EthereumInterchainGasPaymasterIndexer<M>
@ -71,7 +71,11 @@ where
M: Middleware + 'static, M: Middleware + 'static,
{ {
/// Create new EthereumInterchainGasPaymasterIndexer /// Create new EthereumInterchainGasPaymasterIndexer
pub fn new(provider: Arc<M>, locator: &ContractLocator, reorg_period: u32) -> Self { pub fn new(
provider: Arc<M>,
locator: &ContractLocator,
reorg_period: EthereumReorgPeriod,
) -> Self {
Self { Self {
contract: Arc::new(EthereumInterchainGasPaymasterInternal::new( contract: Arc::new(EthereumInterchainGasPaymasterInternal::new(
locator.address, locator.address,
@ -122,13 +126,7 @@ where
#[instrument(level = "debug", err, ret, skip(self))] #[instrument(level = "debug", err, ret, skip(self))]
#[allow(clippy::blocks_in_conditions)] // TODO: `rustc` 1.80.1 clippy issue #[allow(clippy::blocks_in_conditions)] // TODO: `rustc` 1.80.1 clippy issue
async fn get_finalized_block_number(&self) -> ChainResult<u32> { async fn get_finalized_block_number(&self) -> ChainResult<u32> {
Ok(self get_finalized_block_number(&self.provider, &self.reorg_period).await
.provider
.get_block_number()
.await
.map_err(ChainCommunicationError::from_other)?
.as_u32()
.saturating_sub(self.reorg_period))
} }
async fn fetch_logs_by_tx_hash( async fn fetch_logs_by_tx_hash(

@ -2,7 +2,6 @@
#![allow(missing_docs)] #![allow(missing_docs)]
use std::collections::HashMap; use std::collections::HashMap;
use std::num::NonZeroU64;
use std::ops::RangeInclusive; use std::ops::RangeInclusive;
use std::sync::Arc; use std::sync::Arc;
@ -14,7 +13,7 @@ use ethers_contract::builders::ContractCall;
use ethers_contract::{Multicall, MulticallResult}; use ethers_contract::{Multicall, MulticallResult};
use futures_util::future::join_all; use futures_util::future::join_all;
use hyperlane_core::rpc_clients::call_and_retry_indefinitely; use hyperlane_core::rpc_clients::call_and_retry_indefinitely;
use hyperlane_core::{BatchResult, QueueOperation, H512}; use hyperlane_core::{BatchResult, QueueOperation, ReorgPeriod, H512};
use itertools::Itertools; use itertools::Itertools;
use tracing::instrument; use tracing::instrument;
@ -31,11 +30,14 @@ use crate::interfaces::i_mailbox::{
IMailbox as EthereumMailboxInternal, ProcessCall, IMAILBOX_ABI, IMailbox as EthereumMailboxInternal, ProcessCall, IMAILBOX_ABI,
}; };
use crate::interfaces::mailbox::DispatchFilter; use crate::interfaces::mailbox::DispatchFilter;
use crate::tx::{call_with_lag, fill_tx_gas_params, report_tx}; use crate::tx::{call_with_reorg_period, fill_tx_gas_params, report_tx};
use crate::{BuildableWithProvider, ConnectionConf, EthereumProvider, TransactionOverrides}; use crate::{
BuildableWithProvider, ConnectionConf, EthereumProvider, EthereumReorgPeriod,
TransactionOverrides,
};
use super::multicall::{self, build_multicall}; use super::multicall::{self, build_multicall};
use super::utils::fetch_raw_logs_and_meta; use super::utils::{fetch_raw_logs_and_meta, get_finalized_block_number};
impl<M> std::fmt::Display for EthereumMailboxInternal<M> impl<M> std::fmt::Display for EthereumMailboxInternal<M>
where where
@ -47,7 +49,7 @@ where
} }
pub struct SequenceIndexerBuilder { pub struct SequenceIndexerBuilder {
pub reorg_period: u32, pub reorg_period: EthereumReorgPeriod,
} }
#[async_trait] #[async_trait]
@ -70,7 +72,7 @@ impl BuildableWithProvider for SequenceIndexerBuilder {
} }
pub struct DeliveryIndexerBuilder { pub struct DeliveryIndexerBuilder {
pub reorg_period: u32, pub reorg_period: EthereumReorgPeriod,
} }
#[async_trait] #[async_trait]
@ -100,7 +102,7 @@ where
{ {
contract: Arc<EthereumMailboxInternal<M>>, contract: Arc<EthereumMailboxInternal<M>>,
provider: Arc<M>, provider: Arc<M>,
reorg_period: u32, reorg_period: EthereumReorgPeriod,
} }
impl<M> EthereumMailboxIndexer<M> impl<M> EthereumMailboxIndexer<M>
@ -108,7 +110,11 @@ where
M: Middleware + 'static, M: Middleware + 'static,
{ {
/// Create new EthereumMailboxIndexer /// Create new EthereumMailboxIndexer
pub fn new(provider: Arc<M>, locator: &ContractLocator, reorg_period: u32) -> Self { pub fn new(
provider: Arc<M>,
locator: &ContractLocator,
reorg_period: EthereumReorgPeriod,
) -> Self {
let contract = Arc::new(EthereumMailboxInternal::new( let contract = Arc::new(EthereumMailboxInternal::new(
locator.address, locator.address,
provider.clone(), provider.clone(),
@ -122,13 +128,7 @@ where
#[instrument(level = "debug", err, ret, skip(self))] #[instrument(level = "debug", err, ret, skip(self))]
async fn get_finalized_block_number(&self) -> ChainResult<u32> { async fn get_finalized_block_number(&self) -> ChainResult<u32> {
Ok(self get_finalized_block_number(&self.provider, &self.reorg_period).await
.provider
.get_block_number()
.await
.map_err(ChainCommunicationError::from_other)?
.as_u32()
.saturating_sub(self.reorg_period))
} }
} }
@ -460,8 +460,9 @@ where
M: Middleware + 'static, M: Middleware + 'static,
{ {
#[instrument(skip(self))] #[instrument(skip(self))]
async fn count(&self, maybe_lag: Option<NonZeroU64>) -> ChainResult<u32> { async fn count(&self, reorg_period: &ReorgPeriod) -> ChainResult<u32> {
let call = call_with_lag(self.contract.nonce(), &self.provider, maybe_lag).await?; let call =
call_with_reorg_period(self.contract.nonce(), &self.provider, reorg_period).await?;
let nonce = call.call().await?; let nonce = call.call().await?;
Ok(nonce) Ok(nonce)
} }

@ -1,5 +1,4 @@
#![allow(missing_docs)] #![allow(missing_docs)]
use std::num::NonZeroU64;
use std::ops::RangeInclusive; use std::ops::RangeInclusive;
use std::sync::Arc; use std::sync::Arc;
@ -10,18 +9,18 @@ use hyperlane_core::rpc_clients::call_and_retry_indefinitely;
use tracing::instrument; use tracing::instrument;
use hyperlane_core::{ use hyperlane_core::{
ChainCommunicationError, ChainResult, Checkpoint, ContractLocator, HyperlaneChain, ChainResult, Checkpoint, ContractLocator, HyperlaneChain, HyperlaneContract, HyperlaneDomain,
HyperlaneContract, HyperlaneDomain, HyperlaneProvider, Indexed, Indexer, LogMeta, HyperlaneProvider, Indexed, Indexer, LogMeta, MerkleTreeHook, MerkleTreeInsertion, ReorgPeriod,
MerkleTreeHook, MerkleTreeInsertion, SequenceAwareIndexer, H256, H512, SequenceAwareIndexer, H256, H512,
}; };
use crate::interfaces::merkle_tree_hook::{ use crate::interfaces::merkle_tree_hook::{
InsertedIntoTreeFilter, MerkleTreeHook as MerkleTreeHookContract, Tree, InsertedIntoTreeFilter, MerkleTreeHook as MerkleTreeHookContract, Tree,
}; };
use crate::tx::call_with_lag; use crate::tx::call_with_reorg_period;
use crate::{BuildableWithProvider, ConnectionConf, EthereumProvider}; use crate::{BuildableWithProvider, ConnectionConf, EthereumProvider, EthereumReorgPeriod};
use super::utils::fetch_raw_logs_and_meta; use super::utils::{fetch_raw_logs_and_meta, get_finalized_block_number};
// We don't need the reverse of this impl, so it's ok to disable the clippy lint // We don't need the reverse of this impl, so it's ok to disable the clippy lint
#[allow(clippy::from_over_into)] #[allow(clippy::from_over_into)]
@ -58,7 +57,7 @@ impl BuildableWithProvider for MerkleTreeHookBuilder {
} }
pub struct MerkleTreeHookIndexerBuilder { pub struct MerkleTreeHookIndexerBuilder {
pub reorg_period: u32, pub reorg_period: EthereumReorgPeriod,
} }
#[async_trait] #[async_trait]
@ -88,7 +87,7 @@ where
{ {
contract: Arc<MerkleTreeHookContract<M>>, contract: Arc<MerkleTreeHookContract<M>>,
provider: Arc<M>, provider: Arc<M>,
reorg_period: u32, reorg_period: EthereumReorgPeriod,
} }
impl<M> EthereumMerkleTreeHookIndexer<M> impl<M> EthereumMerkleTreeHookIndexer<M>
@ -96,7 +95,11 @@ where
M: Middleware + 'static, M: Middleware + 'static,
{ {
/// Create new EthereumMerkleTreeHookIndexer /// Create new EthereumMerkleTreeHookIndexer
pub fn new(provider: Arc<M>, locator: &ContractLocator, reorg_period: u32) -> Self { pub fn new(
provider: Arc<M>,
locator: &ContractLocator,
reorg_period: EthereumReorgPeriod,
) -> Self {
Self { Self {
contract: Arc::new(MerkleTreeHookContract::new( contract: Arc::new(MerkleTreeHookContract::new(
locator.address, locator.address,
@ -143,13 +146,7 @@ where
#[instrument(level = "debug", err, skip(self))] #[instrument(level = "debug", err, skip(self))]
#[allow(clippy::blocks_in_conditions)] // TODO: `rustc` 1.80.1 clippy issue #[allow(clippy::blocks_in_conditions)] // TODO: `rustc` 1.80.1 clippy issue
async fn get_finalized_block_number(&self) -> ChainResult<u32> { async fn get_finalized_block_number(&self) -> ChainResult<u32> {
Ok(self get_finalized_block_number(&self.provider, &self.reorg_period).await
.provider
.get_block_number()
.await
.map_err(ChainCommunicationError::from_other)?
.as_u32()
.saturating_sub(self.reorg_period))
} }
async fn fetch_logs_by_tx_hash( async fn fetch_logs_by_tx_hash(
@ -253,9 +250,13 @@ where
M: Middleware + 'static, M: Middleware + 'static,
{ {
#[instrument(skip(self))] #[instrument(skip(self))]
async fn latest_checkpoint(&self, maybe_lag: Option<NonZeroU64>) -> ChainResult<Checkpoint> { async fn latest_checkpoint(&self, reorg_period: &ReorgPeriod) -> ChainResult<Checkpoint> {
let call = let call = call_with_reorg_period(
call_with_lag(self.contract.latest_checkpoint(), &self.provider, maybe_lag).await?; self.contract.latest_checkpoint(),
&self.provider,
reorg_period,
)
.await?;
let (root, index) = call.call().await?; let (root, index) = call.call().await?;
Ok(Checkpoint { Ok(Checkpoint {
@ -268,15 +269,17 @@ where
#[instrument(skip(self))] #[instrument(skip(self))]
#[allow(clippy::needless_range_loop)] #[allow(clippy::needless_range_loop)]
async fn tree(&self, maybe_lag: Option<NonZeroU64>) -> ChainResult<IncrementalMerkle> { async fn tree(&self, reorg_period: &ReorgPeriod) -> ChainResult<IncrementalMerkle> {
let call = call_with_lag(self.contract.tree(), &self.provider, maybe_lag).await?; let call =
call_with_reorg_period(self.contract.tree(), &self.provider, reorg_period).await?;
Ok(call.call().await?.into()) Ok(call.call().await?.into())
} }
#[instrument(skip(self))] #[instrument(skip(self))]
async fn count(&self, maybe_lag: Option<NonZeroU64>) -> ChainResult<u32> { async fn count(&self, reorg_period: &ReorgPeriod) -> ChainResult<u32> {
let call = call_with_lag(self.contract.count(), &self.provider, maybe_lag).await?; let call =
call_with_reorg_period(self.contract.count(), &self.provider, reorg_period).await?;
let count = call.call().await?; let count = call.call().await?;
Ok(count) Ok(count)
} }

@ -1,5 +1,7 @@
pub use {interchain_gas::*, mailbox::*, merkle_tree_hook::*, validator_announce::*}; pub use {interchain_gas::*, mailbox::*, merkle_tree_hook::*, validator_announce::*};
pub(crate) use utils::get_finalized_block_number;
mod interchain_gas; mod interchain_gas;
mod mailbox; mod mailbox;
mod merkle_tree_hook; mod merkle_tree_hook;

@ -6,7 +6,10 @@ use ethers::{
types::{H160 as EthersH160, H256 as EthersH256}, types::{H160 as EthersH160, H256 as EthersH256},
}; };
use ethers_contract::{ContractError, EthEvent, LogMeta as EthersLogMeta}; use ethers_contract::{ContractError, EthEvent, LogMeta as EthersLogMeta};
use hyperlane_core::{ChainResult, LogMeta, H512}; use hyperlane_core::{ChainCommunicationError, ChainResult, LogMeta, H512};
use tracing::instrument;
use crate::EthereumReorgPeriod;
pub async fn fetch_raw_logs_and_meta<T: EthEvent, M>( pub async fn fetch_raw_logs_and_meta<T: EthEvent, M>(
tx_hash: H512, tx_hash: H512,
@ -44,3 +47,33 @@ where
.collect(); .collect();
Ok(logs) Ok(logs)
} }
#[instrument(level = "trace", err, ret, skip(provider))]
pub async fn get_finalized_block_number<M>(
provider: &M,
reorg_period: &EthereumReorgPeriod,
) -> ChainResult<u32>
where
M: Middleware + 'static,
{
let number = match *reorg_period {
EthereumReorgPeriod::Blocks(blocks) => provider
.get_block_number()
.await
.map_err(ChainCommunicationError::from_other)?
.as_u32()
.saturating_sub(blocks),
EthereumReorgPeriod::Tag(tag) => provider
.get_block(tag)
.await
.map_err(ChainCommunicationError::from_other)?
.and_then(|block| block.number)
.ok_or(ChainCommunicationError::CustomError(
"Unable to get finalized block number".into(),
))?
.as_u32(),
};
Ok(number)
}

@ -49,26 +49,49 @@ where
{ {
#[instrument(err, skip(self))] #[instrument(err, skip(self))]
#[allow(clippy::blocks_in_conditions)] // TODO: `rustc` 1.80.1 clippy issue #[allow(clippy::blocks_in_conditions)] // TODO: `rustc` 1.80.1 clippy issue
async fn get_block_by_hash(&self, hash: &H256) -> ChainResult<BlockInfo> { async fn get_block_by_height(&self, height: u64) -> ChainResult<BlockInfo> {
let block = get_with_retry_on_none(hash, |h| { let block = get_with_retry_on_none(
let eth_h256: ethers_core_types::H256 = h.into(); &height,
self.provider.get_block(eth_h256) |h| self.provider.get_block(*h),
}) |h| HyperlaneProviderError::CouldNotFindBlockByHeight(*h),
)
.await?; .await?;
Ok(BlockInfo {
hash: *hash, let block_height = block
.number
.ok_or(HyperlaneProviderError::CouldNotFindBlockByHeight(height))?
.as_u64();
if block_height != height {
Err(HyperlaneProviderError::IncorrectBlockByHeight(
height,
block_height,
))?;
}
let block_hash = block
.hash
.ok_or(HyperlaneProviderError::BlockWithoutHash(height))?;
let block_info = BlockInfo {
hash: block_hash.into(),
timestamp: block.timestamp.as_u64(), timestamp: block.timestamp.as_u64(),
number: block number: block_height,
.number };
.ok_or(HyperlaneProviderError::BlockIsNotPartOfChainYet(*hash))?
.as_u64(), Ok(block_info)
})
} }
#[instrument(err, skip(self))] #[instrument(err, skip(self))]
#[allow(clippy::blocks_in_conditions)] // TODO: `rustc` 1.80.1 clippy issue #[allow(clippy::blocks_in_conditions)] // TODO: `rustc` 1.80.1 clippy issue
async fn get_txn_by_hash(&self, hash: &H256) -> ChainResult<TxnInfo> { async fn get_txn_by_hash(&self, hash: &H256) -> ChainResult<TxnInfo> {
let txn = get_with_retry_on_none(hash, |h| self.provider.get_transaction(*h)).await?; let txn = get_with_retry_on_none(
hash,
|h| self.provider.get_transaction(*h),
|h| HyperlaneProviderError::CouldNotFindTransactionByHash(*h),
)
.await?;
let receipt = self let receipt = self
.provider .provider
.get_transaction_receipt(*hash) .get_transaction_receipt(*hash)
@ -193,22 +216,24 @@ impl BuildableWithProvider for HyperlaneProviderBuilder {
/// Call a get function that returns a Result<Option<T>> and retry if the inner /// Call a get function that returns a Result<Option<T>> and retry if the inner
/// option is None. This can happen because the provider has not discovered the /// option is None. This can happen because the provider has not discovered the
/// object we are looking for yet. /// object we are looking for yet.
async fn get_with_retry_on_none<T, F, O, E>(hash: &H256, get: F) -> ChainResult<T> async fn get_with_retry_on_none<T, F, O, E, I, N>(
id: &I,
get: F,
not_found_error: N,
) -> ChainResult<T>
where where
F: Fn(&H256) -> O, F: Fn(&I) -> O,
O: Future<Output = Result<Option<T>, E>>, O: Future<Output = Result<Option<T>, E>>,
E: std::error::Error + Send + Sync + 'static, E: std::error::Error + Send + Sync + 'static,
N: Fn(&I) -> HyperlaneProviderError,
{ {
for _ in 0..3 { for _ in 0..3 {
if let Some(t) = get(hash) if let Some(t) = get(id).await.map_err(ChainCommunicationError::from_other)? {
.await
.map_err(ChainCommunicationError::from_other)?
{
return Ok(t); return Ok(t);
} else { } else {
sleep(Duration::from_secs(5)).await; sleep(Duration::from_secs(5)).await;
continue; continue;
}; };
} }
Err(HyperlaneProviderError::CouldNotFindObjectByHash(*hash).into()) Err(not_found_error(id).into())
} }

@ -1,4 +1,3 @@
use std::num::NonZeroU64;
use std::sync::Arc; use std::sync::Arc;
use std::time::Duration; use std::time::Duration;
@ -16,10 +15,12 @@ use ethers_core::{
EIP1559_FEE_ESTIMATION_REWARD_PERCENTILE, EIP1559_FEE_ESTIMATION_REWARD_PERCENTILE,
}, },
}; };
use hyperlane_core::{utils::bytes_to_hex, ChainCommunicationError, ChainResult, H256, U256}; use hyperlane_core::{
utils::bytes_to_hex, ChainCommunicationError, ChainResult, ReorgPeriod, H256, U256,
};
use tracing::{debug, error, info, warn}; use tracing::{debug, error, info, warn};
use crate::{Middleware, TransactionOverrides}; use crate::{EthereumReorgPeriod, Middleware, TransactionOverrides};
/// An amount of gas to add to the estimated gas /// An amount of gas to add to the estimated gas
pub const GAS_ESTIMATE_BUFFER: u32 = 75_000; pub const GAS_ESTIMATE_BUFFER: u32 = 75_000;
@ -216,23 +217,20 @@ where
Ok((base_fee_per_gas, max_fee_per_gas, max_priority_fee_per_gas)) Ok((base_fee_per_gas, max_fee_per_gas, max_priority_fee_per_gas))
} }
pub(crate) async fn call_with_lag<M, T>( pub(crate) async fn call_with_reorg_period<M, T>(
call: ethers::contract::builders::ContractCall<M, T>, call: ethers::contract::builders::ContractCall<M, T>,
provider: &M, provider: &M,
maybe_lag: Option<NonZeroU64>, reorg_period: &ReorgPeriod,
) -> ChainResult<ethers::contract::builders::ContractCall<M, T>> ) -> ChainResult<ethers::contract::builders::ContractCall<M, T>>
where where
M: Middleware + 'static, M: Middleware + 'static,
T: Detokenize, T: Detokenize,
{ {
if let Some(lag) = maybe_lag { if !reorg_period.is_none() {
let fixed_block_number: BlockNumber = provider let block_id = EthereumReorgPeriod::try_from(reorg_period)?
.get_block_number() .into_block_id(provider)
.await .await?;
.map_err(ChainCommunicationError::from_other)? Ok(call.block(block_id))
.saturating_sub(lag.get().into())
.into();
Ok(call.block(fixed_block_number))
} else { } else {
Ok(call) Ok(call)
} }

@ -10,13 +10,12 @@ use fuels::{
use hyperlane_core::{ use hyperlane_core::{
utils::bytes_to_hex, ChainCommunicationError, ChainResult, ContractLocator, HyperlaneAbi, utils::bytes_to_hex, ChainCommunicationError, ChainResult, ContractLocator, HyperlaneAbi,
HyperlaneChain, HyperlaneContract, HyperlaneDomain, HyperlaneMessage, HyperlaneProvider, HyperlaneChain, HyperlaneContract, HyperlaneDomain, HyperlaneMessage, HyperlaneProvider,
Indexed, Indexer, LogMeta, Mailbox, RawHyperlaneMessage, SequenceAwareIndexer, TxCostEstimate, Indexed, Indexer, LogMeta, Mailbox, RawHyperlaneMessage, ReorgPeriod, SequenceAwareIndexer,
TxOutcome, H256, H512, U256, TxCostEstimate, TxOutcome, H256, H512, U256,
}; };
use std::{ use std::{
collections::HashMap, collections::HashMap,
fmt::{Debug, Formatter}, fmt::{Debug, Formatter},
num::NonZeroU64,
ops::RangeInclusive, ops::RangeInclusive,
}; };
use tracing::{instrument, warn}; use tracing::{instrument, warn};
@ -74,9 +73,9 @@ impl Debug for FuelMailbox {
impl Mailbox for FuelMailbox { impl Mailbox for FuelMailbox {
#[instrument(level = "debug", err, ret, skip(self))] #[instrument(level = "debug", err, ret, skip(self))]
#[allow(clippy::blocks_in_conditions)] // TODO: `rustc` 1.80.1 clippy issue #[allow(clippy::blocks_in_conditions)] // TODO: `rustc` 1.80.1 clippy issue
async fn count(&self, lag: Option<NonZeroU64>) -> ChainResult<u32> { async fn count(&self, reorg_period: &ReorgPeriod) -> ChainResult<u32> {
assert!( assert!(
lag.is_none(), reorg_period.is_none(),
"Fuel does not support querying point-in-time" "Fuel does not support querying point-in-time"
); );
self.contract self.contract

@ -1,7 +1,6 @@
use std::{collections::HashMap, ops::Deref}; use std::{collections::HashMap, ops::Deref};
use async_trait::async_trait; use async_trait::async_trait;
use fuels::{ use fuels::{
client::{FuelClient, PageDirection, PaginationRequest}, client::{FuelClient, PageDirection, PaginationRequest},
prelude::Provider, prelude::Provider,
@ -13,13 +12,14 @@ use fuels::{
transaction::{Transaction, TransactionType}, transaction::{Transaction, TransactionType},
transaction_response::TransactionResponse, transaction_response::TransactionResponse,
tx_status::TxStatus, tx_status::TxStatus,
Address, Bytes32, ContractId, Address, BlockHeight, Bytes32, ContractId,
}, },
}; };
use futures::future::join_all; use futures::future::join_all;
use hyperlane_core::{ use hyperlane_core::{
BlockInfo, ChainCommunicationError, ChainInfo, ChainResult, HyperlaneChain, HyperlaneDomain, BlockInfo, ChainCommunicationError, ChainInfo, ChainResult, HyperlaneChain, HyperlaneDomain,
HyperlaneMessage, HyperlaneProvider, Indexed, LogMeta, TxnInfo, H256, H512, U256, HyperlaneMessage, HyperlaneProvider, HyperlaneProviderError, Indexed, LogMeta, TxnInfo, H256,
H512, U256,
}; };
use crate::{make_client, make_provider, prelude::FuelIntoH256, ConnectionConf}; use crate::{make_client, make_provider, prelude::FuelIntoH256, ConnectionConf};
@ -285,19 +285,30 @@ impl HyperlaneChain for FuelProvider {
impl HyperlaneProvider for FuelProvider { impl HyperlaneProvider for FuelProvider {
/// Used by scraper /// Used by scraper
#[allow(clippy::clone_on_copy)] // TODO: `rustc` 1.80.1 clippy issue #[allow(clippy::clone_on_copy)] // TODO: `rustc` 1.80.1 clippy issue
async fn get_block_by_hash(&self, hash: &H256) -> ChainResult<BlockInfo> { async fn get_block_by_height(&self, height: u64) -> ChainResult<BlockInfo> {
let block_res = self.provider.block(&hash.0.into()).await.map_err(|e| { let block_res = self
ChainCommunicationError::CustomError(format!("Failed to get block: {}", e)) .provider
})?; .block_by_height(BlockHeight::new(height as u32))
.await
.map_err(|e| HyperlaneProviderError::CouldNotFindBlockByHeight(height))?;
match block_res { let block_info = match block_res {
Some(block) => Ok(BlockInfo { Some(block) => BlockInfo {
hash: H256::from_slice(block.id.as_slice()), hash: H256::from_slice(block.id.as_slice()),
number: block.header.height.into(),
timestamp: block.header.time.map_or(0, |t| t.timestamp() as u64), timestamp: block.header.time.map_or(0, |t| t.timestamp() as u64),
}), number: block.header.height.into(),
None => Err(ChainCommunicationError::BlockNotFound(hash.clone())), },
None => Err(HyperlaneProviderError::CouldNotFindBlockByHeight(height))?,
};
if block_info.number != height {
Err(HyperlaneProviderError::IncorrectBlockByHeight(
height,
block_info.number,
))?;
} }
Ok(block_info)
} }
/// Used by scraper /// Used by scraper

@ -14,6 +14,9 @@ pub enum HyperlaneSealevelError {
/// ClientError error /// ClientError error
#[error("{0}")] #[error("{0}")]
ClientError(#[from] ClientError), ClientError(#[from] ClientError),
/// Decoding error
#[error("{0}")]
Decoding(#[from] solana_sdk::bs58::decode::Error),
} }
impl From<HyperlaneSealevelError> for ChainCommunicationError { impl From<HyperlaneSealevelError> for ChainCommunicationError {

@ -12,8 +12,8 @@ use hyperlane_core::{
ChainCommunicationError::ContractError, ChainResult, Checkpoint, ContractLocator, Decode as _, ChainCommunicationError::ContractError, ChainResult, Checkpoint, ContractLocator, Decode as _,
Encode as _, FixedPointNumber, HyperlaneAbi, HyperlaneChain, HyperlaneContract, Encode as _, FixedPointNumber, HyperlaneAbi, HyperlaneChain, HyperlaneContract,
HyperlaneDomain, HyperlaneMessage, HyperlaneProvider, Indexed, Indexer, KnownHyperlaneDomain, HyperlaneDomain, HyperlaneMessage, HyperlaneProvider, Indexed, Indexer, KnownHyperlaneDomain,
LogMeta, Mailbox, MerkleTreeHook, SequenceAwareIndexer, TxCostEstimate, TxOutcome, H256, H512, LogMeta, Mailbox, MerkleTreeHook, ReorgPeriod, SequenceAwareIndexer, TxCostEstimate, TxOutcome,
U256, H256, H512, U256,
}; };
use hyperlane_sealevel_interchain_security_module_interface::{ use hyperlane_sealevel_interchain_security_module_interface::{
InterchainSecurityModuleInstruction, VerifyInstruction, InterchainSecurityModuleInstruction, VerifyInstruction,
@ -416,8 +416,8 @@ impl std::fmt::Debug for SealevelMailbox {
#[async_trait] #[async_trait]
impl Mailbox for SealevelMailbox { impl Mailbox for SealevelMailbox {
#[instrument(err, ret, skip(self))] #[instrument(err, ret, skip(self))]
async fn count(&self, _maybe_lag: Option<NonZeroU64>) -> ChainResult<u32> { async fn count(&self, reorg_period: &ReorgPeriod) -> ChainResult<u32> {
<Self as MerkleTreeHook>::count(self, _maybe_lag).await <Self as MerkleTreeHook>::count(self, reorg_period).await
} }
#[instrument(err, ret, skip(self))] #[instrument(err, ret, skip(self))]
@ -430,7 +430,7 @@ impl Mailbox for SealevelMailbox {
let account = self let account = self
.rpc() .rpc()
.get_possible_account_with_finalized_commitment(&processed_message_account_key) .get_account_option_with_finalized_commitment(&processed_message_account_key)
.await?; .await?;
Ok(account.is_some()) Ok(account.is_some())
@ -755,7 +755,7 @@ impl SequenceAwareIndexer<HyperlaneMessage> for SealevelMailboxIndexer {
async fn latest_sequence_count_and_tip(&self) -> ChainResult<(Option<u32>, u32)> { async fn latest_sequence_count_and_tip(&self) -> ChainResult<(Option<u32>, u32)> {
let tip = Indexer::<HyperlaneMessage>::get_finalized_block_number(self).await?; let tip = Indexer::<HyperlaneMessage>::get_finalized_block_number(self).await?;
// TODO: need to make sure the call and tip are at the same height? // TODO: need to make sure the call and tip are at the same height?
let count = Mailbox::count(&self.mailbox, None).await?; let count = Mailbox::count(&self.mailbox, &ReorgPeriod::None).await?;
Ok((Some(count), tip)) Ok((Some(count), tip))
} }
} }

@ -1,11 +1,11 @@
use std::{num::NonZeroU64, ops::RangeInclusive}; use std::ops::RangeInclusive;
use async_trait::async_trait; use async_trait::async_trait;
use derive_new::new; use derive_new::new;
use hyperlane_core::{ use hyperlane_core::{
accumulator::incremental::IncrementalMerkle, ChainCommunicationError, ChainResult, Checkpoint, accumulator::incremental::IncrementalMerkle, ChainCommunicationError, ChainResult, Checkpoint,
HyperlaneChain, HyperlaneMessage, Indexed, Indexer, LogMeta, MerkleTreeHook, HyperlaneChain, HyperlaneMessage, Indexed, Indexer, LogMeta, MerkleTreeHook,
MerkleTreeInsertion, SequenceAwareIndexer, MerkleTreeInsertion, ReorgPeriod, SequenceAwareIndexer,
}; };
use hyperlane_sealevel_mailbox::accounts::OutboxAccount; use hyperlane_sealevel_mailbox::accounts::OutboxAccount;
use tracing::instrument; use tracing::instrument;
@ -16,9 +16,9 @@ use crate::{SealevelMailbox, SealevelMailboxIndexer};
impl MerkleTreeHook for SealevelMailbox { impl MerkleTreeHook for SealevelMailbox {
#[instrument(err, ret, skip(self))] #[instrument(err, ret, skip(self))]
#[allow(clippy::blocks_in_conditions)] // TODO: `rustc` 1.80.1 clippy issue #[allow(clippy::blocks_in_conditions)] // TODO: `rustc` 1.80.1 clippy issue
async fn tree(&self, lag: Option<NonZeroU64>) -> ChainResult<IncrementalMerkle> { async fn tree(&self, reorg_period: &ReorgPeriod) -> ChainResult<IncrementalMerkle> {
assert!( assert!(
lag.is_none(), reorg_period.is_none(),
"Sealevel does not support querying point-in-time" "Sealevel does not support querying point-in-time"
); );
@ -35,13 +35,13 @@ impl MerkleTreeHook for SealevelMailbox {
#[instrument(err, ret, skip(self))] #[instrument(err, ret, skip(self))]
#[allow(clippy::blocks_in_conditions)] // TODO: `rustc` 1.80.1 clippy issue #[allow(clippy::blocks_in_conditions)] // TODO: `rustc` 1.80.1 clippy issue
async fn latest_checkpoint(&self, lag: Option<NonZeroU64>) -> ChainResult<Checkpoint> { async fn latest_checkpoint(&self, reorg_period: &ReorgPeriod) -> ChainResult<Checkpoint> {
assert!( assert!(
lag.is_none(), reorg_period.is_none(),
"Sealevel does not support querying point-in-time" "Sealevel does not support querying point-in-time"
); );
let tree = self.tree(lag).await?; let tree = self.tree(reorg_period).await?;
let root = tree.root(); let root = tree.root();
let count: u32 = tree let count: u32 = tree
@ -64,8 +64,8 @@ impl MerkleTreeHook for SealevelMailbox {
#[instrument(err, ret, skip(self))] #[instrument(err, ret, skip(self))]
#[allow(clippy::blocks_in_conditions)] // TODO: `rustc` 1.80.1 clippy issue #[allow(clippy::blocks_in_conditions)] // TODO: `rustc` 1.80.1 clippy issue
async fn count(&self, _maybe_lag: Option<NonZeroU64>) -> ChainResult<u32> { async fn count(&self, reorg_period: &ReorgPeriod) -> ChainResult<u32> {
let tree = self.tree(_maybe_lag).await?; let tree = self.tree(reorg_period).await?;
tree.count() tree.count()
.try_into() .try_into()

@ -1,11 +1,11 @@
use std::{str::FromStr, sync::Arc}; use std::{str::FromStr, sync::Arc};
use async_trait::async_trait; use async_trait::async_trait;
use hyperlane_core::{ use hyperlane_core::{
BlockInfo, ChainInfo, ChainResult, HyperlaneChain, HyperlaneDomain, HyperlaneProvider, TxnInfo, BlockInfo, ChainInfo, ChainResult, HyperlaneChain, HyperlaneDomain, HyperlaneProvider,
H256, U256, HyperlaneProviderError, TxnInfo, H256, U256,
}; };
use solana_sdk::bs58;
use solana_sdk::pubkey::Pubkey; use solana_sdk::pubkey::Pubkey;
use crate::{error::HyperlaneSealevelError, ConnectionConf, SealevelRpcClient}; use crate::{error::HyperlaneSealevelError, ConnectionConf, SealevelRpcClient};
@ -47,8 +47,25 @@ impl HyperlaneChain for SealevelProvider {
#[async_trait] #[async_trait]
impl HyperlaneProvider for SealevelProvider { impl HyperlaneProvider for SealevelProvider {
async fn get_block_by_hash(&self, _hash: &H256) -> ChainResult<BlockInfo> { async fn get_block_by_height(&self, slot: u64) -> ChainResult<BlockInfo> {
todo!() // FIXME let confirmed_block = self.rpc_client.get_block(slot).await?;
let hash_binary = bs58::decode(confirmed_block.blockhash)
.into_vec()
.map_err(HyperlaneSealevelError::Decoding)?;
let block_hash = H256::from_slice(&hash_binary);
let block_time = confirmed_block
.block_time
.ok_or(HyperlaneProviderError::CouldNotFindBlockByHeight(slot))?;
let block_info = BlockInfo {
hash: block_hash,
timestamp: block_time as u64,
number: slot,
};
Ok(block_info)
} }
async fn get_txn_by_hash(&self, _hash: &H256) -> ChainResult<TxnInfo> { async fn get_txn_by_hash(&self, _hash: &H256) -> ChainResult<TxnInfo> {

@ -3,8 +3,8 @@ use borsh::{BorshDeserialize, BorshSerialize};
use hyperlane_core::{ChainCommunicationError, ChainResult, U256}; use hyperlane_core::{ChainCommunicationError, ChainResult, U256};
use serializable_account_meta::{SerializableAccountMeta, SimulationReturnData}; use serializable_account_meta::{SerializableAccountMeta, SimulationReturnData};
use solana_client::{ use solana_client::{
nonblocking::rpc_client::RpcClient, rpc_config::RpcProgramAccountsConfig, nonblocking::rpc_client::RpcClient, rpc_config::RpcBlockConfig,
rpc_response::Response, rpc_config::RpcProgramAccountsConfig, rpc_response::Response,
}; };
use solana_sdk::{ use solana_sdk::{
account::Account, account::Account,
@ -16,7 +16,9 @@ use solana_sdk::{
signature::{Keypair, Signature, Signer}, signature::{Keypair, Signature, Signer},
transaction::Transaction, transaction::Transaction,
}; };
use solana_transaction_status::{TransactionStatus, UiReturnDataEncoding, UiTransactionReturnData}; use solana_transaction_status::{
TransactionStatus, UiConfirmedBlock, UiReturnDataEncoding, UiTransactionReturnData,
};
use crate::error::HyperlaneSealevelError; use crate::error::HyperlaneSealevelError;
@ -79,12 +81,12 @@ impl SealevelRpcClient {
&self, &self,
pubkey: &Pubkey, pubkey: &Pubkey,
) -> ChainResult<Account> { ) -> ChainResult<Account> {
self.get_possible_account_with_finalized_commitment(pubkey) self.get_account_option_with_finalized_commitment(pubkey)
.await? .await?
.ok_or_else(|| ChainCommunicationError::from_other_str("Could not find account data")) .ok_or_else(|| ChainCommunicationError::from_other_str("Could not find account data"))
} }
pub async fn get_possible_account_with_finalized_commitment( pub async fn get_account_option_with_finalized_commitment(
&self, &self,
pubkey: &Pubkey, pubkey: &Pubkey,
) -> ChainResult<Option<Account>> { ) -> ChainResult<Option<Account>> {
@ -97,6 +99,19 @@ impl SealevelRpcClient {
Ok(account) Ok(account)
} }
pub async fn get_block(&self, height: u64) -> ChainResult<UiConfirmedBlock> {
let config = RpcBlockConfig {
commitment: Some(CommitmentConfig::finalized()),
max_supported_transaction_version: Some(0),
..Default::default()
};
self.0
.get_block_with_config(height, config)
.await
.map_err(HyperlaneSealevelError::ClientError)
.map_err(Into::into)
}
pub async fn get_block_height(&self) -> ChainResult<u32> { pub async fn get_block_height(&self) -> ChainResult<u32> {
let height = self let height = self
.0 .0

@ -34,7 +34,7 @@
"interchainAccountIsm": "0xd766e7C7517f2d0D92754b2fe4aE7AdEf7bDEC3e", "interchainAccountIsm": "0xd766e7C7517f2d0D92754b2fe4aE7AdEf7bDEC3e",
"interchainAccountRouter": "0x25C87e735021F72d8728438C2130b02E3141f2cb", "interchainAccountRouter": "0x25C87e735021F72d8728438C2130b02E3141f2cb",
"interchainGasPaymaster": "0x8F1E22d309baa69D398a03cc88E9b46037e988AA", "interchainGasPaymaster": "0x8F1E22d309baa69D398a03cc88E9b46037e988AA",
"interchainSecurityModule": "0x565C280Cdb56095Cf6BF23b5fF140180208CBa9e", "interchainSecurityModule": "0x4e1d2cdB48A2C2912b11801Eb1F1d5007474cA43",
"isTestnet": false, "isTestnet": false,
"mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7",
"merkleTreeHook": "0x811808Dd29ba8B0FC6C0ec0b5537035E59745162", "merkleTreeHook": "0x811808Dd29ba8B0FC6C0ec0b5537035E59745162",
@ -100,7 +100,7 @@
"interchainAccountIsm": "0x2A7574358Ec53522CE2452887661AB4c86F7d400", "interchainAccountIsm": "0x2A7574358Ec53522CE2452887661AB4c86F7d400",
"interchainAccountRouter": "0x91874Dbed74925dFe6059B90385EEb90DdE0B2E6", "interchainAccountRouter": "0x91874Dbed74925dFe6059B90385EEb90DdE0B2E6",
"interchainGasPaymaster": "0x3b6044acd6767f017e99318AA6Ef93b7B06A5a22", "interchainGasPaymaster": "0x3b6044acd6767f017e99318AA6Ef93b7B06A5a22",
"interchainSecurityModule": "0x3d0BE14dFbB1Eb736303260c1724B6ea270c8Dc4", "interchainSecurityModule": "0x50d0b0E27B8B93119618f053A623886116dd3b6d",
"mailbox": "0x979Ca5202784112f4738403dBec5D0F3B9daabB9", "mailbox": "0x979Ca5202784112f4738403dBec5D0F3B9daabB9",
"merkleTreeHook": "0x748040afB89B8FdBb992799808215419d36A0930", "merkleTreeHook": "0x748040afB89B8FdBb992799808215419d36A0930",
"name": "arbitrum", "name": "arbitrum",
@ -172,7 +172,7 @@
"interchainAccountIsm": "0x27a3233c05C1Df7c163123301D14bE9349E3Cb48", "interchainAccountIsm": "0x27a3233c05C1Df7c163123301D14bE9349E3Cb48",
"interchainAccountRouter": "0xa82a0227e6d6db53AF4B264A852bfF91C6504a51", "interchainAccountRouter": "0xa82a0227e6d6db53AF4B264A852bfF91C6504a51",
"interchainGasPaymaster": "0x95519ba800BBd0d34eeAE026fEc620AD978176C0", "interchainGasPaymaster": "0x95519ba800BBd0d34eeAE026fEc620AD978176C0",
"interchainSecurityModule": "0x6723A49c12FE37ccBD08512dd586C8471743676f", "interchainSecurityModule": "0xbc803Da34A88E5f6B50dfc0CC9D924d9865c91C5",
"mailbox": "0xFf06aFcaABaDDd1fb08371f9ccA15D73D51FeBD6", "mailbox": "0xFf06aFcaABaDDd1fb08371f9ccA15D73D51FeBD6",
"merkleTreeHook": "0x84eea61D679F42D92145fA052C89900CBAccE95A", "merkleTreeHook": "0x84eea61D679F42D92145fA052C89900CBAccE95A",
"name": "avalanche", "name": "avalanche",
@ -245,7 +245,7 @@
"interchainAccountIsm": "0x223F7D3f27E6272266AE4B5B91Fd5C7A2d798cD8", "interchainAccountIsm": "0x223F7D3f27E6272266AE4B5B91Fd5C7A2d798cD8",
"interchainAccountRouter": "0x4767D22117bBeeb295413000B620B93FD8522d53", "interchainAccountRouter": "0x4767D22117bBeeb295413000B620B93FD8522d53",
"interchainGasPaymaster": "0xc3F23848Ed2e04C0c6d41bd7804fa8f89F940B94", "interchainGasPaymaster": "0xc3F23848Ed2e04C0c6d41bd7804fa8f89F940B94",
"interchainSecurityModule": "0xaeEf8f7D049C03181E0B5f2746CA2Db4d25C0B82", "interchainSecurityModule": "0xB7fcb4665ace2B0d36fd92D26b4a8B516c0bFe5F",
"mailbox": "0xeA87ae93Fa0019a82A727bfd3eBd1cFCa8f64f1D", "mailbox": "0xeA87ae93Fa0019a82A727bfd3eBd1cFCa8f64f1D",
"merkleTreeHook": "0x19dc38aeae620380430C200a6E990D5Af5480117", "merkleTreeHook": "0x19dc38aeae620380430C200a6E990D5Af5480117",
"name": "base", "name": "base",
@ -316,7 +316,7 @@
"interchainAccountIsm": "0xe93f2f409ad8B5000431D234472973fe848dcBEC", "interchainAccountIsm": "0xe93f2f409ad8B5000431D234472973fe848dcBEC",
"interchainAccountRouter": "0x2f4Eb04189e11Af642237Da62d163Ab714614498", "interchainAccountRouter": "0x2f4Eb04189e11Af642237Da62d163Ab714614498",
"interchainGasPaymaster": "0xB3fCcD379ad66CED0c91028520C64226611A48c9", "interchainGasPaymaster": "0xB3fCcD379ad66CED0c91028520C64226611A48c9",
"interchainSecurityModule": "0xbCe3469E8C270e04ea9ccd20Efdeed2b90c9d57C", "interchainSecurityModule": "0xECa4a584E91867a72cd036DB7Db22Ad894a197B7",
"mailbox": "0x3a867fCfFeC2B790970eeBDC9023E75B0a172aa7", "mailbox": "0x3a867fCfFeC2B790970eeBDC9023E75B0a172aa7",
"merkleTreeHook": "0xC9B8ea6230d6687a4b13fD3C0b8f0Ec607B26465", "merkleTreeHook": "0xC9B8ea6230d6687a4b13fD3C0b8f0Ec607B26465",
"name": "blast", "name": "blast",
@ -384,7 +384,7 @@
"interchainAccountIsm": "0x451dF8AB0936D85526D816f0b4dCaDD934A034A4", "interchainAccountIsm": "0x451dF8AB0936D85526D816f0b4dCaDD934A034A4",
"interchainAccountRouter": "0x5C02157068a52cEcfc98EDb6115DE6134EcB4764", "interchainAccountRouter": "0x5C02157068a52cEcfc98EDb6115DE6134EcB4764",
"interchainGasPaymaster": "0x62B7592C1B6D1E43f4630B8e37f4377097840C05", "interchainGasPaymaster": "0x62B7592C1B6D1E43f4630B8e37f4377097840C05",
"interchainSecurityModule": "0x26eA240CB4cABd7B75A9F17E7f4e224170270Ee3", "interchainSecurityModule": "0x93E3e6CA295803417212421785606B1F7dDeaD8f",
"mailbox": "0x8358D8291e3bEDb04804975eEa0fe9fe0fAfB147", "mailbox": "0x8358D8291e3bEDb04804975eEa0fe9fe0fAfB147",
"merkleTreeHook": "0x781bE492F1232E66990d83a9D3AC3Ec26f56DAfB", "merkleTreeHook": "0x781bE492F1232E66990d83a9D3AC3Ec26f56DAfB",
"name": "bob", "name": "bob",
@ -429,7 +429,7 @@
"blocks": { "blocks": {
"confirmations": 1, "confirmations": 1,
"estimateBlockTime": 3, "estimateBlockTime": 3,
"reorgPeriod": 15 "reorgPeriod": "finalized"
}, },
"chainId": 56, "chainId": 56,
"deployer": { "deployer": {
@ -450,7 +450,7 @@
"interchainAccountIsm": "0x9e22945bE593946618383B108CC5bce09eBA4C26", "interchainAccountIsm": "0x9e22945bE593946618383B108CC5bce09eBA4C26",
"interchainAccountRouter": "0x32A07c1B7a7fe8D4A0e44B0181873aB9d64C16c1", "interchainAccountRouter": "0x32A07c1B7a7fe8D4A0e44B0181873aB9d64C16c1",
"interchainGasPaymaster": "0x78E25e7f84416e69b9339B0A6336EB6EFfF6b451", "interchainGasPaymaster": "0x78E25e7f84416e69b9339B0A6336EB6EFfF6b451",
"interchainSecurityModule": "0x0A7cE15E3cc638abC3B5FfA7Fc8F3295Ae3595D1", "interchainSecurityModule": "0xA0506B5b12770494740A4a7cc86C9A36Dc1Fc6Dc",
"mailbox": "0x2971b9Aec44bE4eb673DF1B88cDB57b96eefe8a4", "mailbox": "0x2971b9Aec44bE4eb673DF1B88cDB57b96eefe8a4",
"merkleTreeHook": "0xFDb9Cd5f9daAA2E4474019405A328a88E7484f26", "merkleTreeHook": "0xFDb9Cd5f9daAA2E4474019405A328a88E7484f26",
"name": "bsc", "name": "bsc",
@ -531,7 +531,7 @@
"interchainAccountIsm": "0xB732c83aeE29596E3163Da2260710eAB67Bc0B29", "interchainAccountIsm": "0xB732c83aeE29596E3163Da2260710eAB67Bc0B29",
"interchainAccountRouter": "0x27a6cAe33378bB6A6663b382070427A01fc9cB37", "interchainAccountRouter": "0x27a6cAe33378bB6A6663b382070427A01fc9cB37",
"interchainGasPaymaster": "0x571f1435613381208477ac5d6974310d88AC7cB7", "interchainGasPaymaster": "0x571f1435613381208477ac5d6974310d88AC7cB7",
"interchainSecurityModule": "0x33BC62504248F4cb43813532067ccAEd46a5e61C", "interchainSecurityModule": "0xa6f4835940dbA46E295076D0CD0411349C33789f",
"mailbox": "0x50da3B3907A08a24fe4999F4Dcf337E8dC7954bb", "mailbox": "0x50da3B3907A08a24fe4999F4Dcf337E8dC7954bb",
"merkleTreeHook": "0x04dB778f05854f26E67e0a66b740BBbE9070D366", "merkleTreeHook": "0x04dB778f05854f26E67e0a66b740BBbE9070D366",
"name": "celo", "name": "celo",
@ -596,7 +596,7 @@
"interchainAccountIsm": "0x4Eb82Ee35b0a1c1d776E3a3B547f9A9bA6FCC9f2", "interchainAccountIsm": "0x4Eb82Ee35b0a1c1d776E3a3B547f9A9bA6FCC9f2",
"interchainAccountRouter": "0xEF9A332Ec1fD233Bf9344A58be56ff9E104B4f60", "interchainAccountRouter": "0xEF9A332Ec1fD233Bf9344A58be56ff9E104B4f60",
"interchainGasPaymaster": "0x7E27456a839BFF31CA642c060a2b68414Cb6e503", "interchainGasPaymaster": "0x7E27456a839BFF31CA642c060a2b68414Cb6e503",
"interchainSecurityModule": "0xc1FF2bf7a4C315bE2a06941D236457EB02F93993", "interchainSecurityModule": "0x05f6BAa16F1aCf7b19c4A09E019D856c10ab8355",
"mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7",
"merkleTreeHook": "0x0054D19613f20dD72721A146ED408971a2CCA9BD", "merkleTreeHook": "0x0054D19613f20dD72721A146ED408971a2CCA9BD",
"name": "cheesechain", "name": "cheesechain",
@ -659,7 +659,7 @@
"from": 4842212 "from": 4842212
}, },
"interchainGasPaymaster": "0x9844aFFaBE17c37F791ff99ABa58B0FbB75e22AF", "interchainGasPaymaster": "0x9844aFFaBE17c37F791ff99ABa58B0FbB75e22AF",
"interchainSecurityModule": "0xEfFaEddFf4FFd6F8a6D714bf149b114fD34E5Fd4", "interchainSecurityModule": "0x9A746C4BC2bE7E657A3469f0a0DAA1dE517b8514",
"mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7",
"merkleTreeHook": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a", "merkleTreeHook": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a",
"name": "cyber", "name": "cyber",
@ -726,7 +726,7 @@
"from": 23783929 "from": 23783929
}, },
"interchainGasPaymaster": "0x9844aFFaBE17c37F791ff99ABa58B0FbB75e22AF", "interchainGasPaymaster": "0x9844aFFaBE17c37F791ff99ABa58B0FbB75e22AF",
"interchainSecurityModule": "0xB5e6AA45E117f9fD2a3F8e78432fCAfdB833d316", "interchainSecurityModule": "0x168E9C1481F50E66Cc5F5E24b04eBf7071629c4E",
"mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7",
"merkleTreeHook": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a", "merkleTreeHook": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a",
"name": "degenchain", "name": "degenchain",
@ -784,7 +784,8 @@
"gasCurrencyCoinGeckoId": "ethereum", "gasCurrencyCoinGeckoId": "ethereum",
"index": { "index": {
"from": 1, "from": 1,
"mode": "sequence" "mode": "sequence",
"chunk": 100
}, },
"interchainGasPaymaster": "ABb3i11z7wKoGCfeRQNQbVYWjAm7jG7HzZnDLV4RKRbK", "interchainGasPaymaster": "ABb3i11z7wKoGCfeRQNQbVYWjAm7jG7HzZnDLV4RKRbK",
"mailbox": "EitxJuv2iBjsg2d7jVy2LDC1e2zBrx4GB5Y9h2Ko3A9Y", "mailbox": "EitxJuv2iBjsg2d7jVy2LDC1e2zBrx4GB5Y9h2Ko3A9Y",
@ -838,7 +839,7 @@
"interchainAccountIsm": "0xCeafc098e5c3c7768b9229Be2FEC275862A81Abd", "interchainAccountIsm": "0xCeafc098e5c3c7768b9229Be2FEC275862A81Abd",
"interchainAccountRouter": "0xed9a722c543883FB7e07E78F3879762DE09eA7D5", "interchainAccountRouter": "0xed9a722c543883FB7e07E78F3879762DE09eA7D5",
"interchainGasPaymaster": "0xB30EAB08aa87138D57168D0e236850A530f49921", "interchainGasPaymaster": "0xB30EAB08aa87138D57168D0e236850A530f49921",
"interchainSecurityModule": "0xC0737f1EA1d0aF287c2804090370b1715c593385", "interchainSecurityModule": "0x094120BaC576aD7D88ec6893C9B220a0e64923E9",
"mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7",
"merkleTreeHook": "0xC831271c1fB212012811a91Dd43e5926C1020563", "merkleTreeHook": "0xC831271c1fB212012811a91Dd43e5926C1020563",
"name": "endurance", "name": "endurance",
@ -909,7 +910,7 @@
"interchainAccountIsm": "0x292C614ED53DaaDBf971521bc2C652d1ca51cB47", "interchainAccountIsm": "0x292C614ED53DaaDBf971521bc2C652d1ca51cB47",
"interchainAccountRouter": "0x5E532F7B610618eE73C2B462978e94CB1F7995Ce", "interchainAccountRouter": "0x5E532F7B610618eE73C2B462978e94CB1F7995Ce",
"interchainGasPaymaster": "0x9e6B1022bE9BBF5aFd152483DAD9b88911bC8611", "interchainGasPaymaster": "0x9e6B1022bE9BBF5aFd152483DAD9b88911bC8611",
"interchainSecurityModule": "0xFc440a9c946Bf4840623E4adf49646089361584a", "interchainSecurityModule": "0x23d160e4474Ce011829c71Bf1bCaA40F0b5612D5",
"mailbox": "0xc005dc82818d67AF737725bD4bf75435d065D239", "mailbox": "0xc005dc82818d67AF737725bD4bf75435d065D239",
"merkleTreeHook": "0x48e6c30B97748d1e2e03bf3e9FbE3890ca5f8CCA", "merkleTreeHook": "0x48e6c30B97748d1e2e03bf3e9FbE3890ca5f8CCA",
"name": "ethereum", "name": "ethereum",
@ -978,7 +979,7 @@
"interchainAccountIsm": "0x7C012DCA02C42cfA3Fd7Da3B0ED7234B52AE68eF", "interchainAccountIsm": "0x7C012DCA02C42cfA3Fd7Da3B0ED7234B52AE68eF",
"interchainAccountRouter": "0xbed53B5C5BCE9433f25A2A702e6df13E22d84Ae9", "interchainAccountRouter": "0xbed53B5C5BCE9433f25A2A702e6df13E22d84Ae9",
"interchainGasPaymaster": "0x2Fca7f6eC3d4A0408900f2BB30004d4616eE985E", "interchainGasPaymaster": "0x2Fca7f6eC3d4A0408900f2BB30004d4616eE985E",
"interchainSecurityModule": "0x2bed66bbfE45f1d73928179e72B73e5eCF7B9900", "interchainSecurityModule": "0x8B497dff421844Bb0882E0C495d0851D4461675C",
"mailbox": "0x2f9DB5616fa3fAd1aB06cB2C906830BA63d135e3", "mailbox": "0x2f9DB5616fa3fAd1aB06cB2C906830BA63d135e3",
"merkleTreeHook": "0x8358D8291e3bEDb04804975eEa0fe9fe0fAfB147", "merkleTreeHook": "0x8358D8291e3bEDb04804975eEa0fe9fe0fAfB147",
"name": "fraxtal", "name": "fraxtal",
@ -1046,7 +1047,7 @@
"interchainAccountIsm": "0x9629c28990F11c31735765A6FD59E1E1bC197DbD", "interchainAccountIsm": "0x9629c28990F11c31735765A6FD59E1E1bC197DbD",
"interchainAccountRouter": "0x2351FBe24C1212F253b7a300ff0cBCFd97952a19", "interchainAccountRouter": "0x2351FBe24C1212F253b7a300ff0cBCFd97952a19",
"interchainGasPaymaster": "0xFB9e40D811Cea562cc8a322b029eF2BDcC3ef6ed", "interchainGasPaymaster": "0xFB9e40D811Cea562cc8a322b029eF2BDcC3ef6ed",
"interchainSecurityModule": "0x1E12bdb6a33442102FEF2ab766b93c863653B4bE", "interchainSecurityModule": "0x69b33D67B9C51D45E23d22E727FF186DD6298ECA",
"mailbox": "0x3071D4DA6020C956Fe15Bfd0a9Ca8D4574f16696", "mailbox": "0x3071D4DA6020C956Fe15Bfd0a9Ca8D4574f16696",
"merkleTreeHook": "0xfBc08389224d23b79cb21cDc16c5d42F0ad0F57f", "merkleTreeHook": "0xfBc08389224d23b79cb21cDc16c5d42F0ad0F57f",
"name": "fusemainnet", "name": "fusemainnet",
@ -1120,7 +1121,7 @@
"interchainAccountIsm": "0x07E2062A1bC66a2C1d05cb5C3870a4AF86e0056E", "interchainAccountIsm": "0x07E2062A1bC66a2C1d05cb5C3870a4AF86e0056E",
"interchainAccountRouter": "0xBE70Ab882D1F7E37e04a70CDd9Ec23b37a234064", "interchainAccountRouter": "0xBE70Ab882D1F7E37e04a70CDd9Ec23b37a234064",
"interchainGasPaymaster": "0xDd260B99d302f0A3fF885728c086f729c06f227f", "interchainGasPaymaster": "0xDd260B99d302f0A3fF885728c086f729c06f227f",
"interchainSecurityModule": "0x996Be332325DA49Ea590A9772a515d62dD90C74c", "interchainSecurityModule": "0x00533a5F14B3a0632C86f99E4e20a10b73C4AE0D",
"mailbox": "0xaD09d78f4c6b9dA2Ae82b1D34107802d380Bb74f", "mailbox": "0xaD09d78f4c6b9dA2Ae82b1D34107802d380Bb74f",
"merkleTreeHook": "0x2684C6F89E901987E1FdB7649dC5Be0c57C61645", "merkleTreeHook": "0x2684C6F89E901987E1FdB7649dC5Be0c57C61645",
"name": "gnosis", "name": "gnosis",
@ -1183,7 +1184,7 @@
"domainId": 2525, "domainId": 2525,
"domainRoutingIsm": "0xBD70Ea9D599a0FC8158B026797177773C3445730", "domainRoutingIsm": "0xBD70Ea9D599a0FC8158B026797177773C3445730",
"domainRoutingIsmFactory": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908", "domainRoutingIsmFactory": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908",
"fallbackRoutingHook": "0xA376b27212D608324808923Add679A2c9FAFe9Da", "fallbackRoutingHook": "0xf8dba46ff9d8ef650052c89ca2df793fabc375f9",
"gasCurrencyCoinGeckoId": "injective-protocol", "gasCurrencyCoinGeckoId": "injective-protocol",
"index": { "index": {
"from": 37 "from": 37
@ -1191,7 +1192,7 @@
"interchainAccountIsm": "0x708E002637792FDC031E6B62f23DD60014AC976a", "interchainAccountIsm": "0x708E002637792FDC031E6B62f23DD60014AC976a",
"interchainAccountRouter": "0xfB8cea1c7F45608Da30655b50bbF355D123A4358", "interchainAccountRouter": "0xfB8cea1c7F45608Da30655b50bbF355D123A4358",
"interchainGasPaymaster": "0x19dc38aeae620380430C200a6E990D5Af5480117", "interchainGasPaymaster": "0x19dc38aeae620380430C200a6E990D5Af5480117",
"interchainSecurityModule": "0x1Bff27a1c1319b0704348895b67426a4Eb1b629e", "interchainSecurityModule": "0xB8F85B879775adF156Dd4AFa43e97DeB880d99D4",
"mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7",
"merkleTreeHook": "0x0972954923a1e2b2aAb04Fa0c4a0797e5989Cd65", "merkleTreeHook": "0x0972954923a1e2b2aAb04Fa0c4a0797e5989Cd65",
"name": "inevm", "name": "inevm",
@ -1228,7 +1229,14 @@
}, },
"injective": { "injective": {
"bech32Prefix": "inj", "bech32Prefix": "inj",
"blockExplorers": [], "blockExplorers": [
{
"apiUrl": "https://www.mintscan.io/injective",
"family": "other",
"name": "Mintscan",
"url": "https://www.mintscan.io/injective"
}
],
"blocks": { "blocks": {
"confirmations": 1, "confirmations": 1,
"estimateBlockTime": 1, "estimateBlockTime": 1,
@ -1312,7 +1320,7 @@
"from": 14616307 "from": 14616307
}, },
"interchainGasPaymaster": "0x9844aFFaBE17c37F791ff99ABa58B0FbB75e22AF", "interchainGasPaymaster": "0x9844aFFaBE17c37F791ff99ABa58B0FbB75e22AF",
"interchainSecurityModule": "0xcaE599dD2142CD8F09a68bAC89b4d809A038d2E9", "interchainSecurityModule": "0xE2968dAb74541184Ad95651b1e5Cf34Ab1bBEc97",
"mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7",
"merkleTreeHook": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a", "merkleTreeHook": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a",
"name": "kroma", "name": "kroma",
@ -1385,7 +1393,7 @@
"interchainAccountIsm": "0xdcA646C56E7768DD11654956adE24bfFf9Ba4893", "interchainAccountIsm": "0xdcA646C56E7768DD11654956adE24bfFf9Ba4893",
"interchainAccountRouter": "0xD59dA396F162Ed93a41252Cebb8d5DD4F093238C", "interchainAccountRouter": "0xD59dA396F162Ed93a41252Cebb8d5DD4F093238C",
"interchainGasPaymaster": "0x8105a095368f1a184CceA86cCe21318B5Ee5BE28", "interchainGasPaymaster": "0x8105a095368f1a184CceA86cCe21318B5Ee5BE28",
"interchainSecurityModule": "0x916e612358dA3F7E8e19f51ba2Cf7af3285a6793", "interchainSecurityModule": "0x0EEF1e64646EE01DeED4850074Cd4B97C0A630a9",
"mailbox": "0x02d16BC51af6BfD153d67CA61754cF912E82C4d9", "mailbox": "0x02d16BC51af6BfD153d67CA61754cF912E82C4d9",
"merkleTreeHook": "0xC077A0Cc408173349b1c9870C667B40FE3C01dd7", "merkleTreeHook": "0xC077A0Cc408173349b1c9870C667B40FE3C01dd7",
"name": "linea", "name": "linea",
@ -1456,7 +1464,7 @@
"from": 4195553 "from": 4195553
}, },
"interchainGasPaymaster": "0x9844aFFaBE17c37F791ff99ABa58B0FbB75e22AF", "interchainGasPaymaster": "0x9844aFFaBE17c37F791ff99ABa58B0FbB75e22AF",
"interchainSecurityModule": "0xa660FA2047105E0341b356393218586ED2191d14", "interchainSecurityModule": "0x63Bb509b9CA644609B15Ea55E56f0Acbbb9dB02E",
"mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7",
"merkleTreeHook": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a", "merkleTreeHook": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a",
"name": "lisk", "name": "lisk",
@ -1520,7 +1528,7 @@
"from": 3088760 "from": 3088760
}, },
"interchainGasPaymaster": "0x441a01Fca2eD731C0Fc4633998332f9FEDB17575", "interchainGasPaymaster": "0x441a01Fca2eD731C0Fc4633998332f9FEDB17575",
"interchainSecurityModule": "0x391BD8dD2709F77d39dab4fB3bf4BCAfd5EC3248", "interchainSecurityModule": "0x609ad94304896607A6D81DB00d882245045B79da",
"mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7",
"merkleTreeHook": "0x062200d92dF6bB7bA89Ce4D6800110450f94784e", "merkleTreeHook": "0x062200d92dF6bB7bA89Ce4D6800110450f94784e",
"name": "lukso", "name": "lukso",
@ -1594,7 +1602,7 @@
"interchainAccountIsm": "0x8Ea50255C282F89d1A14ad3F159437EE5EF0507f", "interchainAccountIsm": "0x8Ea50255C282F89d1A14ad3F159437EE5EF0507f",
"interchainAccountRouter": "0x693A4cE39d99e46B04cb562329e3F0141cA17331", "interchainAccountRouter": "0x693A4cE39d99e46B04cb562329e3F0141cA17331",
"interchainGasPaymaster": "0x0D63128D887159d63De29497dfa45AFc7C699AE4", "interchainGasPaymaster": "0x0D63128D887159d63De29497dfa45AFc7C699AE4",
"interchainSecurityModule": "0xBcB96842301c659B575c40C3f93F7311D09c93d9", "interchainSecurityModule": "0xC012e8E3cBeB6295E1E4837FBA5DB8E077EBc549",
"isTestnet": false, "isTestnet": false,
"mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", "mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E",
"merkleTreeHook": "0x149db7afD694722747035d5AEC7007ccb6F8f112", "merkleTreeHook": "0x149db7afD694722747035d5AEC7007ccb6F8f112",
@ -1664,7 +1672,7 @@
"interchainAccountIsm": "0xe039DA3A0071BEd087A12660D7b03cf669c7776E", "interchainAccountIsm": "0xe039DA3A0071BEd087A12660D7b03cf669c7776E",
"interchainAccountRouter": "0x45285463352c53a481e882cD5E2AF2E25BBdAd0D", "interchainAccountRouter": "0x45285463352c53a481e882cD5E2AF2E25BBdAd0D",
"interchainGasPaymaster": "0x8105a095368f1a184CceA86cCe21318B5Ee5BE28", "interchainGasPaymaster": "0x8105a095368f1a184CceA86cCe21318B5Ee5BE28",
"interchainSecurityModule": "0xe542Ed13B5782aF0AFAe7f232bB867FB0208Ab7B", "interchainSecurityModule": "0x8722328A5Ed815965F9B5eBAA21d04f0F9BFDd35",
"mailbox": "0x398633D19f4371e1DB5a8EFE90468eB70B1176AA", "mailbox": "0x398633D19f4371e1DB5a8EFE90468eB70B1176AA",
"merkleTreeHook": "0x5332D1AC0A626D265298c14ff681c0A8D28dB86d", "merkleTreeHook": "0x5332D1AC0A626D265298c14ff681c0A8D28dB86d",
"name": "mantle", "name": "mantle",
@ -1726,7 +1734,7 @@
"from": 13523607 "from": 13523607
}, },
"interchainGasPaymaster": "0x9844aFFaBE17c37F791ff99ABa58B0FbB75e22AF", "interchainGasPaymaster": "0x9844aFFaBE17c37F791ff99ABa58B0FbB75e22AF",
"interchainSecurityModule": "0x5725a9Bf3bdaF104Ce1A0098308DD974F6395365", "interchainSecurityModule": "0xE8176Fc70f129255aA83d3db242C2246Ad77Af7D",
"mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7",
"merkleTreeHook": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a", "merkleTreeHook": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a",
"name": "merlin", "name": "merlin",
@ -1793,7 +1801,7 @@
"from": 17966274 "from": 17966274
}, },
"interchainGasPaymaster": "0x9844aFFaBE17c37F791ff99ABa58B0FbB75e22AF", "interchainGasPaymaster": "0x9844aFFaBE17c37F791ff99ABa58B0FbB75e22AF",
"interchainSecurityModule": "0xfd810678075502F76A6ef79cedffe58cff6Cc410", "interchainSecurityModule": "0xA9309228762699D5c81A4b0BAfd06Da21589746b",
"mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7",
"merkleTreeHook": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a", "merkleTreeHook": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a",
"name": "metis", "name": "metis",
@ -1858,7 +1866,7 @@
"from": 3752032 "from": 3752032
}, },
"interchainGasPaymaster": "0x9844aFFaBE17c37F791ff99ABa58B0FbB75e22AF", "interchainGasPaymaster": "0x9844aFFaBE17c37F791ff99ABa58B0FbB75e22AF",
"interchainSecurityModule": "0xfd810678075502F76A6ef79cedffe58cff6Cc410", "interchainSecurityModule": "0xA9309228762699D5c81A4b0BAfd06Da21589746b",
"mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7",
"merkleTreeHook": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a", "merkleTreeHook": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a",
"name": "mint", "name": "mint",
@ -1925,7 +1933,7 @@
"interchainAccountIsm": "0xa377b8269e0A47cdd2fD5AAeAe860b45623c6d82", "interchainAccountIsm": "0xa377b8269e0A47cdd2fD5AAeAe860b45623c6d82",
"interchainAccountRouter": "0x6e1B9f776bd415d7cC3C7458A5f0d801016918f8", "interchainAccountRouter": "0x6e1B9f776bd415d7cC3C7458A5f0d801016918f8",
"interchainGasPaymaster": "0x931dFCc8c1141D6F532FD023bd87DAe0080c835d", "interchainGasPaymaster": "0x931dFCc8c1141D6F532FD023bd87DAe0080c835d",
"interchainSecurityModule": "0x1ab6985E0e15d293e71d01510fa6B57311C69718", "interchainSecurityModule": "0x0777dFffcEd18EE416e35401E0e5e0413b7D43be",
"mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7",
"merkleTreeHook": "0xE2ee936bEa8e42671c400aC96dE198E06F2bA2A6", "merkleTreeHook": "0xE2ee936bEa8e42671c400aC96dE198E06F2bA2A6",
"name": "mode", "name": "mode",
@ -1973,7 +1981,7 @@
"blocks": { "blocks": {
"confirmations": 2, "confirmations": 2,
"estimateBlockTime": 12, "estimateBlockTime": 12,
"reorgPeriod": 10 "reorgPeriod": "finalized"
}, },
"chainId": 1284, "chainId": 1284,
"deployer": { "deployer": {
@ -1993,7 +2001,7 @@
"interchainAccountIsm": "0x79b3730CE3685f65802aF1771319992bA960EB9D", "interchainAccountIsm": "0x79b3730CE3685f65802aF1771319992bA960EB9D",
"interchainAccountRouter": "0xc4482f66191754a8629D35289043C4EB0285F10E", "interchainAccountRouter": "0xc4482f66191754a8629D35289043C4EB0285F10E",
"interchainGasPaymaster": "0x14760E32C0746094cF14D97124865BC7F0F7368F", "interchainGasPaymaster": "0x14760E32C0746094cF14D97124865BC7F0F7368F",
"interchainSecurityModule": "0x105215D46F45a88B3793B798Fb87AF231Ad9f611", "interchainSecurityModule": "0xad1Ad827035eDe500aFd0ff122c53f6eA607Eb5C",
"mailbox": "0x094d03E751f49908080EFf000Dd6FD177fd44CC3", "mailbox": "0x094d03E751f49908080EFf000Dd6FD177fd44CC3",
"merkleTreeHook": "0x87403b85f6f316e7ba91ba1fa6C3Fb7dD4095547", "merkleTreeHook": "0x87403b85f6f316e7ba91ba1fa6C3Fb7dD4095547",
"name": "moonbeam", "name": "moonbeam",
@ -2135,7 +2143,7 @@
"interchainAccountIsm": "0x2c46BF14641d00549ECa4779BF5CBf91602C1DEd", "interchainAccountIsm": "0x2c46BF14641d00549ECa4779BF5CBf91602C1DEd",
"interchainAccountRouter": "0x03D6cC17d45E9EA27ED757A8214d1F07F7D901aD", "interchainAccountRouter": "0x03D6cC17d45E9EA27ED757A8214d1F07F7D901aD",
"interchainGasPaymaster": "0xD8A76C4D91fCbB7Cc8eA795DFDF870E48368995C", "interchainGasPaymaster": "0xD8A76C4D91fCbB7Cc8eA795DFDF870E48368995C",
"interchainSecurityModule": "0x1E491c93Ab56A298bBC34B4Fca8A4cE68E8d540a", "interchainSecurityModule": "0x3878aB31B2426A92E8a1E0AE758d848879F7F5E8",
"mailbox": "0xd4C1905BB1D26BC93DAC913e13CaCC278CdCC80D", "mailbox": "0xd4C1905BB1D26BC93DAC913e13CaCC278CdCC80D",
"merkleTreeHook": "0x68eE9bec9B4dbB61f69D9D293Ae26a5AACb2e28f", "merkleTreeHook": "0x68eE9bec9B4dbB61f69D9D293Ae26a5AACb2e28f",
"name": "optimism", "name": "optimism",
@ -2250,7 +2258,7 @@
"blocks": { "blocks": {
"confirmations": 3, "confirmations": 3,
"estimateBlockTime": 2, "estimateBlockTime": 2,
"reorgPeriod": 256 "reorgPeriod": "finalized"
}, },
"chainId": 137, "chainId": 137,
"deployer": { "deployer": {
@ -2270,7 +2278,7 @@
"interchainAccountIsm": "0xBAC4529cdfE7CCe9E858BF706e41F8Ed096C1BAd", "interchainAccountIsm": "0xBAC4529cdfE7CCe9E858BF706e41F8Ed096C1BAd",
"interchainAccountRouter": "0xF163949AD9F88977ebF649D0461398Ca752E64B9", "interchainAccountRouter": "0xF163949AD9F88977ebF649D0461398Ca752E64B9",
"interchainGasPaymaster": "0x0071740Bf129b05C4684abfbBeD248D80971cce2", "interchainGasPaymaster": "0x0071740Bf129b05C4684abfbBeD248D80971cce2",
"interchainSecurityModule": "0x0D408EF040ca0E7a75f03c41Aa46cAc904770D45", "interchainSecurityModule": "0x9fFC02BfB5C7260C985b005C0cF40d7EC601aac2",
"mailbox": "0x5d934f4e2f797775e53561bB72aca21ba36B96BB", "mailbox": "0x5d934f4e2f797775e53561bB72aca21ba36B96BB",
"merkleTreeHook": "0x73FbD25c3e817DC4B4Cd9d00eff6D83dcde2DfF6", "merkleTreeHook": "0x73FbD25c3e817DC4B4Cd9d00eff6D83dcde2DfF6",
"name": "polygon", "name": "polygon",
@ -2347,7 +2355,7 @@
"interchainAccountIsm": "0xc1198e241DAe48BF5AEDE5DCE49Fe4A6064cF7a7", "interchainAccountIsm": "0xc1198e241DAe48BF5AEDE5DCE49Fe4A6064cF7a7",
"interchainAccountRouter": "0x20a0A32a110362920597F72974E1E0d7e25cA20a", "interchainAccountRouter": "0x20a0A32a110362920597F72974E1E0d7e25cA20a",
"interchainGasPaymaster": "0x0D63128D887159d63De29497dfa45AFc7C699AE4", "interchainGasPaymaster": "0x0D63128D887159d63De29497dfa45AFc7C699AE4",
"interchainSecurityModule": "0x5C622f40365F57D06b5e7132B1483fcbc9566560", "interchainSecurityModule": "0xc6c475184F197FA65f233dFc22FA6bD4cE48B4fE",
"mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", "mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E",
"merkleTreeHook": "0x149db7afD694722747035d5AEC7007ccb6F8f112", "merkleTreeHook": "0x149db7afD694722747035d5AEC7007ccb6F8f112",
"name": "polygonzkevm", "name": "polygonzkevm",
@ -2415,7 +2423,7 @@
"from": 32018468 "from": 32018468
}, },
"interchainGasPaymaster": "0x9844aFFaBE17c37F791ff99ABa58B0FbB75e22AF", "interchainGasPaymaster": "0x9844aFFaBE17c37F791ff99ABa58B0FbB75e22AF",
"interchainSecurityModule": "0x336306ADB3c510A318107c01D109D2072c7abB6B", "interchainSecurityModule": "0x70e8beCE806914959c1B5D8F75d2217058D31437",
"mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7",
"merkleTreeHook": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a", "merkleTreeHook": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a",
"name": "proofofplay", "name": "proofofplay",
@ -2479,7 +2487,7 @@
"from": 363159 "from": 363159
}, },
"interchainGasPaymaster": "0x3071D4DA6020C956Fe15Bfd0a9Ca8D4574f16696", "interchainGasPaymaster": "0x3071D4DA6020C956Fe15Bfd0a9Ca8D4574f16696",
"interchainSecurityModule": "0x06567d07b49ad922A821A641F1C962569a255dbB", "interchainSecurityModule": "0x43346a54445BBdf8241062904E8A13AA62842a02",
"mailbox": "0xeA87ae93Fa0019a82A727bfd3eBd1cFCa8f64f1D", "mailbox": "0xeA87ae93Fa0019a82A727bfd3eBd1cFCa8f64f1D",
"merkleTreeHook": "0x55E4F0bc6b7Bb493D50839A8592e7ad8d5e93cf7", "merkleTreeHook": "0x55E4F0bc6b7Bb493D50839A8592e7ad8d5e93cf7",
"name": "real", "name": "real",
@ -2546,7 +2554,7 @@
"interchainAccountIsm": "0x5DA60220C5dDe35b7aE91c042ff5979047FA0785", "interchainAccountIsm": "0x5DA60220C5dDe35b7aE91c042ff5979047FA0785",
"interchainAccountRouter": "0x7a4d31a686A36285d68e14EDD53631417eB19603", "interchainAccountRouter": "0x7a4d31a686A36285d68e14EDD53631417eB19603",
"interchainGasPaymaster": "0x2Fa570E83009eaEef3a1cbd496a9a30F05266634", "interchainGasPaymaster": "0x2Fa570E83009eaEef3a1cbd496a9a30F05266634",
"interchainSecurityModule": "0x5a3bB91853CfDaDb1bC95D2E061B50d433fbe3E8", "interchainSecurityModule": "0xd8b6B632526834D8192860e6B6CE47165Fd02a42",
"mailbox": "0xeA87ae93Fa0019a82A727bfd3eBd1cFCa8f64f1D", "mailbox": "0xeA87ae93Fa0019a82A727bfd3eBd1cFCa8f64f1D",
"merkleTreeHook": "0x8F1E22d309baa69D398a03cc88E9b46037e988AA", "merkleTreeHook": "0x8F1E22d309baa69D398a03cc88E9b46037e988AA",
"name": "redstone", "name": "redstone",
@ -2608,7 +2616,7 @@
"from": 937117 "from": 937117
}, },
"interchainGasPaymaster": "0x9844aFFaBE17c37F791ff99ABa58B0FbB75e22AF", "interchainGasPaymaster": "0x9844aFFaBE17c37F791ff99ABa58B0FbB75e22AF",
"interchainSecurityModule": "0xA76F4620ac1e97d273B2C9Ca71805c8afD792098", "interchainSecurityModule": "0x6A2748201F66647ad6D164CB3340A893881A4bb2",
"mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7",
"merkleTreeHook": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a", "merkleTreeHook": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a",
"name": "sanko", "name": "sanko",
@ -2676,7 +2684,7 @@
"interchainAccountIsm": "0x32af5Df81fEd5E26119F6640FBB13f3d63a94CDe", "interchainAccountIsm": "0x32af5Df81fEd5E26119F6640FBB13f3d63a94CDe",
"interchainAccountRouter": "0x0B48a744698ba8dFa514742dFEB6728f52fD66f7", "interchainAccountRouter": "0x0B48a744698ba8dFa514742dFEB6728f52fD66f7",
"interchainGasPaymaster": "0xBF12ef4B9f307463D3FB59c3604F294dDCe287E2", "interchainGasPaymaster": "0xBF12ef4B9f307463D3FB59c3604F294dDCe287E2",
"interchainSecurityModule": "0x37e17723b665A9F95F4aecEEc40D9eF39624764e", "interchainSecurityModule": "0xAd1a987BfE0D6fbD92089628daC7C7e4bA9a6AAF",
"mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7",
"merkleTreeHook": "0x6119E37Bd66406A1Db74920aC79C15fB8411Ba76", "merkleTreeHook": "0x6119E37Bd66406A1Db74920aC79C15fB8411Ba76",
"name": "scroll", "name": "scroll",
@ -2744,7 +2752,7 @@
"interchainAccountIsm": "0xf35dc7B9eE4Ebf0cd3546Bd6EE3b403dE2b9F5D6", "interchainAccountIsm": "0xf35dc7B9eE4Ebf0cd3546Bd6EE3b403dE2b9F5D6",
"interchainAccountRouter": "0xBcaedE97a98573A88242B3b0CB0A255F3f90d4d5", "interchainAccountRouter": "0xBcaedE97a98573A88242B3b0CB0A255F3f90d4d5",
"interchainGasPaymaster": "0xFC62DeF1f08793aBf0E67f69257c6be258194F72", "interchainGasPaymaster": "0xFC62DeF1f08793aBf0E67f69257c6be258194F72",
"interchainSecurityModule": "0x26184898fA27D3471B50BD956AB5b3E9Aa14763C", "interchainSecurityModule": "0x494028EA206642e4c60Ec3d12e96B4549E5e1800",
"mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7",
"merkleTreeHook": "0xca1b69fA4c4a7c7fD839bC50867c589592bcfe49", "merkleTreeHook": "0xca1b69fA4c4a7c7fD839bC50867c589592bcfe49",
"name": "sei", "name": "sei",
@ -2804,7 +2812,8 @@
"gasCurrencyCoinGeckoId": "solana", "gasCurrencyCoinGeckoId": "solana",
"index": { "index": {
"from": 1, "from": 1,
"mode": "sequence" "mode": "sequence",
"chunk": 100
}, },
"interchainGasPaymaster": "JAvHW21tYXE9dtdG83DReqU2b4LUexFuCbtJT5tF8X6M", "interchainGasPaymaster": "JAvHW21tYXE9dtdG83DReqU2b4LUexFuCbtJT5tF8X6M",
"mailbox": "E588QtVUvresuXq2KoNEwAmoifCzYGpRBdHByN9KQMbi", "mailbox": "E588QtVUvresuXq2KoNEwAmoifCzYGpRBdHByN9KQMbi",
@ -2858,7 +2867,7 @@
"interchainAccountIsm": "0xAE557e108b3336130370aC74836f1356B4b30Cf2", "interchainAccountIsm": "0xAE557e108b3336130370aC74836f1356B4b30Cf2",
"interchainAccountRouter": "0x1F8CF09F060A2AE962c0Bb1F92e209a1E7b0E10B", "interchainAccountRouter": "0x1F8CF09F060A2AE962c0Bb1F92e209a1E7b0E10B",
"interchainGasPaymaster": "0x273Bc6b01D9E88c064b6E5e409BdF998246AEF42", "interchainGasPaymaster": "0x273Bc6b01D9E88c064b6E5e409BdF998246AEF42",
"interchainSecurityModule": "0x478D0e5d221C8d7CA1A6353315fac6FA88Ff1B97", "interchainSecurityModule": "0xC93F2796A17Ee4580c039aeB7b0c923b10ce79C2",
"mailbox": "0x28EFBCadA00A7ed6772b3666F3898d276e88CAe3", "mailbox": "0x28EFBCadA00A7ed6772b3666F3898d276e88CAe3",
"merkleTreeHook": "0x6A55822cf11f9fcBc4c75BC2638AfE8Eb942cAdd", "merkleTreeHook": "0x6A55822cf11f9fcBc4c75BC2638AfE8Eb942cAdd",
"name": "taiko", "name": "taiko",
@ -2903,7 +2912,7 @@
"blocks": { "blocks": {
"confirmations": 1, "confirmations": 1,
"estimateBlockTime": 6, "estimateBlockTime": 6,
"reorgPeriod": 10 "reorgPeriod": "finalized"
}, },
"chainId": 5845, "chainId": 5845,
"deployer": { "deployer": {
@ -2920,7 +2929,7 @@
"from": 1678063 "from": 1678063
}, },
"interchainGasPaymaster": "0x9844aFFaBE17c37F791ff99ABa58B0FbB75e22AF", "interchainGasPaymaster": "0x9844aFFaBE17c37F791ff99ABa58B0FbB75e22AF",
"interchainSecurityModule": "0x336306ADB3c510A318107c01D109D2072c7abB6B", "interchainSecurityModule": "0x70e8beCE806914959c1B5D8F75d2217058D31437",
"isTestnet": false, "isTestnet": false,
"mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7",
"merkleTreeHook": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a", "merkleTreeHook": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a",
@ -2988,7 +2997,7 @@
"interchainAccountIsm": "0x551BbEc45FD665a8C95ca8731CbC32b7653Bc59B", "interchainAccountIsm": "0x551BbEc45FD665a8C95ca8731CbC32b7653Bc59B",
"interchainAccountRouter": "0xc11f8Cf2343d3788405582F65B8af6A4F7a6FfC8", "interchainAccountRouter": "0xc11f8Cf2343d3788405582F65B8af6A4F7a6FfC8",
"interchainGasPaymaster": "0x0D63128D887159d63De29497dfa45AFc7C699AE4", "interchainGasPaymaster": "0x0D63128D887159d63De29497dfa45AFc7C699AE4",
"interchainSecurityModule": "0x5542503cBde841c336Afef014FE80b0F1c9d716d", "interchainSecurityModule": "0x3465AccC39AE5e6C344184013a57cDCe546834d6",
"mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7",
"merkleTreeHook": "0x149db7afD694722747035d5AEC7007ccb6F8f112", "merkleTreeHook": "0x149db7afD694722747035d5AEC7007ccb6F8f112",
"name": "viction", "name": "viction",
@ -3056,7 +3065,7 @@
"interchainAccountIsm": "0xCB9f90EE5d83Ea52ABd922BD70898f0155D54798", "interchainAccountIsm": "0xCB9f90EE5d83Ea52ABd922BD70898f0155D54798",
"interchainAccountRouter": "0x473884010F0C1742DA8Ad01E7E295624B931076b", "interchainAccountRouter": "0x473884010F0C1742DA8Ad01E7E295624B931076b",
"interchainGasPaymaster": "0x7E27456a839BFF31CA642c060a2b68414Cb6e503", "interchainGasPaymaster": "0x7E27456a839BFF31CA642c060a2b68414Cb6e503",
"interchainSecurityModule": "0xc1FF2bf7a4C315bE2a06941D236457EB02F93993", "interchainSecurityModule": "0x05f6BAa16F1aCf7b19c4A09E019D856c10ab8355",
"mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7",
"merkleTreeHook": "0x0054D19613f20dD72721A146ED408971a2CCA9BD", "merkleTreeHook": "0x0054D19613f20dD72721A146ED408971a2CCA9BD",
"name": "worldchain", "name": "worldchain",
@ -3118,7 +3127,7 @@
"from": 24395308 "from": 24395308
}, },
"interchainGasPaymaster": "0x9844aFFaBE17c37F791ff99ABa58B0FbB75e22AF", "interchainGasPaymaster": "0x9844aFFaBE17c37F791ff99ABa58B0FbB75e22AF",
"interchainSecurityModule": "0xC630ef37e03534721557026FeC397Ec05f85584C", "interchainSecurityModule": "0x4886ed96bcdba2ad85Bf518C3171C39e256ac840",
"mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7",
"merkleTreeHook": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a", "merkleTreeHook": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a",
"name": "xai", "name": "xai",
@ -3186,7 +3195,7 @@
"interchainAccountIsm": "0x29B37088724B745C0ABcE591449Cf042772160C2", "interchainAccountIsm": "0x29B37088724B745C0ABcE591449Cf042772160C2",
"interchainAccountRouter": "0x03cF708E42C89623bd83B281A56935cB562b9258", "interchainAccountRouter": "0x03cF708E42C89623bd83B281A56935cB562b9258",
"interchainGasPaymaster": "0x7E27456a839BFF31CA642c060a2b68414Cb6e503", "interchainGasPaymaster": "0x7E27456a839BFF31CA642c060a2b68414Cb6e503",
"interchainSecurityModule": "0x0811C6250965E7Ba1A872A12249B1b2300d85CFD", "interchainSecurityModule": "0x59B0ec92522F164b72c9BE473382197c564B92dc",
"mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7",
"merkleTreeHook": "0x0054D19613f20dD72721A146ED408971a2CCA9BD", "merkleTreeHook": "0x0054D19613f20dD72721A146ED408971a2CCA9BD",
"name": "xlayer", "name": "xlayer",
@ -3254,7 +3263,7 @@
"interchainAccountIsm": "0x2b6d3F7d28B5EC8C3C028fBCAdcf774D9709Dd29", "interchainAccountIsm": "0x2b6d3F7d28B5EC8C3C028fBCAdcf774D9709Dd29",
"interchainAccountRouter": "0x3AdCBc94ab8C48EC52D06dc65Bb787fD1981E3d5", "interchainAccountRouter": "0x3AdCBc94ab8C48EC52D06dc65Bb787fD1981E3d5",
"interchainGasPaymaster": "0x931dFCc8c1141D6F532FD023bd87DAe0080c835d", "interchainGasPaymaster": "0x931dFCc8c1141D6F532FD023bd87DAe0080c835d",
"interchainSecurityModule": "0x858a077945bCC4afA40DaE5a75faB9237e899b30", "interchainSecurityModule": "0xd32353Ae5719ac4f8f24AeD81A2A6898d2632D26",
"mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7",
"merkleTreeHook": "0xE2ee936bEa8e42671c400aC96dE198E06F2bA2A6", "merkleTreeHook": "0xE2ee936bEa8e42671c400aC96dE198E06F2bA2A6",
"name": "zetachain", "name": "zetachain",
@ -3320,7 +3329,7 @@
"from": 1511458 "from": 1511458
}, },
"interchainGasPaymaster": "0x03cF708E42C89623bd83B281A56935cB562b9258", "interchainGasPaymaster": "0x03cF708E42C89623bd83B281A56935cB562b9258",
"interchainSecurityModule": "0xb04DE6Cbc6E258E8f2D2B00EBdcD2Ea901791EAA", "interchainSecurityModule": "0xFFec270FE3D0e3B9348B3664BE73A5d4906BA620",
"mailbox": "0xc2FbB9411186AB3b1a6AFCCA702D1a80B48b197c", "mailbox": "0xc2FbB9411186AB3b1a6AFCCA702D1a80B48b197c",
"merkleTreeHook": "0x4C97D35c668EE5194a13c8DE8Afc18cce40C9F28", "merkleTreeHook": "0x4C97D35c668EE5194a13c8DE8Afc18cce40C9F28",
"name": "zircuit", "name": "zircuit",
@ -3393,7 +3402,7 @@
"interchainAccountIsm": "0xb2674E213019972f937CCFc5e23BF963D915809e", "interchainAccountIsm": "0xb2674E213019972f937CCFc5e23BF963D915809e",
"interchainAccountRouter": "0x11b76D93a9D39Eb51F54eBf5566308640cDe882b", "interchainAccountRouter": "0x11b76D93a9D39Eb51F54eBf5566308640cDe882b",
"interchainGasPaymaster": "0x18B0688990720103dB63559a3563f7E8d0f63EDb", "interchainGasPaymaster": "0x18B0688990720103dB63559a3563f7E8d0f63EDb",
"interchainSecurityModule": "0xDede6e50E548460FB6a939320F707214CFfC701C", "interchainSecurityModule": "0xED5fD1715A0885a3C7B908BAd5c8C64Ba5166265",
"mailbox": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a", "mailbox": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a",
"merkleTreeHook": "0x886BB0f329781b98f98FDeb1ce7a8957F2d43B9F", "merkleTreeHook": "0x886BB0f329781b98f98FDeb1ce7a8957F2d43B9F",
"name": "zoramainnet", "name": "zoramainnet",
@ -3437,7 +3446,7 @@
"blocks": { "blocks": {
"confirmations": 1, "confirmations": 1,
"estimateBlockTime": 13, "estimateBlockTime": 13,
"reorgPeriod": 32 "reorgPeriod": "finalized"
}, },
"chainId": 592, "chainId": 592,
"deployer": { "deployer": {
@ -3464,7 +3473,7 @@
"domainRoutingIsmFactory": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908", "domainRoutingIsmFactory": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908",
"fallbackRoutingHook": "0xc401e251CCa7A364114504A994D6fC7cb1c243AB", "fallbackRoutingHook": "0xc401e251CCa7A364114504A994D6fC7cb1c243AB",
"interchainGasPaymaster": "0x4E55aDA3ef1942049EA43E904EB01F4A0a9c39bd", "interchainGasPaymaster": "0x4E55aDA3ef1942049EA43E904EB01F4A0a9c39bd",
"interchainSecurityModule": "0x2b19CEB3ef3B1D7428b0788d44401E44E381B62B", "interchainSecurityModule": "0x8Ad4d573D7EafC4Ca58f1dB704B8Db804814D674",
"mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", "mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E",
"merkleTreeHook": "0x441a01Fca2eD731C0Fc4633998332f9FEDB17575", "merkleTreeHook": "0x441a01Fca2eD731C0Fc4633998332f9FEDB17575",
"pausableHook": "0x5Ed813B8b41f25c8002B01A72bbDBe6A0232Fe27", "pausableHook": "0x5Ed813B8b41f25c8002B01A72bbDBe6A0232Fe27",
@ -3531,7 +3540,7 @@
"domainRoutingIsmFactory": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908", "domainRoutingIsmFactory": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908",
"fallbackRoutingHook": "0xc401e251CCa7A364114504A994D6fC7cb1c243AB", "fallbackRoutingHook": "0xc401e251CCa7A364114504A994D6fC7cb1c243AB",
"interchainGasPaymaster": "0x4E55aDA3ef1942049EA43E904EB01F4A0a9c39bd", "interchainGasPaymaster": "0x4E55aDA3ef1942049EA43E904EB01F4A0a9c39bd",
"interchainSecurityModule": "0x8Ad4d573D7EafC4Ca58f1dB704B8Db804814D674", "interchainSecurityModule": "0xa18979d2e5b8A64f62E0f9e9523d28E934F1104c",
"mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", "mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E",
"merkleTreeHook": "0x441a01Fca2eD731C0Fc4633998332f9FEDB17575", "merkleTreeHook": "0x441a01Fca2eD731C0Fc4633998332f9FEDB17575",
"pausableHook": "0x5Ed813B8b41f25c8002B01A72bbDBe6A0232Fe27", "pausableHook": "0x5Ed813B8b41f25c8002B01A72bbDBe6A0232Fe27",
@ -3601,7 +3610,7 @@
"domainRoutingIsmFactory": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908", "domainRoutingIsmFactory": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908",
"fallbackRoutingHook": "0xc401e251CCa7A364114504A994D6fC7cb1c243AB", "fallbackRoutingHook": "0xc401e251CCa7A364114504A994D6fC7cb1c243AB",
"interchainGasPaymaster": "0x4E55aDA3ef1942049EA43E904EB01F4A0a9c39bd", "interchainGasPaymaster": "0x4E55aDA3ef1942049EA43E904EB01F4A0a9c39bd",
"interchainSecurityModule": "0x2b19CEB3ef3B1D7428b0788d44401E44E381B62B", "interchainSecurityModule": "0x8Ad4d573D7EafC4Ca58f1dB704B8Db804814D674",
"mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", "mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E",
"merkleTreeHook": "0x441a01Fca2eD731C0Fc4633998332f9FEDB17575", "merkleTreeHook": "0x441a01Fca2eD731C0Fc4633998332f9FEDB17575",
"pausableHook": "0x5Ed813B8b41f25c8002B01A72bbDBe6A0232Fe27", "pausableHook": "0x5Ed813B8b41f25c8002B01A72bbDBe6A0232Fe27",
@ -3677,7 +3686,7 @@
"domainRoutingIsmFactory": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908", "domainRoutingIsmFactory": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908",
"fallbackRoutingHook": "0xc401e251CCa7A364114504A994D6fC7cb1c243AB", "fallbackRoutingHook": "0xc401e251CCa7A364114504A994D6fC7cb1c243AB",
"interchainGasPaymaster": "0x4E55aDA3ef1942049EA43E904EB01F4A0a9c39bd", "interchainGasPaymaster": "0x4E55aDA3ef1942049EA43E904EB01F4A0a9c39bd",
"interchainSecurityModule": "0x2b19CEB3ef3B1D7428b0788d44401E44E381B62B", "interchainSecurityModule": "0x8Ad4d573D7EafC4Ca58f1dB704B8Db804814D674",
"mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", "mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E",
"merkleTreeHook": "0x441a01Fca2eD731C0Fc4633998332f9FEDB17575", "merkleTreeHook": "0x441a01Fca2eD731C0Fc4633998332f9FEDB17575",
"pausableHook": "0x5Ed813B8b41f25c8002B01A72bbDBe6A0232Fe27", "pausableHook": "0x5Ed813B8b41f25c8002B01A72bbDBe6A0232Fe27",
@ -3741,7 +3750,7 @@
"domainRoutingIsmFactory": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908", "domainRoutingIsmFactory": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908",
"fallbackRoutingHook": "0xc401e251CCa7A364114504A994D6fC7cb1c243AB", "fallbackRoutingHook": "0xc401e251CCa7A364114504A994D6fC7cb1c243AB",
"interchainGasPaymaster": "0x4E55aDA3ef1942049EA43E904EB01F4A0a9c39bd", "interchainGasPaymaster": "0x4E55aDA3ef1942049EA43E904EB01F4A0a9c39bd",
"interchainSecurityModule": "0x2b19CEB3ef3B1D7428b0788d44401E44E381B62B", "interchainSecurityModule": "0x8Ad4d573D7EafC4Ca58f1dB704B8Db804814D674",
"mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", "mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E",
"merkleTreeHook": "0x441a01Fca2eD731C0Fc4633998332f9FEDB17575", "merkleTreeHook": "0x441a01Fca2eD731C0Fc4633998332f9FEDB17575",
"pausableHook": "0x5Ed813B8b41f25c8002B01A72bbDBe6A0232Fe27", "pausableHook": "0x5Ed813B8b41f25c8002B01A72bbDBe6A0232Fe27",
@ -3814,7 +3823,7 @@
"domainRoutingIsmFactory": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908", "domainRoutingIsmFactory": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908",
"fallbackRoutingHook": "0xc401e251CCa7A364114504A994D6fC7cb1c243AB", "fallbackRoutingHook": "0xc401e251CCa7A364114504A994D6fC7cb1c243AB",
"interchainGasPaymaster": "0x4E55aDA3ef1942049EA43E904EB01F4A0a9c39bd", "interchainGasPaymaster": "0x4E55aDA3ef1942049EA43E904EB01F4A0a9c39bd",
"interchainSecurityModule": "0x2b19CEB3ef3B1D7428b0788d44401E44E381B62B", "interchainSecurityModule": "0x8Ad4d573D7EafC4Ca58f1dB704B8Db804814D674",
"mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", "mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E",
"merkleTreeHook": "0x441a01Fca2eD731C0Fc4633998332f9FEDB17575", "merkleTreeHook": "0x441a01Fca2eD731C0Fc4633998332f9FEDB17575",
"pausableHook": "0x5Ed813B8b41f25c8002B01A72bbDBe6A0232Fe27", "pausableHook": "0x5Ed813B8b41f25c8002B01A72bbDBe6A0232Fe27",
@ -3882,7 +3891,7 @@
"domainRoutingIsmFactory": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908", "domainRoutingIsmFactory": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908",
"fallbackRoutingHook": "0xc401e251CCa7A364114504A994D6fC7cb1c243AB", "fallbackRoutingHook": "0xc401e251CCa7A364114504A994D6fC7cb1c243AB",
"interchainGasPaymaster": "0x4E55aDA3ef1942049EA43E904EB01F4A0a9c39bd", "interchainGasPaymaster": "0x4E55aDA3ef1942049EA43E904EB01F4A0a9c39bd",
"interchainSecurityModule": "0x2b19CEB3ef3B1D7428b0788d44401E44E381B62B", "interchainSecurityModule": "0x8Ad4d573D7EafC4Ca58f1dB704B8Db804814D674",
"mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", "mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E",
"merkleTreeHook": "0x441a01Fca2eD731C0Fc4633998332f9FEDB17575", "merkleTreeHook": "0x441a01Fca2eD731C0Fc4633998332f9FEDB17575",
"pausableHook": "0x5Ed813B8b41f25c8002B01A72bbDBe6A0232Fe27", "pausableHook": "0x5Ed813B8b41f25c8002B01A72bbDBe6A0232Fe27",
@ -3915,7 +3924,7 @@
"blocks": { "blocks": {
"confirmations": 1, "confirmations": 1,
"estimateBlockTime": 5, "estimateBlockTime": 5,
"reorgPeriod": 5 "reorgPeriod": "finalized"
}, },
"chainId": 109, "chainId": 109,
"deployer": { "deployer": {
@ -3945,7 +3954,7 @@
"domainRoutingIsmFactory": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908", "domainRoutingIsmFactory": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908",
"fallbackRoutingHook": "0xc401e251CCa7A364114504A994D6fC7cb1c243AB", "fallbackRoutingHook": "0xc401e251CCa7A364114504A994D6fC7cb1c243AB",
"interchainGasPaymaster": "0x4E55aDA3ef1942049EA43E904EB01F4A0a9c39bd", "interchainGasPaymaster": "0x4E55aDA3ef1942049EA43E904EB01F4A0a9c39bd",
"interchainSecurityModule": "0x12C8cfA5B97Df96AaB2795a4186675dA49938968", "interchainSecurityModule": "0xf08b7F859966ed27286Fe7d924A42b40e2DB80Bd",
"mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", "mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E",
"merkleTreeHook": "0x441a01Fca2eD731C0Fc4633998332f9FEDB17575", "merkleTreeHook": "0x441a01Fca2eD731C0Fc4633998332f9FEDB17575",
"pausableHook": "0x5Ed813B8b41f25c8002B01A72bbDBe6A0232Fe27", "pausableHook": "0x5Ed813B8b41f25c8002B01A72bbDBe6A0232Fe27",
@ -4015,7 +4024,7 @@
"interchainAccountIsm": "0xcd9D3744512F07AE844c40E27912092d7c503565", "interchainAccountIsm": "0xcd9D3744512F07AE844c40E27912092d7c503565",
"interchainAccountRouter": "0x92cdbF0Ccdf8E93467FA858fb986fa650A02f2A8", "interchainAccountRouter": "0x92cdbF0Ccdf8E93467FA858fb986fa650A02f2A8",
"interchainGasPaymaster": "0xb58257cc81E47EC72fD38aE16297048de23163b4", "interchainGasPaymaster": "0xb58257cc81E47EC72fD38aE16297048de23163b4",
"interchainSecurityModule": "0xA16954f5040ba7fE2286569aD107a22a46FffDC6", "interchainSecurityModule": "0xcC5C35a6214982d9018B95e9684D5b4dA626237e",
"mailbox": "0x7f50C5776722630a0024fAE05fDe8b47571D7B39", "mailbox": "0x7f50C5776722630a0024fAE05fDe8b47571D7B39",
"merkleTreeHook": "0xCC3D1659D50461d27a2F025dDb2c9B06B584B7e1", "merkleTreeHook": "0xCC3D1659D50461d27a2F025dDb2c9B06B584B7e1",
"pausableHook": "0x4E55aDA3ef1942049EA43E904EB01F4A0a9c39bd", "pausableHook": "0x4E55aDA3ef1942049EA43E904EB01F4A0a9c39bd",
@ -4075,7 +4084,7 @@
"interchainAccountIsm": "0xc23BaF5Eb5848D19701BbE7f139645e6bd58a319", "interchainAccountIsm": "0xc23BaF5Eb5848D19701BbE7f139645e6bd58a319",
"interchainAccountRouter": "0x7c58Cadcc2b60ACF794eE1843488d6f5703f76BE", "interchainAccountRouter": "0x7c58Cadcc2b60ACF794eE1843488d6f5703f76BE",
"interchainGasPaymaster": "0xb4fc9B5fD57499Ef6FfF3995728a55F7A618ef86", "interchainGasPaymaster": "0xb4fc9B5fD57499Ef6FfF3995728a55F7A618ef86",
"interchainSecurityModule": "0x128432015A0E08d490e0FD6b4dE4EAbe30f617a3", "interchainSecurityModule": "0x50B5Edd94A1C7ad18Fa2CA667A30Dc051a695aEe",
"mailbox": "0xb129828B9EDa48192D0B2db35D0E40dCF51B3594", "mailbox": "0xb129828B9EDa48192D0B2db35D0E40dCF51B3594",
"merkleTreeHook": "0x3E969bA938E6A993eeCD6F65b0dd8712B07dFe59", "merkleTreeHook": "0x3E969bA938E6A993eeCD6F65b0dd8712B07dFe59",
"pausableHook": "0x6Fb36672365C7c797028C400A61c58c0ECc53cD2", "pausableHook": "0x6Fb36672365C7c797028C400A61c58c0ECc53cD2",
@ -4147,7 +4156,7 @@
"interchainAccountIsm": "0x783EC5e105234a570eB90f314284E5dBe53bdd90", "interchainAccountIsm": "0x783EC5e105234a570eB90f314284E5dBe53bdd90",
"interchainAccountRouter": "0xc5D6aCaafBCcEC6D7fD7d92F4509befce641c563", "interchainAccountRouter": "0xc5D6aCaafBCcEC6D7fD7d92F4509befce641c563",
"interchainGasPaymaster": "0xe8d5590F2e969F9d21f0132f2b596273f8a03Ef2", "interchainGasPaymaster": "0xe8d5590F2e969F9d21f0132f2b596273f8a03Ef2",
"interchainSecurityModule": "0xe274f228f87c0D72241CF9aAC15d91e3630aE6f6", "interchainSecurityModule": "0x58D6fb4aADd3ae83ec529d3d0f42Ae904207a336",
"mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", "mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E",
"merkleTreeHook": "0xDab56C5A1EffFdd23f6BD1243E457B1575984Bc6", "merkleTreeHook": "0xDab56C5A1EffFdd23f6BD1243E457B1575984Bc6",
"pausableHook": "0x73db9c7430548f399e335f3424e8d56080e9010c", "pausableHook": "0x73db9c7430548f399e335f3424e8d56080e9010c",
@ -4210,7 +4219,7 @@
"interchainAccountIsm": "0x9eaaC366BFD70430cFee6E70265fefFf1CfC9E47", "interchainAccountIsm": "0x9eaaC366BFD70430cFee6E70265fefFf1CfC9E47",
"interchainAccountRouter": "0xbb0AE51BCa526cF313b6a95BfaB020794af6C394", "interchainAccountRouter": "0xbb0AE51BCa526cF313b6a95BfaB020794af6C394",
"interchainGasPaymaster": "0xe8d5590F2e969F9d21f0132f2b596273f8a03Ef2", "interchainGasPaymaster": "0xe8d5590F2e969F9d21f0132f2b596273f8a03Ef2",
"interchainSecurityModule": "0xe274f228f87c0D72241CF9aAC15d91e3630aE6f6", "interchainSecurityModule": "0x58D6fb4aADd3ae83ec529d3d0f42Ae904207a336",
"mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", "mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E",
"merkleTreeHook": "0xDab56C5A1EffFdd23f6BD1243E457B1575984Bc6", "merkleTreeHook": "0xDab56C5A1EffFdd23f6BD1243E457B1575984Bc6",
"pausableHook": "0x73db9c7430548f399e335f3424e8d56080e9010c", "pausableHook": "0x73db9c7430548f399e335f3424e8d56080e9010c",
@ -4280,7 +4289,7 @@
"interchainAccountIsm": "0xeE8C0E1EeBfFCC451a013336386eA53E42a44451", "interchainAccountIsm": "0xeE8C0E1EeBfFCC451a013336386eA53E42a44451",
"interchainAccountRouter": "0x9eb56085DdbDA60aDf7d2B533AFeD90e38fC9666", "interchainAccountRouter": "0x9eb56085DdbDA60aDf7d2B533AFeD90e38fC9666",
"interchainGasPaymaster": "0xe8d5590F2e969F9d21f0132f2b596273f8a03Ef2", "interchainGasPaymaster": "0xe8d5590F2e969F9d21f0132f2b596273f8a03Ef2",
"interchainSecurityModule": "0xe274f228f87c0D72241CF9aAC15d91e3630aE6f6", "interchainSecurityModule": "0x58D6fb4aADd3ae83ec529d3d0f42Ae904207a336",
"mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", "mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E",
"merkleTreeHook": "0xDab56C5A1EffFdd23f6BD1243E457B1575984Bc6", "merkleTreeHook": "0xDab56C5A1EffFdd23f6BD1243E457B1575984Bc6",
"pausableHook": "0x73db9c7430548f399e335f3424e8d56080e9010c", "pausableHook": "0x73db9c7430548f399e335f3424e8d56080e9010c",
@ -4351,7 +4360,7 @@
"interchainAccountIsm": "0x25EAC2007b0D40E3f0AF112FD346412321038719", "interchainAccountIsm": "0x25EAC2007b0D40E3f0AF112FD346412321038719",
"interchainAccountRouter": "0xfF26696DcDb6BbFD27e959b847D4f1399D5BcF64", "interchainAccountRouter": "0xfF26696DcDb6BbFD27e959b847D4f1399D5BcF64",
"interchainGasPaymaster": "0x9024A3902B542C87a5C4A2b3e15d60B2f087Dc3E", "interchainGasPaymaster": "0x9024A3902B542C87a5C4A2b3e15d60B2f087Dc3E",
"interchainSecurityModule": "0x8750ac24C3bE28b406fBCD664AbabF676d3aCB29", "interchainSecurityModule": "0x9dccF81bB9f419425b0a6584E8800556B92209Cc",
"mailbox": "0x3a867fCfFeC2B790970eeBDC9023E75B0a172aa7", "mailbox": "0x3a867fCfFeC2B790970eeBDC9023E75B0a172aa7",
"merkleTreeHook": "0x9c44E6b8F0dB517C2c3a0478caaC5349b614F912", "merkleTreeHook": "0x9c44E6b8F0dB517C2c3a0478caaC5349b614F912",
"pausableHook": "0x53e912b41125d6094590a7DBEf1360d3d56EEa19", "pausableHook": "0x53e912b41125d6094590a7DBEf1360d3d56EEa19",
@ -4419,7 +4428,7 @@
"interchainAccountIsm": "0x99fEFc1119E86Ee0153eb887cF8E8ab2d92A16e8", "interchainAccountIsm": "0x99fEFc1119E86Ee0153eb887cF8E8ab2d92A16e8",
"interchainAccountRouter": "0xbB88a31E4b709b645c06825c0E0b5CAC906d97DE", "interchainAccountRouter": "0xbB88a31E4b709b645c06825c0E0b5CAC906d97DE",
"interchainGasPaymaster": "0xe8d5590F2e969F9d21f0132f2b596273f8a03Ef2", "interchainGasPaymaster": "0xe8d5590F2e969F9d21f0132f2b596273f8a03Ef2",
"interchainSecurityModule": "0xe274f228f87c0D72241CF9aAC15d91e3630aE6f6", "interchainSecurityModule": "0x58D6fb4aADd3ae83ec529d3d0f42Ae904207a336",
"mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", "mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E",
"merkleTreeHook": "0xDab56C5A1EffFdd23f6BD1243E457B1575984Bc6", "merkleTreeHook": "0xDab56C5A1EffFdd23f6BD1243E457B1575984Bc6",
"pausableHook": "0x73db9c7430548f399e335f3424e8d56080e9010c", "pausableHook": "0x73db9c7430548f399e335f3424e8d56080e9010c",
@ -4485,7 +4494,7 @@
"interchainAccountIsm": "0xFB9e40D811Cea562cc8a322b029eF2BDcC3ef6ed", "interchainAccountIsm": "0xFB9e40D811Cea562cc8a322b029eF2BDcC3ef6ed",
"interchainAccountRouter": "0xeE8C0E1EeBfFCC451a013336386eA53E42a44451", "interchainAccountRouter": "0xeE8C0E1EeBfFCC451a013336386eA53E42a44451",
"interchainGasPaymaster": "0x148CF67B8A242c1360bb2C93fCe203EC4d4f9B56", "interchainGasPaymaster": "0x148CF67B8A242c1360bb2C93fCe203EC4d4f9B56",
"interchainSecurityModule": "0x01031eCa87184c84938016E1444150472Da35b3a", "interchainSecurityModule": "0x81EC949b07e033b0346E60C2098464d115F0a997",
"mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", "mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E",
"merkleTreeHook": "0x53e912b41125d6094590a7DBEf1360d3d56EEa19", "merkleTreeHook": "0x53e912b41125d6094590a7DBEf1360d3d56EEa19",
"pausableHook": "0x2d5918c3602F17937Ff982F7Bb7110774D3A24AD", "pausableHook": "0x2d5918c3602F17937Ff982F7Bb7110774D3A24AD",
@ -4556,7 +4565,7 @@
"interchainAccountIsm": "0x9eb56085DdbDA60aDf7d2B533AFeD90e38fC9666", "interchainAccountIsm": "0x9eb56085DdbDA60aDf7d2B533AFeD90e38fC9666",
"interchainAccountRouter": "0x83475ca5bEB2Eaa59A2FF48a0544ebaa4a32c2de", "interchainAccountRouter": "0x83475ca5bEB2Eaa59A2FF48a0544ebaa4a32c2de",
"interchainGasPaymaster": "0x9024A3902B542C87a5C4A2b3e15d60B2f087Dc3E", "interchainGasPaymaster": "0x9024A3902B542C87a5C4A2b3e15d60B2f087Dc3E",
"interchainSecurityModule": "0x8750ac24C3bE28b406fBCD664AbabF676d3aCB29", "interchainSecurityModule": "0x9dccF81bB9f419425b0a6584E8800556B92209Cc",
"mailbox": "0x3a867fCfFeC2B790970eeBDC9023E75B0a172aa7", "mailbox": "0x3a867fCfFeC2B790970eeBDC9023E75B0a172aa7",
"merkleTreeHook": "0x9c44E6b8F0dB517C2c3a0478caaC5349b614F912", "merkleTreeHook": "0x9c44E6b8F0dB517C2c3a0478caaC5349b614F912",
"pausableHook": "0x53e912b41125d6094590a7DBEf1360d3d56EEa19", "pausableHook": "0x53e912b41125d6094590a7DBEf1360d3d56EEa19",
@ -4617,7 +4626,7 @@
"interchainAccountIsm": "0x61374178e45F65fF9D6252d017Cd580FC60B7654", "interchainAccountIsm": "0x61374178e45F65fF9D6252d017Cd580FC60B7654",
"interchainAccountRouter": "0x783EC5e105234a570eB90f314284E5dBe53bdd90", "interchainAccountRouter": "0x783EC5e105234a570eB90f314284E5dBe53bdd90",
"interchainGasPaymaster": "0xE56Da9D48E698eB70F56aeCC0BC25Ff1710EEA76", "interchainGasPaymaster": "0xE56Da9D48E698eB70F56aeCC0BC25Ff1710EEA76",
"interchainSecurityModule": "0xE89fF24e1979F6AbD6b71b733cc62d1289d193c4", "interchainSecurityModule": "0x9d1481A1fc2515aeE0Bf4eEeDDB75893DfAF0752",
"mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", "mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E",
"merkleTreeHook": "0x4757Bdd68Bba8a6d901cEC82E61E184fF2986918", "merkleTreeHook": "0x4757Bdd68Bba8a6d901cEC82E61E184fF2986918",
"pausableHook": "0x9024A3902B542C87a5C4A2b3e15d60B2f087Dc3E", "pausableHook": "0x9024A3902B542C87a5C4A2b3e15d60B2f087Dc3E",
@ -4681,7 +4690,7 @@
"interchainAccountIsm": "0xFB9e40D811Cea562cc8a322b029eF2BDcC3ef6ed", "interchainAccountIsm": "0xFB9e40D811Cea562cc8a322b029eF2BDcC3ef6ed",
"interchainAccountRouter": "0xeE8C0E1EeBfFCC451a013336386eA53E42a44451", "interchainAccountRouter": "0xeE8C0E1EeBfFCC451a013336386eA53E42a44451",
"interchainGasPaymaster": "0x168DFF0Ad2b180F3801883Fe5Ae56d7E7d91D5f4", "interchainGasPaymaster": "0x168DFF0Ad2b180F3801883Fe5Ae56d7E7d91D5f4",
"interchainSecurityModule": "0xFF16628ff85F145Ce6d1712014D46DcFB52da75A", "interchainSecurityModule": "0x8f93c32C19986B891beA2bF317686Aa2336b3854",
"mailbox": "0x02d16BC51af6BfD153d67CA61754cF912E82C4d9", "mailbox": "0x02d16BC51af6BfD153d67CA61754cF912E82C4d9",
"merkleTreeHook": "0x148CF67B8A242c1360bb2C93fCe203EC4d4f9B56", "merkleTreeHook": "0x148CF67B8A242c1360bb2C93fCe203EC4d4f9B56",
"pausableHook": "0xb129828B9EDa48192D0B2db35D0E40dCF51B3594", "pausableHook": "0xb129828B9EDa48192D0B2db35D0E40dCF51B3594",
@ -4746,7 +4755,7 @@
"interchainAccountIsm": "0xb5668713E9BA8bC96f97D691663E70b54CE90b0A", "interchainAccountIsm": "0xb5668713E9BA8bC96f97D691663E70b54CE90b0A",
"interchainAccountRouter": "0xc5068BB6803ADbe5600DE5189fe27A4dAcE31170", "interchainAccountRouter": "0xc5068BB6803ADbe5600DE5189fe27A4dAcE31170",
"interchainGasPaymaster": "0xA1Df6B70044029a2D1eDDC50EfDE2813e478140a", "interchainGasPaymaster": "0xA1Df6B70044029a2D1eDDC50EfDE2813e478140a",
"interchainSecurityModule": "0x729E790E70902429873c23BaA73eE39aCEEfc461", "interchainSecurityModule": "0x01180E7B92A4fEA1e250C92E32A02Df1cA058Fe0",
"mailbox": "0x783EC5e105234a570eB90f314284E5dBe53bdd90", "mailbox": "0x783EC5e105234a570eB90f314284E5dBe53bdd90",
"merkleTreeHook": "0x25d668D37f20E6f396cB5DF1DFf5A3f2F568e707", "merkleTreeHook": "0x25d668D37f20E6f396cB5DF1DFf5A3f2F568e707",
"pausableHook": "0xC9ab9Dc82F05eA118F266611f4c474529d43b599", "pausableHook": "0xC9ab9Dc82F05eA118F266611f4c474529d43b599",
@ -4771,6 +4780,69 @@
"transactionOverrides": { "transactionOverrides": {
"gasPrice": 100000000 "gasPrice": 100000000
} }
},
"stride": {
"bech32Prefix": "stride",
"blockExplorers": [
{
"apiUrl": "https://www.mintscan.io/stride",
"family": "other",
"name": "Mintscan",
"url": "https://www.mintscan.io/stride"
}
],
"blocks": {
"confirmations": 1,
"estimateBlockTime": 5,
"reorgPeriod": 1
},
"chainId": "stride-1",
"deployer": {
"name": "Stride Labs",
"url": "https://www.stride.zone"
},
"displayName": "Stride",
"domainId": 745,
"gasCurrencyCoinGeckoId": "stride",
"grpcUrls": [
{
"http": "https://stride-grpc.publicnode.com:443"
}
],
"isTestnet": false,
"name": "stride",
"nativeToken": {
"decimals": 6,
"denom": "ustrd",
"name": "Stride",
"symbol": "STRD"
},
"protocol": "cosmos",
"restUrls": [
{
"http": "https://stride-api.polkachu.com"
}
],
"rpcUrls": [
{
"http": "https://stride-rpc.polkachu.com"
}
],
"slip44": 118,
"interchainGasPaymaster": "0x602D5BF31F85FE90BF812A5EE6E2CC8CF6998A687125CABEDD120983CB88DA54",
"mailbox": "0x89945750e089d84581f194e1947a58480b335f18386ad4f761f05feebf5e2454",
"merkleTreeHook": "0x7ab4a8c3ba5371e34cd8d5dc584e0d924504fc21c3cbf41c3f64d436176bf007",
"validatorAnnounce": "0xf57d954bf3ddb5f1032a0e020a99e931215cf83ceb4de987c781488065aaae0d",
"gasPrice": {
"denom": "ustrd",
"amount": "0.005"
},
"canonicalAsset": "ustrd",
"contractAddressBytes": 32,
"index": {
"from": 9152000,
"chunk": 5
}
} }
}, },
"defaultRpcConsensusType": "fallback" "defaultRpcConsensusType": "fallback"

@ -170,7 +170,7 @@ where
Ok(logs) => logs, Ok(logs) => logs,
Err(err) => { Err(err) => {
warn!(?err, ?range, "Error fetching logs in range"); warn!(?err, ?range, "Error fetching logs in range");
break SLEEP_DURATION; break Some(SLEEP_DURATION);
} }
}; };
@ -196,13 +196,20 @@ where
// Update cursor // Update cursor
if let Err(err) = cursor.update(logs, range).await { if let Err(err) = cursor.update(logs, range).await {
warn!(?err, "Error updating cursor"); warn!(?err, "Error updating cursor");
break SLEEP_DURATION; break Some(SLEEP_DURATION);
}; };
break Default::default(); break None;
}, },
CursorAction::Sleep(duration) => duration, CursorAction::Sleep(duration) => Some(duration),
}; };
sleep(sleep_duration).await if let Some(sleep_duration) = sleep_duration {
debug!(
cursor = ?cursor,
?sleep_duration,
"Cursor can't make progress, sleeping",
);
sleep(sleep_duration).await
}
} }
async fn dedupe_and_store_logs( async fn dedupe_and_store_logs(

@ -10,13 +10,13 @@ use hyperlane_core::{
config::OperationBatchConfig, AggregationIsm, CcipReadIsm, ContractLocator, HyperlaneAbi, config::OperationBatchConfig, AggregationIsm, CcipReadIsm, ContractLocator, HyperlaneAbi,
HyperlaneDomain, HyperlaneDomainProtocol, HyperlaneMessage, HyperlaneProvider, IndexMode, HyperlaneDomain, HyperlaneDomainProtocol, HyperlaneMessage, HyperlaneProvider, IndexMode,
InterchainGasPaymaster, InterchainGasPayment, InterchainSecurityModule, Mailbox, InterchainGasPaymaster, InterchainGasPayment, InterchainSecurityModule, Mailbox,
MerkleTreeHook, MerkleTreeInsertion, MultisigIsm, RoutingIsm, SequenceAwareIndexer, MerkleTreeHook, MerkleTreeInsertion, MultisigIsm, ReorgPeriod, RoutingIsm,
ValidatorAnnounce, H256, SequenceAwareIndexer, ValidatorAnnounce, H256,
}; };
use hyperlane_cosmos as h_cosmos; use hyperlane_cosmos as h_cosmos;
use hyperlane_ethereum::{ use hyperlane_ethereum::{
self as h_eth, BuildableWithProvider, EthereumInterchainGasPaymasterAbi, EthereumMailboxAbi, self as h_eth, BuildableWithProvider, EthereumInterchainGasPaymasterAbi, EthereumMailboxAbi,
EthereumValidatorAnnounceAbi, EthereumReorgPeriod, EthereumValidatorAnnounceAbi,
}; };
use hyperlane_fuel as h_fuel; use hyperlane_fuel as h_fuel;
use hyperlane_sealevel as h_sealevel; use hyperlane_sealevel as h_sealevel;
@ -45,7 +45,7 @@ pub struct ChainConf {
/// Signer configuration for this chain /// Signer configuration for this chain
pub signer: Option<SignerConf>, pub signer: Option<SignerConf>,
/// The reorg period of the chain, i.e. the number of blocks until finality /// The reorg period of the chain, i.e. the number of blocks until finality
pub reorg_period: u32, pub reorg_period: ReorgPeriod,
/// Addresses of contracts on the chain /// Addresses of contracts on the chain
pub addresses: CoreContractAddresses, pub addresses: CoreContractAddresses,
/// The chain connection details /// The chain connection details
@ -272,13 +272,13 @@ impl ChainConf {
match &self.connection { match &self.connection {
ChainConnectionConf::Ethereum(conf) => { ChainConnectionConf::Ethereum(conf) => {
let reorg_period =
EthereumReorgPeriod::try_from(&self.reorg_period).context(ctx)?;
self.build_ethereum( self.build_ethereum(
conf, conf,
&locator, &locator,
metrics, metrics,
h_eth::SequenceIndexerBuilder { h_eth::SequenceIndexerBuilder { reorg_period },
reorg_period: self.reorg_period,
},
) )
.await .await
} }
@ -289,11 +289,12 @@ impl ChainConf {
} }
ChainConnectionConf::Cosmos(conf) => { ChainConnectionConf::Cosmos(conf) => {
let signer = self.cosmos_signer().await.context(ctx)?; let signer = self.cosmos_signer().await.context(ctx)?;
let reorg_period = self.reorg_period.as_blocks().context(ctx)?;
let indexer = Box::new(h_cosmos::CosmosMailboxDispatchIndexer::new( let indexer = Box::new(h_cosmos::CosmosMailboxDispatchIndexer::new(
conf.clone(), conf.clone(),
locator, locator,
signer, signer,
self.reorg_period, reorg_period,
)?); )?);
Ok(indexer as Box<dyn SequenceAwareIndexer<HyperlaneMessage>>) Ok(indexer as Box<dyn SequenceAwareIndexer<HyperlaneMessage>>)
} }
@ -311,13 +312,13 @@ impl ChainConf {
match &self.connection { match &self.connection {
ChainConnectionConf::Ethereum(conf) => { ChainConnectionConf::Ethereum(conf) => {
let reorg_period =
EthereumReorgPeriod::try_from(&self.reorg_period).context(ctx)?;
self.build_ethereum( self.build_ethereum(
conf, conf,
&locator, &locator,
metrics, metrics,
h_eth::DeliveryIndexerBuilder { h_eth::DeliveryIndexerBuilder { reorg_period },
reorg_period: self.reorg_period,
},
) )
.await .await
} }
@ -328,11 +329,12 @@ impl ChainConf {
} }
ChainConnectionConf::Cosmos(conf) => { ChainConnectionConf::Cosmos(conf) => {
let signer = self.cosmos_signer().await.context(ctx)?; let signer = self.cosmos_signer().await.context(ctx)?;
let reorg_period = self.reorg_period.as_blocks().context(ctx)?;
let indexer = Box::new(h_cosmos::CosmosMailboxDeliveryIndexer::new( let indexer = Box::new(h_cosmos::CosmosMailboxDeliveryIndexer::new(
conf.clone(), conf.clone(),
locator, locator,
signer, signer,
self.reorg_period, reorg_period,
)?); )?);
Ok(indexer as Box<dyn SequenceAwareIndexer<H256>>) Ok(indexer as Box<dyn SequenceAwareIndexer<H256>>)
} }
@ -389,13 +391,15 @@ impl ChainConf {
match &self.connection { match &self.connection {
ChainConnectionConf::Ethereum(conf) => { ChainConnectionConf::Ethereum(conf) => {
let reorg_period =
EthereumReorgPeriod::try_from(&self.reorg_period).context(ctx)?;
self.build_ethereum( self.build_ethereum(
conf, conf,
&locator, &locator,
metrics, metrics,
h_eth::InterchainGasPaymasterIndexerBuilder { h_eth::InterchainGasPaymasterIndexerBuilder {
mailbox_address: self.addresses.mailbox.into(), mailbox_address: self.addresses.mailbox.into(),
reorg_period: self.reorg_period, reorg_period,
}, },
) )
.await .await
@ -408,10 +412,11 @@ impl ChainConf {
Ok(indexer as Box<dyn SequenceAwareIndexer<InterchainGasPayment>>) Ok(indexer as Box<dyn SequenceAwareIndexer<InterchainGasPayment>>)
} }
ChainConnectionConf::Cosmos(conf) => { ChainConnectionConf::Cosmos(conf) => {
let reorg_period = self.reorg_period.as_blocks().context(ctx)?;
let indexer = Box::new(h_cosmos::CosmosInterchainGasPaymasterIndexer::new( let indexer = Box::new(h_cosmos::CosmosInterchainGasPaymasterIndexer::new(
conf.clone(), conf.clone(),
locator, locator,
self.reorg_period, reorg_period,
)?); )?);
Ok(indexer as Box<dyn SequenceAwareIndexer<InterchainGasPayment>>) Ok(indexer as Box<dyn SequenceAwareIndexer<InterchainGasPayment>>)
} }
@ -429,13 +434,13 @@ impl ChainConf {
match &self.connection { match &self.connection {
ChainConnectionConf::Ethereum(conf) => { ChainConnectionConf::Ethereum(conf) => {
let reorg_period =
EthereumReorgPeriod::try_from(&self.reorg_period).context(ctx)?;
self.build_ethereum( self.build_ethereum(
conf, conf,
&locator, &locator,
metrics, metrics,
h_eth::MerkleTreeHookIndexerBuilder { h_eth::MerkleTreeHookIndexerBuilder { reorg_period },
reorg_period: self.reorg_period,
},
) )
.await .await
} }
@ -450,12 +455,13 @@ impl ChainConf {
} }
ChainConnectionConf::Cosmos(conf) => { ChainConnectionConf::Cosmos(conf) => {
let signer = self.cosmos_signer().await.context(ctx)?; let signer = self.cosmos_signer().await.context(ctx)?;
let reorg_period = self.reorg_period.as_blocks().context(ctx)?;
let indexer = Box::new(h_cosmos::CosmosMerkleTreeHookIndexer::new( let indexer = Box::new(h_cosmos::CosmosMerkleTreeHookIndexer::new(
conf.clone(), conf.clone(),
locator, locator,
// TODO: remove signer requirement entirely // TODO: remove signer requirement entirely
signer, signer,
self.reorg_period, reorg_period,
)?); )?);
Ok(indexer as Box<dyn SequenceAwareIndexer<MerkleTreeInsertion>>) Ok(indexer as Box<dyn SequenceAwareIndexer<MerkleTreeInsertion>>)
} }

@ -180,7 +180,7 @@ mod test {
use std::panic::AssertUnwindSafe; use std::panic::AssertUnwindSafe;
use futures_util::FutureExt; use futures_util::FutureExt;
use hyperlane_core::{ReorgEvent, H256}; use hyperlane_core::{ReorgEvent, ReorgPeriod, H256};
#[tokio::test] #[tokio::test]
async fn test_build_and_validate() { async fn test_build_and_validate() {
@ -209,7 +209,7 @@ mod test {
.unwrap(); .unwrap();
let dummy_checkpoint_index = 56; let dummy_checkpoint_index = 56;
let unix_timestamp = 1620000000; let unix_timestamp = 1620000000;
let reorg_period = 5; let reorg_period = ReorgPeriod::from_blocks(5);
let dummy_reorg_event = ReorgEvent { let dummy_reorg_event = ReorgEvent {
local_merkle_root: dummy_local_merkle_root, local_merkle_root: dummy_local_merkle_root,
canonical_merkle_root: dummy_canonical_merkle_root, canonical_merkle_root: dummy_canonical_merkle_root,
@ -237,7 +237,9 @@ mod test {
canonical_merkle_root: 0xb437b888332ef12f7260c7f679aad3c96b91ab81c2dc7242f8b290f0b6bba92b, canonical_merkle_root: 0xb437b888332ef12f7260c7f679aad3c96b91ab81c2dc7242f8b290f0b6bba92b,
checkpoint_index: 56, checkpoint_index: 56,
unix_timestamp: 1620000000, unix_timestamp: 1620000000,
reorg_period: 5, reorg_period: Blocks(
5,
),
}. Please resolve the reorg to continue."# }. Please resolve the reorg to continue."#
); );
} else { } else {

@ -19,7 +19,7 @@ use url::Url;
use h_cosmos::RawCosmosAmount; use h_cosmos::RawCosmosAmount;
use hyperlane_core::{ use hyperlane_core::{
cfg_unwrap_all, config::*, HyperlaneDomain, HyperlaneDomainProtocol, cfg_unwrap_all, config::*, HyperlaneDomain, HyperlaneDomainProtocol,
HyperlaneDomainTechnicalStack, IndexMode, HyperlaneDomainTechnicalStack, IndexMode, ReorgPeriod,
}; };
use crate::settings::{ use crate::settings::{
@ -34,6 +34,8 @@ pub use self::json_value_parser::ValueParser;
mod connection_parser; mod connection_parser;
mod json_value_parser; mod json_value_parser;
const DEFAULT_CHUNK_SIZE: u32 = 1999;
/// The base agent config /// The base agent config
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(transparent)] #[serde(transparent)]
@ -136,8 +138,8 @@ fn parse_chain(
.chain(&mut err) .chain(&mut err)
.get_opt_key("blocks") .get_opt_key("blocks")
.get_key("reorgPeriod") .get_key("reorgPeriod")
.parse_u32() .parse_value("Invalid reorgPeriod")
.unwrap_or(1); .unwrap_or(ReorgPeriod::from_blocks(1));
let rpcs = parse_base_and_override_urls(&chain, "rpcUrls", "customRpcUrls", "http", &mut err); let rpcs = parse_base_and_override_urls(&chain, "rpcUrls", "customRpcUrls", "http", &mut err);
@ -152,7 +154,7 @@ fn parse_chain(
.get_opt_key("index") .get_opt_key("index")
.get_opt_key("chunk") .get_opt_key("chunk")
.parse_u32() .parse_u32()
.unwrap_or(1999); .unwrap_or(DEFAULT_CHUNK_SIZE);
let mode = chain let mode = chain
.chain(&mut err) .chain(&mut err)
.get_opt_key("index") .get_opt_key("index")

@ -3,16 +3,20 @@
use std::{ use std::{
fmt::{Debug, Formatter}, fmt::{Debug, Formatter},
hash::{Hash, Hasher}, hash::{Hash, Hasher},
num::NonZeroU32,
}; };
use derive_new::new; use derive_new::new;
use num_derive::FromPrimitive; use num_derive::FromPrimitive;
use num_traits::FromPrimitive; use num_traits::FromPrimitive;
use serde::Serialize; use serde::{Deserialize, Deserializer, Serialize, Serializer};
#[cfg(feature = "strum")] #[cfg(feature = "strum")]
use strum::{EnumIter, EnumString, IntoStaticStr}; use strum::{EnumIter, EnumString, IntoStaticStr};
use crate::{utils::many_to_one, HyperlaneProtocolError, IndexMode, H160, H256}; use crate::{
utils::many_to_one, ChainCommunicationError, HyperlaneProtocolError, IndexMode, H160, H256,
};
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Address(pub bytes::Bytes); pub struct Address(pub bytes::Bytes);
@ -39,6 +43,80 @@ impl<'a> std::fmt::Display for ContractLocator<'a> {
} }
} }
#[derive(Default, Debug, Clone, PartialEq)]
pub enum ReorgPeriod {
#[default]
None,
Blocks(NonZeroU32),
Tag(String),
}
impl ReorgPeriod {
pub fn from_blocks(blocks: u32) -> Self {
NonZeroU32::try_from(blocks)
.map(ReorgPeriod::Blocks)
.unwrap_or(ReorgPeriod::None)
}
pub fn as_blocks(&self) -> Result<u32, ChainCommunicationError> {
match self {
ReorgPeriod::None => Ok(0),
ReorgPeriod::Blocks(blocks) => Ok(blocks.get()),
ReorgPeriod::Tag(_) => Err(ChainCommunicationError::InvalidReorgPeriod(self.clone())),
}
}
pub fn is_none(&self) -> bool {
matches!(self, ReorgPeriod::None)
}
}
impl Serialize for ReorgPeriod {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match self {
ReorgPeriod::None => serializer.serialize_u32(0),
ReorgPeriod::Blocks(blocks) => serializer.serialize_u32(blocks.get()),
ReorgPeriod::Tag(tag) => serializer.serialize_str(tag),
}
}
}
impl<'de> Deserialize<'de> for ReorgPeriod {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
use serde::de;
struct ReorgPeriodVisitor;
impl<'de> de::Visitor<'de> for ReorgPeriodVisitor {
type Value = ReorgPeriod;
fn expecting(&self, f: &mut Formatter) -> std::fmt::Result {
f.write_str("reorgPeriod as a number or string")
}
fn visit_u64<E: de::Error>(self, v: u64) -> Result<Self::Value, E> {
let v = v.try_into().map_err(de::Error::custom)?;
Ok(ReorgPeriod::from_blocks(v))
}
fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
match v.parse::<u32>() {
Ok(v) => self.visit_u32(v),
Err(_) => Ok(ReorgPeriod::Tag(v.to_string())),
}
}
}
deserializer.deserialize_any(ReorgPeriodVisitor)
}
}
/// All domains supported by Hyperlane. /// All domains supported by Hyperlane.
#[derive(FromPrimitive, PartialEq, Eq, Debug, Clone, Copy, Hash, Serialize)] #[derive(FromPrimitive, PartialEq, Eq, Debug, Clone, Copy, Hash, Serialize)]
#[cfg_attr( #[cfg_attr(
@ -221,6 +299,7 @@ pub enum HyperlaneDomainTechnicalStack {
OpStack, OpStack,
PolygonCDK, PolygonCDK,
PolkadotSubstrate, PolkadotSubstrate,
ZkSync,
#[default] #[default]
Other, Other,
} }
@ -304,6 +383,7 @@ impl KnownHyperlaneDomain {
HyperlaneDomainTechnicalStack::PolkadotSubstrate: [ HyperlaneDomainTechnicalStack::PolkadotSubstrate: [
Moonbeam, Tangle Moonbeam, Tangle
], ],
HyperlaneDomainTechnicalStack::ZkSync: [],
HyperlaneDomainTechnicalStack::Other: [ HyperlaneDomainTechnicalStack::Other: [
Avalanche, BinanceSmartChain, Celo, EclipseMainnet, Endurance, Ethereum, Avalanche, BinanceSmartChain, Celo, EclipseMainnet, Endurance, Ethereum,
FuseMainnet, Gnosis, Injective, Linea, Lukso, Neutron, Osmosis, Polygon, FuseMainnet, Gnosis, Injective, Linea, Lukso, Neutron, Osmosis, Polygon,
@ -505,9 +585,9 @@ impl HyperlaneDomain {
#[cfg(test)] #[cfg(test)]
#[cfg(feature = "strum")] #[cfg(feature = "strum")]
mod tests { mod tests {
use std::str::FromStr; use std::{num::NonZeroU32, str::FromStr};
use crate::KnownHyperlaneDomain; use crate::{KnownHyperlaneDomain, ReorgPeriod};
#[test] #[test]
fn domain_strings() { fn domain_strings() {
@ -560,4 +640,32 @@ mod tests {
); );
assert!("foo".parse::<KnownHyperlaneDomain>().is_err()); assert!("foo".parse::<KnownHyperlaneDomain>().is_err());
} }
#[test]
fn parse_reorg_period() {
assert_eq!(
serde_json::from_value::<ReorgPeriod>(0.into()).unwrap(),
ReorgPeriod::None
);
assert_eq!(
serde_json::from_value::<ReorgPeriod>("0".into()).unwrap(),
ReorgPeriod::None
);
assert_eq!(
serde_json::from_value::<ReorgPeriod>(12.into()).unwrap(),
ReorgPeriod::Blocks(NonZeroU32::new(12).unwrap())
);
assert_eq!(
serde_json::from_value::<ReorgPeriod>("12".into()).unwrap(),
ReorgPeriod::Blocks(NonZeroU32::new(12).unwrap())
);
assert_eq!(
serde_json::from_value::<ReorgPeriod>("finalized".into()).unwrap(),
ReorgPeriod::Tag("finalized".into())
);
}
} }

@ -10,8 +10,10 @@ use crate::config::StrOrIntParseError;
use crate::rpc_clients::RpcClientError; use crate::rpc_clients::RpcClientError;
use std::string::FromUtf8Error; use std::string::FromUtf8Error;
use crate::HyperlaneProviderError; use crate::{
use crate::{Error as PrimitiveTypeError, HyperlaneSignerError, H256, U256}; Error as PrimitiveTypeError, HyperlaneProviderError, HyperlaneSignerError, ReorgPeriod, H256,
U256,
};
/// The result of interacting with a chain. /// The result of interacting with a chain.
pub type ChainResult<T> = Result<T, ChainCommunicationError>; pub type ChainResult<T> = Result<T, ChainCommunicationError>;
@ -91,9 +93,6 @@ pub enum ChainCommunicationError {
/// Failed to parse strings or integers /// Failed to parse strings or integers
#[error("Data parsing error {0:?}")] #[error("Data parsing error {0:?}")]
StrOrIntParseError(#[from] StrOrIntParseError), StrOrIntParseError(#[from] StrOrIntParseError),
/// BlockNotFoundError
#[error("Block not found: {0:?}")]
BlockNotFound(H256),
/// utf8 error /// utf8 error
#[error("{0}")] #[error("{0}")]
Utf8(#[from] FromUtf8Error), Utf8(#[from] FromUtf8Error),
@ -157,6 +156,9 @@ pub enum ChainCommunicationError {
/// Hyperlane signer error /// Hyperlane signer error
#[error("{0}")] #[error("{0}")]
HyperlaneSignerError(#[from] HyperlaneSignerError), HyperlaneSignerError(#[from] HyperlaneSignerError),
/// Invalid reorg period
#[error("Invalid reorg period: {0:?}")]
InvalidReorgPeriod(ReorgPeriod),
} }
impl ChainCommunicationError { impl ChainCommunicationError {

@ -1,12 +1,11 @@
use std::fmt::Debug; use std::fmt::Debug;
use std::num::NonZeroU64;
use async_trait::async_trait; use async_trait::async_trait;
use derive_new::new; use derive_new::new;
use crate::{ use crate::{
traits::TxOutcome, utils::domain_hash, BatchItem, ChainCommunicationError, ChainResult, traits::TxOutcome, utils::domain_hash, BatchItem, ChainCommunicationError, ChainResult,
HyperlaneContract, HyperlaneMessage, QueueOperation, TxCostEstimate, H256, U256, HyperlaneContract, HyperlaneMessage, QueueOperation, ReorgPeriod, TxCostEstimate, H256, U256,
}; };
/// Interface for the Mailbox chain contract. Allows abstraction over different /// Interface for the Mailbox chain contract. Allows abstraction over different
@ -20,9 +19,9 @@ pub trait Mailbox: HyperlaneContract + Send + Sync + Debug {
/// Gets the current leaf count of the merkle tree /// Gets the current leaf count of the merkle tree
/// ///
/// - `lag` is how far behind the current block to query, if not specified /// - `reorg_period` is how far behind the current block to query, if not specified
/// it will query at the latest block. /// it will query at the latest block.
async fn count(&self, lag: Option<NonZeroU64>) -> ChainResult<u32>; async fn count(&self, reorg_period: &ReorgPeriod) -> ChainResult<u32>;
/// Fetch the status of a message /// Fetch the status of a message
async fn delivered(&self, id: H256) -> ChainResult<bool>; async fn delivered(&self, id: H256) -> ChainResult<bool>;

@ -1,11 +1,11 @@
use std::fmt::Debug; use std::fmt::Debug;
use std::num::NonZeroU64;
use async_trait::async_trait; use async_trait::async_trait;
use auto_impl::auto_impl; use auto_impl::auto_impl;
use crate::{ use crate::{
accumulator::incremental::IncrementalMerkle, ChainResult, Checkpoint, HyperlaneContract, accumulator::incremental::IncrementalMerkle, ChainResult, Checkpoint, HyperlaneContract,
ReorgPeriod,
}; };
/// Interface for the MerkleTreeHook chain contract. Allows abstraction over different /// Interface for the MerkleTreeHook chain contract. Allows abstraction over different
@ -15,19 +15,19 @@ use crate::{
pub trait MerkleTreeHook: HyperlaneContract + Send + Sync + Debug { pub trait MerkleTreeHook: HyperlaneContract + Send + Sync + Debug {
/// Return the incremental merkle tree in storage /// Return the incremental merkle tree in storage
/// ///
/// - `lag` is how far behind the current block to query, if not specified /// - `reorg_period` is how far behind the current block to query, if not specified
/// it will query at the latest block. /// it will query at the latest block.
async fn tree(&self, lag: Option<NonZeroU64>) -> ChainResult<IncrementalMerkle>; async fn tree(&self, reorg_period: &ReorgPeriod) -> ChainResult<IncrementalMerkle>;
/// Gets the current leaf count of the merkle tree /// Gets the current leaf count of the merkle tree
/// ///
/// - `lag` is how far behind the current block to query, if not specified /// - `reorg_period` is how far behind the current block to query, if not specified
/// it will query at the latest block. /// it will query at the latest block.
async fn count(&self, lag: Option<NonZeroU64>) -> ChainResult<u32>; async fn count(&self, reorg_period: &ReorgPeriod) -> ChainResult<u32>;
/// Get the latest checkpoint. /// Get the latest checkpoint.
/// ///
/// - `lag` is how far behind the current block to query, if not specified /// - `reorg_period` is how far behind the current block to query, if not specified
/// it will query at the latest block. /// it will query at the latest block.
async fn latest_checkpoint(&self, lag: Option<NonZeroU64>) -> ChainResult<Checkpoint>; async fn latest_checkpoint(&self, reorg_period: &ReorgPeriod) -> ChainResult<Checkpoint>;
} }

@ -16,8 +16,8 @@ use crate::{BlockInfo, ChainInfo, ChainResult, HyperlaneChain, TxnInfo, H256, U2
#[async_trait] #[async_trait]
#[auto_impl(&, Box, Arc)] #[auto_impl(&, Box, Arc)]
pub trait HyperlaneProvider: HyperlaneChain + Send + Sync + Debug { pub trait HyperlaneProvider: HyperlaneChain + Send + Sync + Debug {
/// Get block info for a given block hash /// Get block info for a given block height
async fn get_block_by_hash(&self, hash: &H256) -> ChainResult<BlockInfo>; async fn get_block_by_height(&self, height: u64) -> ChainResult<BlockInfo>;
/// Get txn info for a given txn hash /// Get txn info for a given txn hash
async fn get_txn_by_hash(&self, hash: &H256) -> ChainResult<TxnInfo>; async fn get_txn_by_hash(&self, hash: &H256) -> ChainResult<TxnInfo>;
@ -35,13 +35,19 @@ pub trait HyperlaneProvider: HyperlaneChain + Send + Sync + Debug {
/// Errors when querying for provider information. /// Errors when querying for provider information.
#[derive(Error, Debug)] #[derive(Error, Debug)]
pub enum HyperlaneProviderError { pub enum HyperlaneProviderError {
/// The requested block hash is not yet known by the provider
#[error("Block is not part of chain yet {0:?}")]
BlockIsNotPartOfChainYet(H256),
/// The provider did not return the gas which was used /// The provider did not return the gas which was used
#[error("Provider did not return gas used")] #[error("Provider did not return gas used")]
NoGasUsed, NoGasUsed,
/// Could not find a transaction, block, or other object /// Could not find a transaction by hash
#[error("Could not find object from provider with hash {0:?}")] #[error("Could not find transaction from provider with hash {0:?}")]
CouldNotFindObjectByHash(H256), CouldNotFindTransactionByHash(H256),
/// Could not find a block by height
#[error("Could not find block from provider with height {0:?}")]
CouldNotFindBlockByHeight(u64),
/// The requested block does not have its hash
#[error("Block with height {0:?} does not contain its hash")]
BlockWithoutHash(u64),
/// Incorrect block is received
#[error("Requested block with height {0:?}, received block with height {1:?}")]
IncorrectBlockByHeight(u64, u64),
} }

@ -0,0 +1,17 @@
use crate::H256;
/// Struct `BlockId` contains two types of identifiers for the same block: hash and height.
#[derive(Debug, Default, Copy, Clone)]
pub struct BlockId {
/// Block hash
pub hash: H256,
/// Block height
pub height: u64,
}
impl BlockId {
/// Creates instance of `BlockId` struct
pub fn new(hash: H256, height: u64) -> Self {
Self { hash, height }
}
}

@ -9,6 +9,7 @@ pub use self::primitive_types::*;
pub use ::primitive_types as ethers_core_types; pub use ::primitive_types as ethers_core_types;
pub use account_address_type::AccountAddressType; pub use account_address_type::AccountAddressType;
pub use announcement::*; pub use announcement::*;
pub use block_id::BlockId;
pub use chain_data::*; pub use chain_data::*;
pub use checkpoint::*; pub use checkpoint::*;
pub use indexing::*; pub use indexing::*;
@ -23,6 +24,7 @@ use crate::{Decode, Encode, HyperlaneProtocolError};
/// This module contains enum for account address type /// This module contains enum for account address type
mod account_address_type; mod account_address_type;
mod announcement; mod announcement;
mod block_id;
mod chain_data; mod chain_data;
mod checkpoint; mod checkpoint;
mod indexing; mod indexing;

@ -1,7 +1,7 @@
use derive_new::new; use derive_new::new;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::H256; use crate::{ReorgPeriod, H256};
/// Details about a detected chain reorg, from an agent's perspective /// Details about a detected chain reorg, from an agent's perspective
#[derive(Debug, Clone, Serialize, Deserialize, new)] #[derive(Debug, Clone, Serialize, Deserialize, new)]
@ -15,6 +15,6 @@ pub struct ReorgEvent {
pub checkpoint_index: u32, pub checkpoint_index: u32,
/// the timestamp when the reorg was detected, in seconds since the Unix epoch /// the timestamp when the reorg was detected, in seconds since the Unix epoch
pub unix_timestamp: u64, pub unix_timestamp: u64,
/// the reorg period configured for the agent, in blocks /// the reorg period configured for the agent
pub reorg_period: u64, pub reorg_period: ReorgPeriod,
} }

@ -1,7 +1,5 @@
#![allow(non_snake_case)] #![allow(non_snake_case)]
use std::num::NonZeroU64;
use async_trait::async_trait; use async_trait::async_trait;
use mockall::*; use mockall::*;
@ -28,11 +26,11 @@ mock! {
nonce: usize, nonce: usize,
) -> ChainResult<Option<H256>> {} ) -> ChainResult<Option<H256>> {}
pub fn _tree(&self, maybe_lag: Option<NonZeroU64>) -> ChainResult<IncrementalMerkle> {} pub fn _tree(&self, reorg_period: &ReorgPeriod) -> ChainResult<IncrementalMerkle> {}
pub fn _count(&self, maybe_lag: Option<NonZeroU64>) -> ChainResult<u32> {} pub fn _count(&self, reorg_period: &ReorgPeriod) -> ChainResult<u32> {}
pub fn _latest_checkpoint(&self, maybe_lag: Option<NonZeroU64>) -> ChainResult<Checkpoint> {} pub fn _latest_checkpoint(&self, reorg_period: &ReorgPeriod) -> ChainResult<Checkpoint> {}
pub fn _default_ism(&self) -> ChainResult<H256> {} pub fn _default_ism(&self) -> ChainResult<H256> {}
pub fn _recipient_ism(&self, recipient: H256) -> ChainResult<H256> {} pub fn _recipient_ism(&self, recipient: H256) -> ChainResult<H256> {}
@ -68,8 +66,8 @@ impl std::fmt::Debug for MockMailboxContract {
#[async_trait] #[async_trait]
impl Mailbox for MockMailboxContract { impl Mailbox for MockMailboxContract {
async fn count(&self, maybe_lag: Option<NonZeroU64>) -> ChainResult<u32> { async fn count(&self, reorg_period: &ReorgPeriod) -> ChainResult<u32> {
self._count(maybe_lag) self._count(reorg_period)
} }
async fn default_ism(&self) -> ChainResult<H256> { async fn default_ism(&self) -> ChainResult<H256> {

@ -1,350 +0,0 @@
{
"bsc": {
"chainId": 56,
"domainId": 56,
"name": "bsc",
"protocol": "ethereum",
"displayName": "Binance Smart Chain",
"displayNameShort": "Binance",
"nativeToken": {
"decimals": 18,
"name": "BNB",
"symbol": "BNB"
},
"rpcUrls": [
{
"http": "https://bsc-dataseed.binance.org"
},
{
"http": "https://rpc.ankr.com/bsc"
}
],
"blockExplorers": [
{
"name": "BscScan",
"url": "https://bscscan.com",
"apiUrl": "https://api.bscscan.com/api",
"family": "etherscan"
}
],
"blocks": {
"confirmations": 1,
"reorgPeriod": 15,
"estimateBlockTime": 3
},
"gasCurrencyCoinGeckoId": "binancecoin",
"gnosisSafeTransactionServiceUrl": "https://safe-transaction-bsc.safe.global/",
"transactionOverrides": {
"gasPrice": 7000000000
}
},
"avalanche": {
"chainId": 43114,
"domainId": 43114,
"name": "avalanche",
"protocol": "ethereum",
"displayName": "Avalanche",
"nativeToken": {
"decimals": 18,
"name": "Avalanche",
"symbol": "AVAX"
},
"rpcUrls": [
{
"http": "https://api.avax.network/ext/bc/C/rpc",
"pagination": {
"maxBlockRange": 100000,
"minBlockNumber": 6765067
}
}
],
"blockExplorers": [
{
"name": "SnowTrace",
"url": "https://snowtrace.io",
"apiUrl": "https://api.snowtrace.io/api",
"family": "other"
}
],
"blocks": {
"confirmations": 3,
"reorgPeriod": 3,
"estimateBlockTime": 2
},
"gasCurrencyCoinGeckoId": "avalanche-2",
"gnosisSafeTransactionServiceUrl": "https://safe-transaction-avalanche.safe.global/"
},
"polygon": {
"chainId": 137,
"domainId": 137,
"name": "polygon",
"protocol": "ethereum",
"displayName": "Polygon",
"nativeToken": {
"name": "Ether",
"symbol": "ETH",
"decimals": 18
},
"rpcUrls": [
{
"http": "https://rpc-mainnet.matic.quiknode.pro",
"pagination": {
"maxBlockRange": 10000,
"minBlockNumber": 19657100
}
},
{
"http": "https://polygon-rpc.com"
}
],
"blockExplorers": [
{
"name": "PolygonScan",
"url": "https://polygonscan.com",
"apiUrl": "https://api.polygonscan.com/api",
"family": "etherscan"
}
],
"blocks": {
"confirmations": 3,
"reorgPeriod": 256,
"estimateBlockTime": 2
},
"gasCurrencyCoinGeckoId": "matic-network",
"gnosisSafeTransactionServiceUrl": "https://safe-transaction-polygon.safe.global/",
"transactionOverrides": {
"maxFeePerGas": 500000000000,
"maxPriorityFeePerGas": 100000000000
}
},
"celo": {
"chainId": 42220,
"domainId": 42220,
"name": "celo",
"protocol": "ethereum",
"displayName": "Celo",
"nativeToken": {
"decimals": 18,
"name": "CELO",
"symbol": "CELO"
},
"rpcUrls": [
{
"http": "https://forno.celo.org"
}
],
"blockExplorers": [
{
"name": "CeloScan",
"url": "https://celoscan.io",
"apiUrl": "https://api.celoscan.io/api",
"family": "etherscan"
},
{
"name": "Blockscout",
"url": "https://explorer.celo.org",
"apiUrl": "https://explorer.celo.org/mainnet/api",
"family": "blockscout"
}
],
"blocks": {
"confirmations": 1,
"reorgPeriod": 0,
"estimateBlockTime": 5
},
"gnosisSafeTransactionServiceUrl": "https://mainnet-tx-svc.celo-safe-prod.celo-networks-dev.org/"
},
"arbitrum": {
"chainId": 42161,
"domainId": 42161,
"name": "arbitrum",
"protocol": "ethereum",
"displayName": "Arbitrum",
"nativeToken": {
"name": "Ether",
"symbol": "ETH",
"decimals": 18
},
"rpcUrls": [
{
"http": "https://arb1.arbitrum.io/rpc"
}
],
"blockExplorers": [
{
"name": "Arbiscan",
"url": "https://arbiscan.io",
"apiUrl": "https://api.arbiscan.io/api",
"family": "etherscan"
}
],
"blocks": {
"confirmations": 1,
"reorgPeriod": 0,
"estimateBlockTime": 3
},
"gasCurrencyCoinGeckoId": "ethereum",
"gnosisSafeTransactionServiceUrl": "https://safe-transaction-arbitrum.safe.global/"
},
"optimism": {
"chainId": 10,
"domainId": 10,
"name": "optimism",
"protocol": "ethereum",
"displayName": "Optimism",
"nativeToken": {
"name": "Ether",
"symbol": "ETH",
"decimals": 18
},
"rpcUrls": [
{
"http": "https://mainnet.optimism.io"
}
],
"blockExplorers": [
{
"name": "Etherscan",
"url": "https://optimistic.etherscan.io",
"apiUrl": "https://api-optimistic.etherscan.io/api",
"family": "etherscan"
}
],
"blocks": {
"confirmations": 1,
"reorgPeriod": 0,
"estimateBlockTime": 3
},
"gasCurrencyCoinGeckoId": "ethereum",
"gnosisSafeTransactionServiceUrl": "https://safe-transaction-optimism.safe.global/"
},
"ethereum": {
"chainId": 1,
"domainId": 1,
"name": "ethereum",
"protocol": "ethereum",
"displayName": "Ethereum",
"nativeToken": {
"name": "Ether",
"symbol": "ETH",
"decimals": 18
},
"rpcUrls": [
{
"http": "https://mainnet.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161"
},
{
"http": "https://cloudflare-eth.com"
}
],
"blockExplorers": [
{
"name": "Etherscan",
"url": "https://etherscan.io",
"apiUrl": "https://api.etherscan.io/api",
"family": "etherscan"
},
{
"name": "Blockscout",
"url": "https://blockscout.com/eth/mainnet",
"apiUrl": "https://blockscout.com/eth/mainnet/api",
"family": "blockscout"
}
],
"blocks": {
"confirmations": 3,
"reorgPeriod": 14,
"estimateBlockTime": 13
},
"gnosisSafeTransactionServiceUrl": "https://safe-transaction-mainnet.safe.global/",
"transactionOverrides": {
"maxFeePerGas": 150000000000,
"maxPriorityFeePerGas": 5000000000
}
},
"moonbeam": {
"chainId": 1284,
"domainId": 1284,
"name": "moonbeam",
"protocol": "ethereum",
"displayName": "Moonbeam",
"nativeToken": {
"decimals": 18,
"name": "GLMR",
"symbol": "GLMR"
},
"rpcUrls": [
{
"http": "https://rpc.api.moonbeam.network"
}
],
"blockExplorers": [
{
"name": "MoonScan",
"url": "https://moonscan.io",
"apiUrl": "https://api-moonbeam.moonscan.io/api",
"family": "etherscan"
}
],
"blocks": {
"confirmations": 2,
"reorgPeriod": 2,
"estimateBlockTime": 12
},
"gnosisSafeTransactionServiceUrl": "https://transaction.multisig.moonbeam.network"
},
"gnosis": {
"chainId": 100,
"domainId": 100,
"name": "gnosis",
"protocol": "ethereum",
"displayName": "Gnosis",
"nativeToken": {
"name": "xDai",
"symbol": "xDai",
"decimals": 18
},
"rpcUrls": [
{
"http": "https://rpc.gnosischain.com",
"pagination": {
"maxBlockRange": 10000,
"minBlockNumber": 25997478
}
}
],
"blockExplorers": [
{
"name": "GnosisScan",
"url": "https://gnosisscan.io",
"apiUrl": "https://api.gnosisscan.io/api",
"family": "etherscan"
}
],
"blocks": {
"confirmations": 1,
"reorgPeriod": 14,
"estimateBlockTime": 5
},
"gasCurrencyCoinGeckoId": "xdai",
"gnosisSafeTransactionServiceUrl": "https://safe-transaction-gnosis-chain.safe.global/"
},
"solanamainnet": {
"chainId": 1399811149,
"name": "solanamainnet",
"rpcUrls": [
{
"http": "https://api.mainnet-beta.solana.com"
}
]
},
"nautilus": {
"chainId": 22222,
"name": "nautilus",
"rpcUrls": [
{
"http": "https://api.nautilus.nautchain.xyz"
}
]
}
}

@ -1,20 +0,0 @@
[
{
"domain": 56,
"gasOracle": {
"type": "remoteGasData",
"tokenExchangeRate": "100000000000000000000",
"gasPrice": "3000000000",
"tokenDecimals": 18
}
},
{
"domain": 22222,
"gasOracle": {
"type": "remoteGasData",
"tokenExchangeRate": "4700000000000000",
"gasPrice": "1000000000",
"tokenDecimals": 18
}
}
]

@ -1,30 +0,0 @@
{
"solanamainnet": {},
"bsc": {
"foreignDeployment": "0xB97d3bF2fC296c2cAC4056bBC8A783ff39408e20"
},
"avalanche": {
"foreignDeployment": "0x2A925CD8a5d919c5c6599633090c37fe38A561b6"
},
"polygon": {
"foreignDeployment": "0x6c0aC8cEA75232aa7BeD8cbe9C4f820E7a77a9C3"
},
"celo": {
"foreignDeployment": "0x4151773Db70C0b2D4c43Ea44A5FB5803ff1d3e0B"
},
"arbitrum": {
"foreignDeployment": "0x96271cA0ab9eeFB3Ca481749c0Ca4c705fD4F523"
},
"optimism": {
"foreignDeployment": "0xA6f0A37DFDe9C2c8F46F010989C47d9edB3a9FA8"
},
"ethereum": {
"foreignDeployment": "0x9311cEE522A7C122B843b66cC31C6a63e2F92641"
},
"moonbeam": {
"foreignDeployment": "0xAe067C08703508230357025B38c35Cd12793628c"
},
"gnosis": {
"foreignDeployment": "0x26f32245fCF5Ad53159E875d5Cae62aEcf19c2d4"
}
}

@ -1,42 +0,0 @@
{
"moonbeam": {
"hex": "0x000000000000000000000000ae067c08703508230357025b38c35cd12793628c",
"base58": "1111111111113RcuHPfDctyAnFWHvj8tS1q8UHPh"
},
"bsc": {
"hex": "0x000000000000000000000000b97d3bf2fc296c2cac4056bbc8a783ff39408e20",
"base58": "1111111111113atAoP8gQ2GYeue77ETUPAf8w9zw"
},
"optimism": {
"hex": "0x000000000000000000000000a6f0a37dfde9c2c8f46f010989c47d9edb3a9fa8",
"base58": "1111111111113KtqevvpYv7NCiadmp6tRRfivB8K"
},
"avalanche": {
"hex": "0x0000000000000000000000002a925cd8a5d919c5c6599633090c37fe38a561b6",
"base58": "111111111111bQB6b7XVDHSyvi7XmLrQMT8C3xH"
},
"ethereum": {
"hex": "0x0000000000000000000000009311cee522a7c122b843b66cc31c6a63e2f92641",
"base58": "11111111111133qb6DzNiJ7whNaYGud2WqqtjxFS"
},
"solanamainnet": {
"hex": "0x3797d0096b18b5b645c346a66d7f18c6c5738782c6bce24da57a3462bdef82b1",
"base58": "4k1gruSdH1r57V9QQK4aunzfMYzLFfF83jdYkkEwyem6"
},
"celo": {
"hex": "0x0000000000000000000000004151773db70c0b2d4c43ea44a5fb5803ff1d3e0b",
"base58": "111111111111unDVQcjdeHntE83qvf1vsKCZ4av"
},
"polygon": {
"hex": "0x0000000000000000000000006c0ac8cea75232aa7bed8cbe9c4f820e7a77a9c3",
"base58": "1111111111112WJXE3PCAsCXYZxU9Kh51sSZEa5G"
},
"arbitrum": {
"hex": "0x00000000000000000000000096271ca0ab9eefb3ca481749c0ca4c705fd4f523",
"base58": "11111111111136L61X7cdT9tPZ4GKBtzJtrjFAd8"
},
"gnosis": {
"hex": "0x00000000000000000000000026f32245fcf5ad53159e875d5cae62aecf19c2d4",
"base58": "111111111111YURfyMRiiTWy8X6pYHAqmYPmBpf"
}
}

@ -1,32 +0,0 @@
{
"solanamainnet": {
"interchainSecurityModule": "BYTsxBuKVbwgsZFswzB91nrxveQySghwXzaKqn8exNnC"
},
"gnosis": {
"foreignDeployment": "0x99ca8c74cE7Cfa9d72A51fbb05F9821f5f826b3a"
},
"bsc": {
"foreignDeployment": "0xe5554478F167936dB253f79f57c41770bfa00Bae"
},
"avalanche": {
"foreignDeployment": "0xe1De9910fe71cC216490AC7FCF019e13a34481D7"
},
"polygon": {
"foreignDeployment": "0xAb65C41a1BC580a52f0b166879122EFdce0cB868"
},
"celo": {
"foreignDeployment": "0xfE29f6a4468536029Fc9c97d3a9669b9fe38E114"
},
"arbitrum": {
"foreignDeployment": "0x414B67F62b143d6db6E9b633168Dd6fd4DA20642"
},
"optimism": {
"foreignDeployment": "0xB4caf2CA864B413DAA502fA18A8D48cD0740fC52"
},
"ethereum": {
"foreignDeployment": "0xed31c20c5517EaC05decD5F6dCd01Fe6d16fD09D"
},
"moonbeam": {
"foreignDeployment": "0x3eB9eE2CFC8DCB6F58B5869D33336CFcBf1dC354"
}
}

@ -1,42 +0,0 @@
{
"solanamainnet": {
"hex": "0x29dacc0e7124ea39b1fd43ab0fd30e038cf405c0229890229d0086d0b6516f9c",
"base58": "3pPDp16iVTJFge2sm85Q61hW61UN5xNqeG24gqFhzLFV"
},
"avalanche": {
"hex": "0x000000000000000000000000e1de9910fe71cc216490ac7fcf019e13a34481d7",
"base58": "11111111111149We9K5tM8ijcyNy9zDMG9RyDBCJ"
},
"arbitrum": {
"hex": "0x000000000000000000000000414b67f62b143d6db6e9b633168dd6fd4da20642",
"base58": "111111111111um79Yc6Evs5e1m2fdD2x7T1cpXb"
},
"moonbeam": {
"hex": "0x0000000000000000000000003eb9ee2cfc8dcb6f58b5869d33336cfcbf1dc354",
"base58": "111111111111sgjzaeuHfqhExkdPQ1gJdhcSr4j"
},
"optimism": {
"hex": "0x000000000000000000000000b4caf2ca864b413daa502fa18a8d48cd0740fc52",
"base58": "1111111111113X64nhkfMi9X5MbxKsiDTeeTmjsw"
},
"ethereum": {
"hex": "0x000000000000000000000000ed31c20c5517eac05decd5f6dcd01fe6d16fd09d",
"base58": "1111111111114JfPmRiKEsR445qonVzCpsAvXCR2"
},
"gnosis": {
"hex": "0x00000000000000000000000099ca8c74ce7cfa9d72a51fbb05f9821f5f826b3a",
"base58": "11111111111139Gc7eyQjpZrmWkkYQRyA2Grcvmf"
},
"bsc": {
"hex": "0x000000000000000000000000e5554478f167936db253f79f57c41770bfa00bae",
"base58": "1111111111114CJxuV4VoAh5NsJy9qCGHqryoTCy"
},
"polygon": {
"hex": "0x000000000000000000000000ab65c41a1bc580a52f0b166879122efdce0cb868",
"base58": "1111111111113PVkHAU9H7moDSoQvhC3Y2wgmovX"
},
"celo": {
"hex": "0x000000000000000000000000fe29f6a4468536029fc9c97d3a9669b9fe38e114",
"base58": "1111111111114YNh3uhCWh2NjyPttobeNRyuDHYo"
}
}

@ -1,106 +0,0 @@
{
"celo": {
"type": 3,
"threshold": 4,
"validators": [
"0x1f20274b1210046769d48174c2f0e7c25ca7d5c5",
"0x3bc014bafa43f93d534aed34f750997cdffcf007",
"0xd79d506d741fa735938f7b7847a926e34a6fe6b0",
"0xe4a258bc61e65914c2a477b2a8a433ab4ebdf44b",
"0x6aea63b0be4679c1385c26a92a3ff8aa6a8379f2",
"0xc0085e1a49bcc69e534272adb82c74c0e007e1ca"
]
},
"ethereum": {
"type": 3,
"threshold": 4,
"validators": [
"0x4c327ccb881a7542be77500b2833dc84c839e7b7",
"0x84cb373148ef9112b277e68acf676fefa9a9a9a0",
"0x0d860c2b28bec3af4fd3a5997283e460ff6f2789",
"0xd4c1211f0eefb97a846c4e6d6589832e52fc03db",
"0x600c90404d5c9df885404d2cc5350c9b314ea3a2",
"0x892DC66F5B2f8C438E03f6323394e34A9C24F2D6"
]
},
"avalanche": {
"type": 3,
"threshold": 4,
"validators": [
"0xa7aa52623fe3d78c343008c95894be669e218b8d",
"0xb6004433fb04f643e2d48ae765c0e7f890f0bc0c",
"0xa07e213e0985b21a6128e6c22ab5fb73948b0cc2",
"0x73853ed9a5f6f2e4c521970a94d43469e3cdaea6",
"0xbd2e136cda02ba627ca882e49b184cbe976081c8",
"0x1418126f944a44dad9edbab32294a8c890e7a9e3"
]
},
"polygon": {
"type": 3,
"threshold": 4,
"validators": [
"0x59a001c3451e7f9f3b4759ea215382c1e9aa5fc1",
"0x009fb042d28944017177920c1d40da02bfebf474",
"0xba4b13e23705a5919c1901150d9697e8ffb3ea71",
"0x2faa4071b718972f9b4beec1d8cbaa4eb6cca6c6",
"0x5ae9b0f833dfe09ef455562a1f603f1634504dd6",
"0x6a163d312f7352a95c9b81dca15078d5bf77a442"
]
},
"bsc": {
"type": 3,
"threshold": 4,
"validators": [
"0xcc84b1eb711e5076b2755cf4ad1d2b42c458a45e",
"0xefe34eae2bca1846b895d2d0762ec21796aa196a",
"0x662674e80e189b0861d6835c287693f50ee0c2ff",
"0x8a0f59075af466841808c529624807656309c9da",
"0xdd2ff046ccd748a456b4757a73d47f165469669f",
"0x034c4924c30ec4aa1b7f3ad58548988f0971e1bf"
]
},
"arbitrum": {
"type": 3,
"threshold": 4,
"validators": [
"0xbcb815f38d481a5eba4d7ac4c9e74d9d0fc2a7e7",
"0xd839424e2e5ace0a81152298dc2b1e3bb3c7fb20",
"0xb8085c954b75b7088bcce69e61d12fcef797cd8d",
"0x9856dcb10fd6e5407fa74b5ab1d3b96cc193e9b7",
"0x505dff4e0827aa5065f5e001db888e0569d46490",
"0x25c6779d4610f940bf2488732e10bcffb9d36f81"
]
},
"optimism": {
"type": 3,
"threshold": 4,
"validators": [
"0x9f2296d5cfc6b5176adc7716c7596898ded13d35",
"0x9c10bbe8efa03a8f49dfdb5c549258e3a8dca097",
"0x62144d4a52a0a0335ea5bb84392ef9912461d9dd",
"0xaff4718d5d637466ad07441ee3b7c4af8e328dbd",
"0xc64d1efeab8ae222bc889fe669f75d21b23005d9",
"0xfa174eb2b4921bb652bc1ada3e8b00e7e280bf3c"
]
},
"moonbeam": {
"type": 3,
"threshold": 3,
"validators": [
"0x237243d32d10e3bdbbf8dbcccc98ad44c1c172ea",
"0x9509c8cf0a06955f27342262af501b74874e98fb",
"0xb7113c999e4d587b162dd1a28c73f3f51c6bdcdc",
"0x26725501597d47352a23cd26f122709f69ad53bc"
]
},
"gnosis": {
"type": 3,
"threshold": 3,
"validators": [
"0xd0529ec8df08d0d63c0f023786bfa81e4bb51fd6",
"0x8a72ff8571c53c62c7ca02e8c97a443cd5674383",
"0x4075c2f6bd6d9562067cfe551d49c2bcafa7d692",
"0xa18580444eaeb1c5957e7b66a6bf84b6519f904d"
]
}
}

@ -1,18 +0,0 @@
{
"bsc": {
"type": 3,
"threshold": 1,
"validators": [
"0x0000000000000000000000000000000000000001"
]
},
"nautilus": {
"type": 3,
"threshold": 2,
"validators": [
"0x9c920af9467595a23cb3433adefc3854d498a437",
"0x87611503e37ce041527c11c24263e8760fccf81f",
"0x573443248cf9929af0001b88f62131f2de29fe9f"
]
}
}

@ -1,3 +0,0 @@
{
"program_id": "9k74DkJvS2x9QhG4XfnKsLkqaCDyVfaj8s6FyJyhAeEP"
}

@ -1,65 +0,0 @@
{
"celo": {
"type": 3,
"threshold": 1,
"validators": [
"0xe7a82e210f512f8e9900d6bc2acbf7981c63e66e"
]
},
"ethereum": {
"type": 3,
"threshold": 1,
"validators": [
"0xaea1adb1c687b061e5b60b9da84cb69e7b5fab44"
]
},
"avalanche": {
"type": 3,
"threshold": 1,
"validators": [
"0x706976391e23dea28152e0207936bd942aba01ce"
]
},
"polygon": {
"type": 3,
"threshold": 1,
"validators": [
"0xef372f6ff7775989b3ac884506ee31c79638c989"
]
},
"bsc": {
"type": 3,
"threshold": 1,
"validators": [
"0x0823081031a4a6f97c6083775c191d17ca96d0ab"
]
},
"arbitrum": {
"type": 3,
"threshold": 1,
"validators": [
"0x1a95b35fb809d57faf1117c1cc29a6c5df289df1"
]
},
"optimism": {
"type": 3,
"threshold": 1,
"validators": [
"0x60e938bf280bbc21bacfd8bf435459d9003a8f98"
]
},
"moonbeam": {
"type": 3,
"threshold": 1,
"validators": [
"0x0df7140811e309dc69638352545151ebb9d5e0fd"
]
},
"gnosis": {
"type": 3,
"threshold": 1,
"validators": [
"0x15f48e78092a4f79febface509cfd76467c6cdbb"
]
}
}

@ -1,3 +0,0 @@
{
"program_id": "BYTsxBuKVbwgsZFswzB91nrxveQySghwXzaKqn8exNnC"
}

@ -1,8 +0,0 @@
{
"mailbox": "Ge9atjAc3Ltu91VTbNpJDCjZ9CFxFyck4h3YBcTF9XPq",
"validator_announce": "C88Lk5GR6cPxYoJxPbNDDEwsx5Kxn1wZEomvQ2So333g",
"multisig_ism_message_id": "6pHP4EeX2Xek24Be7PPTWCqcpmNEPENW1m9RnZSFSmA1",
"igp_program_id": "HksFWQM1EXJJ5mxo2uZoMfmksXHaNhCunh71NqcQQHZ8",
"overhead_igp_account": "GTj6WzNxLNFydq5zJrV9p13fyqotRoo1MQykNCWuVpbS",
"igp_account": "FCNfmLSZLo5x7oNYmkYU8WdPUu7pj636P9CaMxkmaCp7"
}

@ -1,10 +0,0 @@
{
"solanamainnet": {
"hex": "0xc5ba229fa2822fe65ac2bd0a93d8371d75292c3415dd381923c1088a3308528b",
"base58": "EJqwFjvVJSAxH8Ur2PYuMfdvoJeutjmH6GkoEFQ4MdSa"
},
"nautilus": {
"hex": "0x0000000000000000000000004501bbe6e731a4bc5c60c03a77435b2f6d5e9fe7",
"base58": "111111111111xm5qkrK7gZ8Cmjr4ggPLRxy2T8a"
}
}

@ -1,16 +0,0 @@
{
"solanamainnet": {
"type": "collateral",
"decimals": 9,
"remoteDecimals": 9,
"token": "wzbcJyhGhQDLTV1S99apZiiBdE4jmYfbw99saMMdP59",
"splTokenProgram": "token",
"interchainSecurityModule": "9k74DkJvS2x9QhG4XfnKsLkqaCDyVfaj8s6FyJyhAeEP",
"owner": "EzppBFV2taxWw8kEjxNYvby6q7W1biJEqwP3iC7YgRe3"
},
"nautilus": {
"type": "native",
"decimals": 18,
"foreignDeployment": "0x4501bBE6e731A4bC5c60C03A77435b2f6d5e9Fe7"
}
}

File diff suppressed because it is too large Load Diff

@ -1,4 +1,13 @@
{ {
"alephzeroevm": {
"threshold": 2,
"validators": [
"0xcae8fab142adc4e434bb7409e40dd932cc3851aa",
"0xCF0211faFBb91FD9D06D7E306B30032DC3A1934f",
"0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36"
],
"type": "messageIdMultisigIsm"
},
"ancient8": { "ancient8": {
"threshold": 2, "threshold": 2,
"validators": [ "validators": [
@ -6,7 +15,7 @@
"0xa5a56e97fb46f0ac3a3d261e404acb998d9a6969", "0xa5a56e97fb46f0ac3a3d261e404acb998d9a6969",
"0x95c7bf235837cb5a609fe6c95870410b9f68bcff" "0x95c7bf235837cb5a609fe6c95870410b9f68bcff"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"arbitrum": { "arbitrum": {
"threshold": 3, "threshold": 3,
@ -17,7 +26,7 @@
"0x38c7a4ca1273ead2e867d096adbcdd0e2acb21d8", "0x38c7a4ca1273ead2e867d096adbcdd0e2acb21d8",
"0xb3ac35d3988bca8c2ffd195b1c6bee18536b317b" "0xb3ac35d3988bca8c2ffd195b1c6bee18536b317b"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"astar": { "astar": {
"threshold": 2, "threshold": 2,
@ -26,7 +35,7 @@
"0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f", "0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f",
"0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36" "0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"astarzkevm": { "astarzkevm": {
"threshold": 2, "threshold": 2,
@ -35,7 +44,7 @@
"0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f", "0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f",
"0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36" "0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"avalanche": { "avalanche": {
"threshold": 2, "threshold": 2,
@ -44,7 +53,7 @@
"0x402e0f8c6e4210d408b6ac00d197d4a099fcd25a", "0x402e0f8c6e4210d408b6ac00d197d4a099fcd25a",
"0x38c7a4ca1273ead2e867d096adbcdd0e2acb21d8" "0x38c7a4ca1273ead2e867d096adbcdd0e2acb21d8"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"base": { "base": {
"threshold": 3, "threshold": 3,
@ -55,7 +64,7 @@
"0xcff391b4e516452d424db66beb9052b041a9ed79", "0xcff391b4e516452d424db66beb9052b041a9ed79",
"0x5450447aee7b544c462c9352bef7cad049b0c2dc" "0x5450447aee7b544c462c9352bef7cad049b0c2dc"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"bitlayer": { "bitlayer": {
"threshold": 2, "threshold": 2,
@ -64,7 +73,7 @@
"0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f", "0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f",
"0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36" "0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"blast": { "blast": {
"threshold": 2, "threshold": 2,
@ -73,7 +82,7 @@
"0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36", "0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36",
"0xae53467a5c2a9d9420c188d10fef5e1d9b9a5b80" "0xae53467a5c2a9d9420c188d10fef5e1d9b9a5b80"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"bob": { "bob": {
"threshold": 2, "threshold": 2,
@ -82,7 +91,7 @@
"0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f", "0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f",
"0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36" "0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"bsc": { "bsc": {
"threshold": 3, "threshold": 3,
@ -92,7 +101,7 @@
"0x38c7a4ca1273ead2e867d096adbcdd0e2acb21d8", "0x38c7a4ca1273ead2e867d096adbcdd0e2acb21d8",
"0x5450447aee7b544c462c9352bef7cad049b0c2dc" "0x5450447aee7b544c462c9352bef7cad049b0c2dc"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"celo": { "celo": {
"threshold": 3, "threshold": 3,
@ -103,7 +112,7 @@
"0xb3ac35d3988bca8c2ffd195b1c6bee18536b317b", "0xb3ac35d3988bca8c2ffd195b1c6bee18536b317b",
"0x5450447aee7b544c462c9352bef7cad049b0c2dc" "0x5450447aee7b544c462c9352bef7cad049b0c2dc"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"cheesechain": { "cheesechain": {
"threshold": 2, "threshold": 2,
@ -111,7 +120,16 @@
"0x478fb53c6860ae8fc35235ba0d38d49b13128226", "0x478fb53c6860ae8fc35235ba0d38d49b13128226",
"0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f" "0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f"
], ],
"type": 3 "type": "messageIdMultisigIsm"
},
"chiliz": {
"threshold": 2,
"validators": [
"0x82d024f453b1a3f3f6606226f06b038da27596f3",
"0xCF0211faFBb91FD9D06D7E306B30032DC3A1934f",
"0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36"
],
"type": "messageIdMultisigIsm"
}, },
"coredao": { "coredao": {
"threshold": 2, "threshold": 2,
@ -120,7 +138,7 @@
"0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f", "0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f",
"0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36" "0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"cyber": { "cyber": {
"threshold": 2, "threshold": 2,
@ -129,7 +147,7 @@
"0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f", "0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f",
"0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36" "0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"degenchain": { "degenchain": {
"threshold": 2, "threshold": 2,
@ -138,7 +156,7 @@
"0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f", "0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f",
"0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36" "0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"dogechain": { "dogechain": {
"threshold": 2, "threshold": 2,
@ -147,7 +165,7 @@
"0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f", "0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f",
"0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36" "0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"endurance": { "endurance": {
"threshold": 2, "threshold": 2,
@ -156,7 +174,7 @@
"0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f", "0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f",
"0x7419021c0de2772b763e554480158a82a291c1f2" "0x7419021c0de2772b763e554480158a82a291c1f2"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"ethereum": { "ethereum": {
"threshold": 4, "threshold": 4,
@ -169,7 +187,7 @@
"0xb683b742b378632a5f73a2a5a45801b3489bba44", "0xb683b742b378632a5f73a2a5a45801b3489bba44",
"0xbf1023eff3dba21263bf2db2add67a0d6bcda2de" "0xbf1023eff3dba21263bf2db2add67a0d6bcda2de"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"everclear": { "everclear": {
"threshold": 2, "threshold": 2,
@ -178,7 +196,7 @@
"0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f", "0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f",
"0xD79DFbF56ee2268f061cc613027a44A880f61Ba2" "0xD79DFbF56ee2268f061cc613027a44A880f61Ba2"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"flare": { "flare": {
"threshold": 2, "threshold": 2,
@ -187,7 +205,16 @@
"0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f", "0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f",
"0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36" "0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36"
], ],
"type": 3 "type": "messageIdMultisigIsm"
},
"flow": {
"threshold": 2,
"validators": [
"0x3aee1090318e9c54d1d23194dcd0f2bee00ddc97",
"0xCF0211faFBb91FD9D06D7E306B30032DC3A1934f",
"0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36"
],
"type": "messageIdMultisigIsm"
}, },
"fraxtal": { "fraxtal": {
"threshold": 2, "threshold": 2,
@ -196,7 +223,7 @@
"0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f", "0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f",
"0x25b3a88f7cfd3c9f7d7e32b295673a16a6ddbd91" "0x25b3a88f7cfd3c9f7d7e32b295673a16a6ddbd91"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"fusemainnet": { "fusemainnet": {
"threshold": 2, "threshold": 2,
@ -205,7 +232,7 @@
"0x6760226b34213d262D41D5291Ed57E81a68b4E0b", "0x6760226b34213d262D41D5291Ed57E81a68b4E0b",
"0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f" "0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"gnosis": { "gnosis": {
"threshold": 3, "threshold": 3,
@ -215,7 +242,16 @@
"0x38c7a4ca1273ead2e867d096adbcdd0e2acb21d8", "0x38c7a4ca1273ead2e867d096adbcdd0e2acb21d8",
"0x5450447aee7b544c462c9352bef7cad049b0c2dc" "0x5450447aee7b544c462c9352bef7cad049b0c2dc"
], ],
"type": 3 "type": "messageIdMultisigIsm"
},
"immutablezkevm": {
"threshold": 2,
"validators": [
"0xa787c2952a4d22f776ee6e87e828e6f75de24330",
"0xCF0211faFBb91FD9D06D7E306B30032DC3A1934f",
"0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36"
],
"type": "messageIdMultisigIsm"
}, },
"inevm": { "inevm": {
"threshold": 2, "threshold": 2,
@ -224,7 +260,7 @@
"0x6B1d09A97b813D53e9D4b7523DA36604C0B52242", "0x6B1d09A97b813D53e9D4b7523DA36604C0B52242",
"0x9ab11f38a609940153850df611c9a2175dcffe0f" "0x9ab11f38a609940153850df611c9a2175dcffe0f"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"injective": { "injective": {
"threshold": 2, "threshold": 2,
@ -233,7 +269,7 @@
"0x6B1d09A97b813D53e9D4b7523DA36604C0B52242", "0x6B1d09A97b813D53e9D4b7523DA36604C0B52242",
"0x9e551b6694bbd295d7d6e6a2540c7d41ce70a3b9" "0x9e551b6694bbd295d7d6e6a2540c7d41ce70a3b9"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"kroma": { "kroma": {
"threshold": 2, "threshold": 2,
@ -242,7 +278,7 @@
"0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f", "0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f",
"0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36" "0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"linea": { "linea": {
"threshold": 2, "threshold": 2,
@ -251,7 +287,7 @@
"0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f", "0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f",
"0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36" "0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"lisk": { "lisk": {
"threshold": 2, "threshold": 2,
@ -260,7 +296,7 @@
"0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f", "0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f",
"0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36" "0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"lukso": { "lukso": {
"threshold": 2, "threshold": 2,
@ -269,10 +305,19 @@
"0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f", "0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f",
"0x101cE77261245140A0871f9407d6233C8230Ec47" "0x101cE77261245140A0871f9407d6233C8230Ec47"
], ],
"type": 3 "type": "messageIdMultisigIsm"
},
"lumia": {
"threshold": 2,
"validators": [
"0x9e283254ed2cd2c80f007348c2822fc8e5c2fa5f",
"0xCF0211faFBb91FD9D06D7E306B30032DC3A1934f",
"0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36"
],
"type": "messageIdMultisigIsm"
}, },
"mantapacific": { "mantapacific": {
"threshold": 5, "threshold": 4,
"validators": [ "validators": [
"0x8e668c97ad76d0e28375275c41ece4972ab8a5bc", "0x8e668c97ad76d0e28375275c41ece4972ab8a5bc",
"0x521a3e6bf8d24809fde1c1fd3494a859a16f132c", "0x521a3e6bf8d24809fde1c1fd3494a859a16f132c",
@ -282,7 +327,7 @@
"0xcc9a0b6de7fe314bd99223687d784730a75bb957", "0xcc9a0b6de7fe314bd99223687d784730a75bb957",
"0x42b6de2edbaa62c2ea2309ad85d20b3e37d38acf" "0x42b6de2edbaa62c2ea2309ad85d20b3e37d38acf"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"mantle": { "mantle": {
"threshold": 2, "threshold": 2,
@ -291,7 +336,7 @@
"0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f", "0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f",
"0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36" "0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"merlin": { "merlin": {
"threshold": 2, "threshold": 2,
@ -300,7 +345,16 @@
"0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f", "0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f",
"0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36" "0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36"
], ],
"type": 3 "type": "messageIdMultisigIsm"
},
"metall2": {
"threshold": 2,
"validators": [
"0x1b000e1e1f0a032ed382c6d69a2d58f6fe773c09",
"0xCF0211faFBb91FD9D06D7E306B30032DC3A1934f",
"0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36"
],
"type": "messageIdMultisigIsm"
}, },
"metis": { "metis": {
"threshold": 2, "threshold": 2,
@ -309,7 +363,7 @@
"0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f", "0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f",
"0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36" "0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"mint": { "mint": {
"threshold": 2, "threshold": 2,
@ -318,7 +372,7 @@
"0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f", "0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f",
"0x0230505530b80186f8cdccfaf9993eb97aebe98a" "0x0230505530b80186f8cdccfaf9993eb97aebe98a"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"mode": { "mode": {
"threshold": 3, "threshold": 3,
@ -328,7 +382,7 @@
"0x7e29608c6e5792bbf9128599ca309be0728af7b4", "0x7e29608c6e5792bbf9128599ca309be0728af7b4",
"0x101cE77261245140A0871f9407d6233C8230Ec47" "0x101cE77261245140A0871f9407d6233C8230Ec47"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"molten": { "molten": {
"threshold": 2, "threshold": 2,
@ -337,7 +391,7 @@
"0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f", "0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f",
"0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36" "0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"moonbeam": { "moonbeam": {
"threshold": 3, "threshold": 3,
@ -347,7 +401,7 @@
"0x38c7a4ca1273ead2e867d096adbcdd0e2acb21d8", "0x38c7a4ca1273ead2e867d096adbcdd0e2acb21d8",
"0xb3ac35d3988bca8c2ffd195b1c6bee18536b317b" "0xb3ac35d3988bca8c2ffd195b1c6bee18536b317b"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"neutron": { "neutron": {
"threshold": 4, "threshold": 4,
@ -360,7 +414,7 @@
"0x54b2cca5091b098a1a993dec03c4d1ee9af65999", "0x54b2cca5091b098a1a993dec03c4d1ee9af65999",
"0x42b6de2edbaa62c2ea2309ad85d20b3e37d38acf" "0x42b6de2edbaa62c2ea2309ad85d20b3e37d38acf"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"oortmainnet": { "oortmainnet": {
"threshold": 2, "threshold": 2,
@ -369,7 +423,7 @@
"0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36", "0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36",
"0x032dE4f94676bF9314331e7D83E8Db4aC74c9E21" "0x032dE4f94676bF9314331e7D83E8Db4aC74c9E21"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"optimism": { "optimism": {
"threshold": 3, "threshold": 3,
@ -380,14 +434,14 @@
"0xb3ac35d3988bca8c2ffd195b1c6bee18536b317b", "0xb3ac35d3988bca8c2ffd195b1c6bee18536b317b",
"0x5450447aee7b544c462c9352bef7cad049b0c2dc" "0x5450447aee7b544c462c9352bef7cad049b0c2dc"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"osmosis": { "osmosis": {
"threshold": 1, "threshold": 1,
"validators": [ "validators": [
"0xea483af11c19fa41b16c31d1534c2a486a92bcac" "0xea483af11c19fa41b16c31d1534c2a486a92bcac"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"polygon": { "polygon": {
"threshold": 3, "threshold": 3,
@ -397,7 +451,7 @@
"0x38c7a4ca1273ead2e867d096adbcdd0e2acb21d8", "0x38c7a4ca1273ead2e867d096adbcdd0e2acb21d8",
"0x5450447aee7b544c462c9352bef7cad049b0c2dc" "0x5450447aee7b544c462c9352bef7cad049b0c2dc"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"polygonzkevm": { "polygonzkevm": {
"threshold": 2, "threshold": 2,
@ -406,7 +460,16 @@
"0x865818fe1db986036d5fd0466dcd462562436d1a", "0x865818fe1db986036d5fd0466dcd462562436d1a",
"0x38c7a4ca1273ead2e867d096adbcdd0e2acb21d8" "0x38c7a4ca1273ead2e867d096adbcdd0e2acb21d8"
], ],
"type": 3 "type": "messageIdMultisigIsm"
},
"polynomial": {
"threshold": 2,
"validators": [
"0xa63ad0891e921ad5947d57e05831fabb9816eca7",
"0xCF0211faFBb91FD9D06D7E306B30032DC3A1934f",
"0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36"
],
"type": "messageIdMultisigIsm"
}, },
"proofofplay": { "proofofplay": {
"threshold": 2, "threshold": 2,
@ -415,7 +478,16 @@
"0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f", "0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f",
"0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36" "0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36"
], ],
"type": 3 "type": "messageIdMultisigIsm"
},
"rari": {
"threshold": 2,
"validators": [
"0x989d6862e09de21337078efbd86843a3eb1133e3",
"0xCF0211faFBb91FD9D06D7E306B30032DC3A1934f",
"0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36"
],
"type": "messageIdMultisigIsm"
}, },
"real": { "real": {
"threshold": 2, "threshold": 2,
@ -424,7 +496,7 @@
"0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f", "0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f",
"0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36" "0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"redstone": { "redstone": {
"threshold": 2, "threshold": 2,
@ -433,7 +505,16 @@
"0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f", "0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f",
"0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36" "0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36"
], ],
"type": 3 "type": "messageIdMultisigIsm"
},
"rootstock": {
"threshold": 2,
"validators": [
"0xcb8e3a72cf427feff27416d0e2ec375a052eaaee",
"0xCF0211faFBb91FD9D06D7E306B30032DC3A1934f",
"0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36"
],
"type": "messageIdMultisigIsm"
}, },
"sanko": { "sanko": {
"threshold": 2, "threshold": 2,
@ -442,7 +523,7 @@
"0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f", "0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f",
"0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36" "0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"scroll": { "scroll": {
"threshold": 3, "threshold": 3,
@ -452,7 +533,7 @@
"0x38c7a4ca1273ead2e867d096adbcdd0e2acb21d8", "0x38c7a4ca1273ead2e867d096adbcdd0e2acb21d8",
"0xbac4ac39f1d8b5ef15f26fdb1294a7c9aba3f948" "0xbac4ac39f1d8b5ef15f26fdb1294a7c9aba3f948"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"sei": { "sei": {
"threshold": 3, "threshold": 3,
@ -462,7 +543,7 @@
"0x101cE77261245140A0871f9407d6233C8230Ec47", "0x101cE77261245140A0871f9407d6233C8230Ec47",
"0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36" "0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"shibarium": { "shibarium": {
"threshold": 2, "threshold": 2,
@ -471,7 +552,7 @@
"0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f", "0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f",
"0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36" "0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"solanamainnet": { "solanamainnet": {
"threshold": 3, "threshold": 3,
@ -482,7 +563,32 @@
"0x38c7a4ca1273ead2e867d096adbcdd0e2acb21d8", "0x38c7a4ca1273ead2e867d096adbcdd0e2acb21d8",
"0xcb6bcbd0de155072a7ff486d9d7286b0f71dcc2d" "0xcb6bcbd0de155072a7ff486d9d7286b0f71dcc2d"
], ],
"type": 3 "type": "messageIdMultisigIsm"
},
"stride": {
"threshold": 4,
"validators": [
"0x38c7a4ca1273ead2e867d096adbcdd0e2acb21d8",
"0x88f0E5528131b10e3463C4c68108217Dd33462ac",
"0xa3eaa1216827ad63dd9db43f6168258a89177990",
"0x3f869C36110F00D10dC74cca3ac1FB133cf019ad",
"0x502dC6135d16E74056f609FBAF76846814C197D3",
"0xc36979780c1aD43275182600a61Ce41f1C390FbE",
"0x87460dcEd16a75AECdBffD4189111d30B099f5b0",
"0xf54982134e52Eb7253236943FBffE0886C5bde0C",
"0x5937b7cE1029C3Ec4bD8e1AaCc0C0f9422654D7d",
"0x3a446ed2923c08445af06e53f0acb558c0e0413c"
],
"type": "messageIdMultisigIsm"
},
"superposition": {
"threshold": 2,
"validators": [
"0x5978d0e6afa9270ddb87cff43a8fa7a763a5dfc4",
"0xCF0211faFBb91FD9D06D7E306B30032DC3A1934f",
"0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36"
],
"type": "messageIdMultisigIsm"
}, },
"taiko": { "taiko": {
"threshold": 3, "threshold": 3,
@ -492,7 +598,7 @@
"0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36", "0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36",
"0x2F007c82672F2Bb97227D4e3F80Ac481bfB40A2a" "0x2F007c82672F2Bb97227D4e3F80Ac481bfB40A2a"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"tangle": { "tangle": {
"threshold": 2, "threshold": 2,
@ -501,7 +607,7 @@
"0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f", "0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f",
"0xe271ef9a6e312540f099a378865432fa73f26689" "0xe271ef9a6e312540f099a378865432fa73f26689"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"viction": { "viction": {
"threshold": 2, "threshold": 2,
@ -510,7 +616,7 @@
"0xa3f93fe365bf99f431d8fde740b140615e24f99b", "0xa3f93fe365bf99f431d8fde740b140615e24f99b",
"0x1f87c368f8e05a85ef9126d984a980a20930cb9c" "0x1f87c368f8e05a85ef9126d984a980a20930cb9c"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"worldchain": { "worldchain": {
"threshold": 2, "threshold": 2,
@ -519,7 +625,7 @@
"0x11e2a683e83617f186614071e422b857256a9aae", "0x11e2a683e83617f186614071e422b857256a9aae",
"0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f" "0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"xai": { "xai": {
"threshold": 2, "threshold": 2,
@ -528,7 +634,7 @@
"0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f", "0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f",
"0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36" "0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"xlayer": { "xlayer": {
"threshold": 2, "threshold": 2,
@ -537,7 +643,7 @@
"0xfed056cC0967F5BC9C6350F6C42eE97d3983394d", "0xfed056cC0967F5BC9C6350F6C42eE97d3983394d",
"0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f" "0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"zetachain": { "zetachain": {
"threshold": 3, "threshold": 3,
@ -547,7 +653,7 @@
"0x101cE77261245140A0871f9407d6233C8230Ec47", "0x101cE77261245140A0871f9407d6233C8230Ec47",
"0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36" "0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"zircuit": { "zircuit": {
"threshold": 3, "threshold": 3,
@ -557,7 +663,7 @@
"0x0180444c9342BD672867Df1432eb3dA354413a6E", "0x0180444c9342BD672867Df1432eb3dA354413a6E",
"0x1da9176C2CE5cC7115340496fa7D1800a98911CE" "0x1da9176C2CE5cC7115340496fa7D1800a98911CE"
], ],
"type": 3 "type": "messageIdMultisigIsm"
}, },
"zoramainnet": { "zoramainnet": {
"threshold": 3, "threshold": 3,
@ -567,6 +673,6 @@
"0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f", "0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f",
"0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36" "0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36"
], ],
"type": 3 "type": "messageIdMultisigIsm"
} }
} }

@ -1,5 +1,31 @@
# @hyperlane-xyz/core # @hyperlane-xyz/core
## 5.6.0
### Minor Changes
- c55257cf5: Minor token related changes like adding custom hook to 4626 collateral, checking for ERC20 as valid contract in HypERC20Collateral, etc.
- 8cc0d9a4a: Added WHypERC4626 as a wrapper for rebasing HypERC4626
### Patch Changes
- 8cc0d9a4a: Add wrapped HypERC4626 for easy defi use
- @hyperlane-xyz/utils@5.6.1
## 5.5.0
### Minor Changes
- 72c23c0d6: Added PRECISION and rateUpdateNonce to ensure compatibility of HypERC4626
### Patch Changes
- c9085afd9: Patched OPL2ToL1Ism to check for correct messageId for external call in verify
- ec6b874b1: Added nonce to HypERC4626
- Updated dependencies [f1712deb7]
- Updated dependencies [29341950e]
- @hyperlane-xyz/utils@5.6.0
## 5.4.1 ## 5.4.1
### Patch Changes ### Patch Changes

@ -7,5 +7,5 @@ pragma solidity >=0.6.11;
**/ **/
abstract contract PackageVersioned { abstract contract PackageVersioned {
// GENERATED CODE - DO NOT EDIT // GENERATED CODE - DO NOT EDIT
string public constant PACKAGE_VERSION = "5.4.1"; string public constant PACKAGE_VERSION = "5.6.0";
} }

@ -1,10 +1,25 @@
// SPDX-License-Identifier: MIT OR Apache-2.0 // SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity >=0.6.11; pragma solidity >=0.6.11;
/*@@@@@@@ @@@@@@@@@
@@@@@@@@@ @@@@@@@@@
@@@@@@@@@ @@@@@@@@@
@@@@@@@@@ @@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@ HYPERLANE @@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@ @@@@@@@@@
@@@@@@@@@ @@@@@@@@@
@@@@@@@@@ @@@@@@@@@
@@@@@@@@@ @@@@@@@@*/
// ============ Internal Imports ============
import {Router} from "./Router.sol"; import {Router} from "./Router.sol";
import {StandardHookMetadata} from "../hooks/libs/StandardHookMetadata.sol"; import {StandardHookMetadata} from "../hooks/libs/StandardHookMetadata.sol";
abstract contract GasRouter is Router { abstract contract GasRouter is Router {
event GasSet(uint32 domain, uint256 gas);
// ============ Mutable Storage ============ // ============ Mutable Storage ============
mapping(uint32 => uint256) public destinationGas; mapping(uint32 => uint256) public destinationGas;
@ -56,6 +71,7 @@ abstract contract GasRouter is Router {
function _setDestinationGas(uint32 domain, uint256 gas) internal { function _setDestinationGas(uint32 domain, uint256 gas) internal {
destinationGas[domain] = gas; destinationGas[domain] = gas;
emit GasSet(domain, gas);
} }
function _GasRouter_dispatch( function _GasRouter_dispatch(

@ -9,6 +9,10 @@ library TypeCasts {
// alignment preserving cast // alignment preserving cast
function bytes32ToAddress(bytes32 _buf) internal pure returns (address) { function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {
require(
uint256(_buf) <= uint256(type(uint160).max),
"TypeCasts: bytes32ToAddress overflow"
);
return address(uint160(uint256(_buf))); return address(uint160(uint256(_buf)));
} }
} }

@ -1,10 +1,25 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
pragma solidity >=0.8.0; pragma solidity >=0.8.0;
/*@@@@@@@ @@@@@@@@@
@@@@@@@@@ @@@@@@@@@
@@@@@@@@@ @@@@@@@@@
@@@@@@@@@ @@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@ HYPERLANE @@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@ @@@@@@@@@
@@@@@@@@@ @@@@@@@@@
@@@@@@@@@ @@@@@@@@@
@@@@@@@@@ @@@@@@@@*/
// ============ Internal Imports ============
import {TokenRouter} from "./libs/TokenRouter.sol"; import {TokenRouter} from "./libs/TokenRouter.sol";
import {TokenMessage} from "./libs/TokenMessage.sol"; import {TokenMessage} from "./libs/TokenMessage.sol";
import {MailboxClient} from "../client/MailboxClient.sol"; import {MailboxClient} from "../client/MailboxClient.sol";
// ============ External Imports ============
import {Address} from "@openzeppelin/contracts/utils/Address.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
@ -22,6 +37,7 @@ contract HypERC20Collateral is TokenRouter {
* @param erc20 Address of the token to keep as collateral * @param erc20 Address of the token to keep as collateral
*/ */
constructor(address erc20, address _mailbox) TokenRouter(_mailbox) { constructor(address erc20, address _mailbox) TokenRouter(_mailbox) {
require(Address.isContract(erc20), "HypERC20Collateral: invalid token");
wrappedToken = IERC20(erc20); wrappedToken = IERC20(erc20);
} }

@ -66,11 +66,7 @@ contract HypERC4626Collateral is HypERC20Collateral {
// Can't override _transferFromSender only because we need to pass shares in the token message // Can't override _transferFromSender only because we need to pass shares in the token message
_transferFromSender(_amount); _transferFromSender(_amount);
uint256 _shares = _depositIntoVault(_amount); uint256 _shares = _depositIntoVault(_amount);
uint256 _exchangeRate = PRECISION.mulDiv( uint256 _exchangeRate = vault.convertToAssets(PRECISION);
vault.totalAssets(),
vault.totalSupply(),
Math.Rounding.Down
);
rateUpdateNonce++; rateUpdateNonce++;
bytes memory _tokenMetadata = abi.encode( bytes memory _tokenMetadata = abi.encode(
@ -121,15 +117,19 @@ contract HypERC4626Collateral is HypERC20Collateral {
* @dev Update the exchange rate on the synthetic token by accounting for additional yield accrued to the underlying vault * @dev Update the exchange rate on the synthetic token by accounting for additional yield accrued to the underlying vault
* @param _destinationDomain domain of the vault * @param _destinationDomain domain of the vault
*/ */
function rebase(uint32 _destinationDomain) public payable { function rebase(
uint32 _destinationDomain,
bytes calldata _hookMetadata,
address _hook
) public payable {
// force a rebase with an empty transfer to 0x1 // force a rebase with an empty transfer to 0x1
_transferRemote( _transferRemote(
_destinationDomain, _destinationDomain,
NULL_RECIPIENT, NULL_RECIPIENT,
0, 0,
msg.value, msg.value,
bytes(""), _hookMetadata,
address(0) _hook
); );
} }
} }

@ -0,0 +1,113 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity >=0.8.0;
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {HypERC4626} from "./HypERC4626.sol";
import {PackageVersioned} from "../../PackageVersioned.sol";
/*@@@@@@@ @@@@@@@@@
@@@@@@@@@ @@@@@@@@@
@@@@@@@@@ @@@@@@@@@
@@@@@@@@@ @@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@ HYPERLANE @@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@ @@@@@@@@@
@@@@@@@@@ @@@@@@@@@
@@@@@@@@@ @@@@@@@@@
@@@@@@@@@ @@@@@@@@*/
/**
* @title WHypERC4626
* @author Abacus Works
* @notice A wrapper for HypERC4626 that allows for wrapping and unwrapping of underlying rebasing tokens
*/
contract WHypERC4626 is ERC20, PackageVersioned {
HypERC4626 public immutable underlying;
constructor(
HypERC4626 _underlying,
string memory name,
string memory symbol
) ERC20(name, symbol) {
underlying = _underlying;
}
/*
* @notice Wraps an amount of underlying tokens into wrapped tokens
* @param _underlyingAmount The amount of underlying tokens to wrap
* @return The amount of wrapped tokens
*/
function wrap(uint256 _underlyingAmount) external returns (uint256) {
require(
_underlyingAmount > 0,
"WHypERC4626: wrap amount must be greater than 0"
);
uint256 wrappedAmount = underlying.assetsToShares(_underlyingAmount);
_mint(msg.sender, wrappedAmount);
underlying.transferFrom(msg.sender, address(this), _underlyingAmount);
return wrappedAmount;
}
/*
* @notice Unwraps an amount of wrapped tokens into underlying tokens
* @param _wrappedAmount The amount of wrapped tokens to unwrap
* @return The amount of underlying tokens
*/
function unwrap(uint256 _wrappedAmount) external returns (uint256) {
require(
_wrappedAmount > 0,
"WHypERC4626: unwrap amount must be greater than 0"
);
uint256 underlyingAmount = underlying.sharesToAssets(_wrappedAmount);
_burn(msg.sender, _wrappedAmount);
underlying.transfer(msg.sender, underlyingAmount);
return underlyingAmount;
}
/*
* @notice Gets the amount of wrapped tokens for a given amount of underlying tokens
* @param _underlyingAmount The amount of underlying tokens
* @return The amount of wrapped tokens
*/
function getWrappedAmount(
uint256 _underlyingAmount
) external view returns (uint256) {
return underlying.assetsToShares(_underlyingAmount);
}
/*
* @notice Gets the amount of underlying tokens for a given amount of wrapped tokens
* @param _wrappedAmount The amount of wrapped tokens
* @return The amount of underlying tokens
*/
function getUnderlyingAmount(
uint256 _wrappedAmount
) external view returns (uint256) {
return underlying.sharesToAssets(_wrappedAmount);
}
/*
* @notice Gets the amount of wrapped tokens for 1 unit of underlying tokens
* @return The amount of wrapped tokens
*/
function wrappedPerUnderlying() external view returns (uint256) {
return underlying.assetsToShares(1 * 10 ** underlying.decimals());
}
/*
* @notice Gets the amount of underlying tokens for 1 unit of wrapped tokens
* @return The amount of underlying tokens
*/
function underlyingPerWrapped() external view returns (uint256) {
return underlying.sharesToAssets(1 * 10 ** decimals());
}
/*
* @notice Gets the decimals of the wrapped token
* @return The decimals of the wrapped token
*/
function decimals() public view override returns (uint8) {
return underlying.decimals();
}
}

@ -1,11 +1,11 @@
{ {
"name": "@hyperlane-xyz/core", "name": "@hyperlane-xyz/core",
"description": "Core solidity contracts for Hyperlane", "description": "Core solidity contracts for Hyperlane",
"version": "5.4.1", "version": "5.6.0",
"dependencies": { "dependencies": {
"@arbitrum/nitro-contracts": "^1.2.1", "@arbitrum/nitro-contracts": "^1.2.1",
"@eth-optimism/contracts": "^0.6.0", "@eth-optimism/contracts": "^0.6.0",
"@hyperlane-xyz/utils": "5.5.0", "@hyperlane-xyz/utils": "5.6.1",
"@layerzerolabs/lz-evm-oapp-v2": "2.0.2", "@layerzerolabs/lz-evm-oapp-v2": "2.0.2",
"@openzeppelin/contracts": "^4.9.3", "@openzeppelin/contracts": "^4.9.3",
"@openzeppelin/contracts-upgradeable": "^v4.9.3", "@openzeppelin/contracts-upgradeable": "^v4.9.3",

@ -68,6 +68,8 @@ contract GasRouterTest is Test {
} }
function testSetDestinationGas(uint256 gas) public { function testSetDestinationGas(uint256 gas) public {
vm.expectEmit(true, true, true, true);
emit GasRouter.GasSet(originDomain, gas);
setDestinationGas(remoteRouter, originDomain, gas); setDestinationGas(remoteRouter, originDomain, gas);
assertEq(remoteRouter.destinationGas(originDomain), gas); assertEq(remoteRouter.destinationGas(originDomain), gas);

@ -75,7 +75,7 @@ contract RateLimitedIsmTest is Test {
TokenMessage.format(bytes32(""), _amount, bytes("")) TokenMessage.format(bytes32(""), _amount, bytes(""))
); );
vm.expectRevert("InvalidRecipient"); vm.expectRevert("TypeCasts: bytes32ToAddress overflow");
rateLimitedIsm.verify(bytes(""), _message); rateLimitedIsm.verify(bytes(""), _message);
} }

@ -406,6 +406,11 @@ contract HypERC20CollateralTest is HypTokenTest {
_enrollRemoteTokenRouter(); _enrollRemoteTokenRouter();
} }
function test_constructor_revert_ifInvalidToken() public {
vm.expectRevert("HypERC20Collateral: invalid token");
new HypERC20Collateral(address(0), address(localMailbox));
}
function testInitialize_revert_ifAlreadyInitialized() public {} function testInitialize_revert_ifAlreadyInitialized() public {}
function testRemoteTransfer() public { function testRemoteTransfer() public {

@ -24,7 +24,9 @@ import {MockMailbox} from "../../contracts/mock/MockMailbox.sol";
import {HypERC20} from "../../contracts/token/HypERC20.sol"; import {HypERC20} from "../../contracts/token/HypERC20.sol";
import {HypERC4626Collateral} from "../../contracts/token/extensions/HypERC4626Collateral.sol"; import {HypERC4626Collateral} from "../../contracts/token/extensions/HypERC4626Collateral.sol";
import {HypERC4626} from "../../contracts/token/extensions/HypERC4626.sol"; import {HypERC4626} from "../../contracts/token/extensions/HypERC4626.sol";
import {StandardHookMetadata} from "../../contracts/hooks/libs/StandardHookMetadata.sol";
import "../../contracts/test/ERC4626/ERC4626Test.sol"; import "../../contracts/test/ERC4626/ERC4626Test.sol";
import {ProtocolFee} from "../../contracts/hooks/ProtocolFee.sol";
contract HypERC4626CollateralTest is HypTokenTest { contract HypERC4626CollateralTest is HypTokenTest {
using TypeCasts for address; using TypeCasts for address;
@ -124,14 +126,38 @@ contract HypERC4626CollateralTest is HypTokenTest {
_accrueYield(); _accrueYield();
localRebasingToken.rebase(DESTINATION); localRebasingToken.rebase(DESTINATION, bytes(""), address(0));
remoteMailbox.processNextInboundMessage(); remoteMailbox.processNextInboundMessage();
assertEq( assertApproxEqRelDecimal(
remoteToken.balanceOf(BOB), remoteToken.balanceOf(BOB),
transferAmount + _discountedYield() transferAmount + _discountedYield(),
1e14,
0
); );
} }
function testRemoteTransfer_rebaseWithCustomHook() public {
_performRemoteTransferWithoutExpectation(0, transferAmount);
assertEq(remoteToken.balanceOf(BOB), transferAmount);
_accrueYield();
uint256 FEE = 1e18;
ProtocolFee customHook = new ProtocolFee(
FEE,
FEE,
address(this),
address(this)
);
localRebasingToken.rebase{value: FEE}(
DESTINATION,
StandardHookMetadata.overrideMsgValue(FEE),
address(customHook)
);
assertEq(address(customHook).balance, FEE);
}
function testRebaseWithTransfer() public { function testRebaseWithTransfer() public {
_performRemoteTransferWithoutExpectation(0, transferAmount); _performRemoteTransferWithoutExpectation(0, transferAmount);
assertEq(remoteToken.balanceOf(BOB), transferAmount); assertEq(remoteToken.balanceOf(BOB), transferAmount);
@ -275,7 +301,7 @@ contract HypERC4626CollateralTest is HypTokenTest {
_accrueYield(); _accrueYield();
localRebasingToken.rebase(DESTINATION); localRebasingToken.rebase(DESTINATION, bytes(""), address(0));
remoteMailbox.processNextInboundMessage(); remoteMailbox.processNextInboundMessage();
// Use balance here since it might be off by <1bp // Use balance here since it might be off by <1bp
@ -314,7 +340,7 @@ contract HypERC4626CollateralTest is HypTokenTest {
_accrueYield(); _accrueYield();
_accrueYield(); // earning 2x yield to be split _accrueYield(); // earning 2x yield to be split
localRebasingToken.rebase(DESTINATION); localRebasingToken.rebase(DESTINATION, bytes(""), address(0));
vm.prank(CAROL); vm.prank(CAROL);
remoteToken.transferRemote( remoteToken.transferRemote(
@ -352,7 +378,7 @@ contract HypERC4626CollateralTest is HypTokenTest {
// decrease collateral in vault by 10% // decrease collateral in vault by 10%
uint256 drawdown = 5e18; uint256 drawdown = 5e18;
primaryToken.burnFrom(address(vault), drawdown); primaryToken.burnFrom(address(vault), drawdown);
localRebasingToken.rebase(DESTINATION); localRebasingToken.rebase(DESTINATION, bytes(""), address(0));
remoteMailbox.processNextInboundMessage(); remoteMailbox.processNextInboundMessage();
// Use balance here since it might be off by <1bp // Use balance here since it might be off by <1bp
@ -378,7 +404,7 @@ contract HypERC4626CollateralTest is HypTokenTest {
_accrueYield(); _accrueYield();
localRebasingToken.rebase(DESTINATION); localRebasingToken.rebase(DESTINATION, bytes(""), address(0));
remoteMailbox.processNextInboundMessage(); remoteMailbox.processNextInboundMessage();
vm.prank(BOB); vm.prank(BOB);
@ -389,13 +415,23 @@ contract HypERC4626CollateralTest is HypTokenTest {
); );
peerMailbox.processNextInboundMessage(); peerMailbox.processNextInboundMessage();
assertEq(remoteRebasingToken.exchangeRate(), 1045e7); // 5 * 0.9 = 4.5% yield assertApproxEqRelDecimal(
remoteRebasingToken.exchangeRate(),
1045e7,
1e14,
0
); // 5 * 0.9 = 4.5% yield
assertEq(peerRebasingToken.exchangeRate(), 1e10); // assertingthat transfers by the synthetic variant don't impact the exchang rate assertEq(peerRebasingToken.exchangeRate(), 1e10); // assertingthat transfers by the synthetic variant don't impact the exchang rate
localRebasingToken.rebase(PEER_DESTINATION); localRebasingToken.rebase(PEER_DESTINATION, bytes(""), address(0));
peerMailbox.processNextInboundMessage(); peerMailbox.processNextInboundMessage();
assertEq(peerRebasingToken.exchangeRate(), 1045e7); // asserting that the exchange rate is set finally by the collateral variant assertApproxEqRelDecimal(
peerRebasingToken.exchangeRate(),
1045e7,
1e14,
0
); // asserting that the exchange rate is set finally by the collateral variant
} }
function test_cyclicTransfers() public { function test_cyclicTransfers() public {
@ -405,7 +441,7 @@ contract HypERC4626CollateralTest is HypTokenTest {
_accrueYield(); _accrueYield();
localRebasingToken.rebase(DESTINATION); // yield is added localRebasingToken.rebase(DESTINATION, bytes(""), address(0)); // yield is added
remoteMailbox.processNextInboundMessage(); remoteMailbox.processNextInboundMessage();
// BOB: remote -> peer(BOB) (yield is leftover) // BOB: remote -> peer(BOB) (yield is leftover)
@ -417,7 +453,7 @@ contract HypERC4626CollateralTest is HypTokenTest {
); );
peerMailbox.processNextInboundMessage(); peerMailbox.processNextInboundMessage();
localRebasingToken.rebase(PEER_DESTINATION); localRebasingToken.rebase(PEER_DESTINATION, bytes(""), address(0));
peerMailbox.processNextInboundMessage(); peerMailbox.processNextInboundMessage();
// BOB: peer -> local(CAROL) // BOB: peer -> local(CAROL)
@ -457,11 +493,13 @@ contract HypERC4626CollateralTest is HypTokenTest {
_accrueYield(); _accrueYield();
localRebasingToken.rebase(DESTINATION); localRebasingToken.rebase(DESTINATION, bytes(""), address(0));
remoteMailbox.processNextInboundMessage(); remoteMailbox.processNextInboundMessage();
assertEq( assertApproxEqRelDecimal(
remoteToken.balanceOf(BOB), remoteToken.balanceOf(BOB),
transferAmount + _discountedYield() transferAmount + _discountedYield(),
1e14,
0
); );
vm.prank(address(localMailbox)); vm.prank(address(localMailbox));

@ -0,0 +1,116 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity ^0.8.13;
import {Test} from "forge-std/Test.sol";
import {MockMailbox} from "../../contracts/mock/MockMailbox.sol";
import {WHypERC4626} from "../../contracts/token/extensions/WHypERC4626.sol";
import {HypERC4626} from "../../contracts/token/extensions/HypERC4626.sol";
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract MockHypERC4626 is HypERC4626 {
constructor(address _mailbox) HypERC4626(18, _mailbox, 2) {}
function mint(address to, uint256 amount) external {
_mint(to, amount);
}
}
contract WHypERC4626Test is Test {
WHypERC4626 public wHypERC4626;
MockHypERC4626 public underlyingToken;
address public alice = address(0x1);
address public bob = address(0x2);
function setUp() public {
MockMailbox mailbox = new MockMailbox(1);
underlyingToken = new MockHypERC4626(address(mailbox));
wHypERC4626 = new WHypERC4626(
underlyingToken,
"Wrapped Rebasing Token",
"WRT"
);
underlyingToken.mint(alice, 1000 * 10 ** 18);
underlyingToken.mint(bob, 1000 * 10 ** 18);
}
function test_wrap() public {
uint256 amount = 100 * 10 ** 18;
vm.startPrank(alice);
underlyingToken.approve(address(wHypERC4626), amount);
uint256 wrappedAmount = wHypERC4626.wrap(amount);
assertEq(wHypERC4626.balanceOf(alice), wrappedAmount);
assertEq(underlyingToken.balanceOf(alice), 900 * 10 ** 18);
vm.stopPrank();
}
function test_wrap_revertsWhen_zeroAmount() public {
vm.startPrank(alice);
underlyingToken.approve(address(wHypERC4626), 0);
vm.expectRevert("WHypERC4626: wrap amount must be greater than 0");
wHypERC4626.wrap(0);
vm.stopPrank();
}
function test_unwrap() public {
uint256 amount = 100 * 10 ** 18;
vm.startPrank(alice);
underlyingToken.approve(address(wHypERC4626), amount);
uint256 wrappedAmount = wHypERC4626.wrap(amount);
uint256 unwrappedAmount = wHypERC4626.unwrap(wrappedAmount);
assertEq(wHypERC4626.balanceOf(alice), 0);
assertEq(underlyingToken.balanceOf(alice), 1000 * 10 ** 18);
assertEq(unwrappedAmount, amount);
vm.stopPrank();
}
function test_unwrap_revertsWhen_zeroAmount() public {
vm.startPrank(alice);
vm.expectRevert("WHypERC4626: unwrap amount must be greater than 0");
wHypERC4626.unwrap(0);
vm.stopPrank();
}
function test_getWrappedAmount() public view {
uint256 amount = 100 * 10 ** 18;
uint256 wrappedAmount = wHypERC4626.getWrappedAmount(amount);
assertEq(wrappedAmount, underlyingToken.assetsToShares(amount));
}
function test_getUnderlyingAmount() public view {
uint256 amount = 100 * 10 ** 18;
uint256 underlyingAmount = wHypERC4626.getUnderlyingAmount(amount);
assertEq(underlyingAmount, underlyingToken.sharesToAssets(amount));
}
function test_wrappedPerUnderlying() public view {
uint256 wrappedPerUnderlying = wHypERC4626.wrappedPerUnderlying();
assertEq(
wrappedPerUnderlying,
underlyingToken.assetsToShares(1 * 10 ** underlyingToken.decimals())
);
}
function test_underlyingPerWrapped() public view {
uint256 underlyingPerWrapped = wHypERC4626.underlyingPerWrapped();
assertEq(
underlyingPerWrapped,
underlyingToken.sharesToAssets(1 * 10 ** underlyingToken.decimals())
);
}
function test_decimals() public view {
uint8 decimals = wHypERC4626.decimals();
assertEq(decimals, underlyingToken.decimals());
}
}

@ -1,5 +1,9 @@
# @hyperlane-xyz/ccip-server # @hyperlane-xyz/ccip-server
## 5.6.1
## 5.6.0
## 5.5.0 ## 5.5.0
## 5.4.0 ## 5.4.0

@ -1,6 +1,6 @@
{ {
"name": "@hyperlane-xyz/ccip-server", "name": "@hyperlane-xyz/ccip-server",
"version": "5.5.0", "version": "5.6.1",
"description": "CCIP server", "description": "CCIP server",
"typings": "dist/index.d.ts", "typings": "dist/index.d.ts",
"typedocMain": "src/index.ts", "typedocMain": "src/index.ts",

@ -0,0 +1,8 @@
{
"extensions": ["ts"],
"spec": ["src/**/*.e2e-test.ts"],
"node-option": [
"experimental-specifier-resolution=node",
"loader=ts-node/esm"
]
}

@ -1,6 +1,6 @@
{ {
"extensions": ["ts"], "extensions": ["ts"],
"spec": ["src/**/*.test.*", "src/**/*.e2e-test.ts"], "spec": ["src/**/*.test.*"],
"node-option": [ "node-option": [
"experimental-specifier-resolution=node", "experimental-specifier-resolution=node",
"loader=ts-node/esm" "loader=ts-node/esm"

@ -1,5 +1,46 @@
# @hyperlane-xyz/cli # @hyperlane-xyz/cli
## 5.6.1
### Patch Changes
- 3474a8450: Explicitly define inquirer/core and inquirier/figures dependencies
- @hyperlane-xyz/sdk@5.6.1
- @hyperlane-xyz/utils@5.6.1
## 5.6.0
### Minor Changes
- 41035aac8: Add strategyUrl detect and validation in the beginning of `warp apply`
Remove yaml transactions print from `warp apply`
- 29341950e: Adds new `core check` command to compare local configuration and on chain deployments. Adds memoization to the EvmHookReader to avoid repeating configuration derivation
- 32d0a67c2: Adds the warp check command to compare warp routes config files with on chain warp route deployments
- 3662297fc: Add prompt in `warp init` command to choose if a trusted relayer should be used instead of making the choice by default for the user and enable the `--yes` flag to default to a trusted ISM
- b1ff48bd1: Add rebasing yield route support into CLI/SDK
- d41aa6928: Add `EthJsonRpcBlockParameterTag` enum for validating reorgPeriod
- c3e9268f1: Add support for an arbitrary string in `reorgPeriod`, which is used as a block tag to get the finalized block.
- a4d5d692f: Update `warp apply` such that it updates in place AND extends in a single call
- 01e7070eb: updates the multi chain selection prompt by adding search functionality and an optional confirmation prompt for the current selection
### Patch Changes
- e89f9e35d: Update registry to v4.7.0
- Updated dependencies [f1712deb7]
- Updated dependencies [46044a2e9]
- Updated dependencies [02a5b92ba]
- Updated dependencies [29341950e]
- Updated dependencies [8001bbbd6]
- Updated dependencies [32d0a67c2]
- Updated dependencies [b1ff48bd1]
- Updated dependencies [d41aa6928]
- Updated dependencies [c3e9268f1]
- Updated dependencies [7d7bcc1a3]
- Updated dependencies [7f3e0669d]
- Updated dependencies [2317eca3c]
- @hyperlane-xyz/utils@5.6.0
- @hyperlane-xyz/sdk@5.6.0
## 5.5.0 ## 5.5.0
### Patch Changes ### Patch Changes

@ -1,13 +1,15 @@
{ {
"name": "@hyperlane-xyz/cli", "name": "@hyperlane-xyz/cli",
"version": "5.5.0", "version": "5.6.1",
"description": "A command-line utility for common Hyperlane operations", "description": "A command-line utility for common Hyperlane operations",
"dependencies": { "dependencies": {
"@aws-sdk/client-kms": "^3.577.0", "@aws-sdk/client-kms": "^3.577.0",
"@aws-sdk/client-s3": "^3.577.0", "@aws-sdk/client-s3": "^3.577.0",
"@hyperlane-xyz/registry": "4.7.0", "@hyperlane-xyz/registry": "4.7.0",
"@hyperlane-xyz/sdk": "5.5.0", "@hyperlane-xyz/sdk": "5.6.1",
"@hyperlane-xyz/utils": "5.5.0", "@hyperlane-xyz/utils": "5.6.1",
"@inquirer/core": "9.0.10",
"@inquirer/figures": "1.0.5",
"@inquirer/prompts": "^3.0.0", "@inquirer/prompts": "^3.0.0",
"ansi-escapes": "^7.0.0", "ansi-escapes": "^7.0.0",
"asn1.js": "^5.4.1", "asn1.js": "^5.4.1",
@ -47,7 +49,8 @@
"clean": "rm -rf ./dist", "clean": "rm -rf ./dist",
"lint": "eslint . --ext .ts", "lint": "eslint . --ext .ts",
"prettier": "prettier --write ./src ./examples", "prettier": "prettier --write ./src ./examples",
"test:ci": "./scripts/all-test.sh", "test:ci": "yarn mocha --config .mocharc.json",
"test:e2e": "./scripts/run-e2e-test.sh",
"version:update": "echo \"export const VERSION = '$npm_package_version';\" > src/version.ts" "version:update": "echo \"export const VERSION = '$npm_package_version';\" > src/version.ts"
}, },
"files": [ "files": [

@ -1,24 +1,24 @@
#!/usr/bin/env bash #!/usr/bin/env bash
function cleanup() { function cleanup() {
set +e set +e
pkill -f anvil pkill -f anvil
rm -rf /tmp/anvil2 rm -rf /tmp/anvil2
rm -rf /tmp/anvil3 rm -rf /tmp/anvil3
rm -f ./test-configs/anvil/chains/anvil2/addresses.yaml rm -f ./test-configs/anvil/chains/anvil2/addresses.yaml
rm -f ./test-configs/anvil/chains/anvil3/addresses.yaml rm -f ./test-configs/anvil/chains/anvil3/addresses.yaml
set -e set -e
} }
cleanup cleanup
echo "Starting anvil2 and anvil3 chain" echo "Starting anvil2 and anvil3 chain for E2E tests"
anvil --chain-id 31338 -p 8555 --state /tmp/anvil2/state --gas-price 1 > /dev/null & anvil --chain-id 31338 -p 8555 --state /tmp/anvil2/state --gas-price 1 > /dev/null &
anvil --chain-id 31347 -p 8600 --state /tmp/anvil3/state --gas-price 1 > /dev/null & anvil --chain-id 31347 -p 8600 --state /tmp/anvil3/state --gas-price 1 > /dev/null &
echo "Running all tests" echo "Running E2E tests"
yarn mocha --config .mocharc.json yarn mocha --config .mocharc-e2e.json
cleanup cleanup
echo "Done all tests" echo "Completed E2E tests"

@ -1,10 +1,13 @@
import { stringify as yamlStringify } from 'yaml';
import { CommandModule } from 'yargs'; import { CommandModule } from 'yargs';
import { import {
CoreConfig,
DeployedCoreAddresses, DeployedCoreAddresses,
DeployedCoreAddressesSchema, DeployedCoreAddressesSchema,
EvmCoreReader, normalizeConfig,
} from '@hyperlane-xyz/sdk'; } from '@hyperlane-xyz/sdk';
import { diffObjMerge } from '@hyperlane-xyz/utils';
import { import {
createCoreDeployConfig, createCoreDeployConfig,
@ -16,17 +19,21 @@ import {
} from '../context/types.js'; } from '../context/types.js';
import { runCoreApply, runCoreDeploy } from '../deploy/core.js'; import { runCoreApply, runCoreDeploy } from '../deploy/core.js';
import { evaluateIfDryRunFailure } from '../deploy/dry-run.js'; import { evaluateIfDryRunFailure } from '../deploy/dry-run.js';
import { errorRed, log, logGray, logGreen } from '../logger.js'; import { log, logCommandHeader, logGreen } from '../logger.js';
import { executeCoreRead } from '../read/core.js';
import { import {
logYamlIfUnderMaxLines, logYamlIfUnderMaxLines,
readYamlOrJson, readYamlOrJson,
writeYamlOrJson, writeYamlOrJson,
} from '../utils/files.js'; } from '../utils/files.js';
import { formatYamlViolationsOutput } from '../utils/output.js';
import { import {
DEFAULT_CORE_DEPLOYMENT_CONFIG_PATH,
chainCommandOption, chainCommandOption,
dryRunCommandOption, dryRunCommandOption,
fromAddressCommandOption, fromAddressCommandOption,
inputFileCommandOption,
outputFileCommandOption, outputFileCommandOption,
skipConfirmationOption, skipConfirmationOption,
} from './options.js'; } from './options.js';
@ -40,6 +47,7 @@ export const coreCommand: CommandModule = {
builder: (yargs) => builder: (yargs) =>
yargs yargs
.command(apply) .command(apply)
.command(check)
.command(deploy) .command(deploy)
.command(init) .command(init)
.command(read) .command(read)
@ -47,6 +55,7 @@ export const coreCommand: CommandModule = {
.demandCommand(), .demandCommand(),
handler: () => log('Command required'), handler: () => log('Command required'),
}; };
export const apply: CommandModuleWithWriteContext<{ export const apply: CommandModuleWithWriteContext<{
chain: string; chain: string;
config: string; config: string;
@ -60,14 +69,13 @@ export const apply: CommandModuleWithWriteContext<{
demandOption: true, demandOption: true,
}, },
config: outputFileCommandOption( config: outputFileCommandOption(
'./configs/core-config.yaml', DEFAULT_CORE_DEPLOYMENT_CONFIG_PATH,
true, true,
'The path to output a Core Config JSON or YAML file.', 'The path to output a Core Config JSON or YAML file.',
), ),
}, },
handler: async ({ context, chain, config: configFilePath }) => { handler: async ({ context, chain, config: configFilePath }) => {
logGray(`Hyperlane Core Apply`); logCommandHeader(`Hyperlane Core Apply`);
logGray('--------------------');
const addresses = (await context.registry.getChainAddresses( const addresses = (await context.registry.getChainAddresses(
chain, chain,
@ -103,7 +111,7 @@ export const deploy: CommandModuleWithWriteContext<{
builder: { builder: {
chain: chainCommandOption, chain: chainCommandOption,
config: outputFileCommandOption( config: outputFileCommandOption(
'./configs/core-config.yaml', DEFAULT_CORE_DEPLOYMENT_CONFIG_PATH,
false, false,
'The path to a JSON or YAML file with a core deployment config.', 'The path to a JSON or YAML file with a core deployment config.',
), ),
@ -112,8 +120,7 @@ export const deploy: CommandModuleWithWriteContext<{
'skip-confirmation': skipConfirmationOption, 'skip-confirmation': skipConfirmationOption,
}, },
handler: async ({ context, chain, config: configFilePath, dryRun }) => { handler: async ({ context, chain, config: configFilePath, dryRun }) => {
logGray(`Hyperlane Core deployment${dryRun ? ' dry-run' : ''}`); logCommandHeader(`Hyperlane Core deployment${dryRun ? ' dry-run' : ''}`);
logGray(`------------------------------------------------`);
try { try {
await runCoreDeploy({ await runCoreDeploy({
@ -142,14 +149,13 @@ export const init: CommandModuleWithContext<{
default: false, default: false,
}, },
config: outputFileCommandOption( config: outputFileCommandOption(
'./configs/core-config.yaml', DEFAULT_CORE_DEPLOYMENT_CONFIG_PATH,
false, false,
'The path to output a Core Config JSON or YAML file.', 'The path to output a Core Config JSON or YAML file.',
), ),
}, },
handler: async ({ context, advanced, config: configFilePath }) => { handler: async ({ context, advanced, config: configFilePath }) => {
logGray('Hyperlane Core Configure'); logCommandHeader('Hyperlane Core Configure');
logGray('------------------------');
await createCoreDeployConfig({ await createCoreDeployConfig({
context, context,
@ -178,39 +184,70 @@ export const read: CommandModuleWithContext<{
description: 'Mailbox address used to derive the core config', description: 'Mailbox address used to derive the core config',
}, },
config: outputFileCommandOption( config: outputFileCommandOption(
'./configs/core-config.yaml', DEFAULT_CORE_DEPLOYMENT_CONFIG_PATH,
false, false,
'The path to output a Core Config JSON or YAML file.', 'The path to output a Core Config JSON or YAML file.',
), ),
}, },
handler: async ({ context, chain, mailbox, config: configFilePath }) => { handler: async ({ context, chain, mailbox, config: configFilePath }) => {
if (!mailbox) { logCommandHeader('Hyperlane Core Read');
const addresses = await context.registry.getChainAddresses(chain);
mailbox = addresses?.mailbox;
if (!mailbox) {
throw new Error(
`${chain} mailbox not provided and none found in registry.`,
);
}
}
logGray('Hyperlane Core Read'); const coreConfig = await executeCoreRead({ context, chain, mailbox });
logGray('-------------------');
const evmCoreReader = new EvmCoreReader(context.multiProvider, chain); writeYamlOrJson(configFilePath, coreConfig, 'yaml');
try { logGreen(`✅ Core config written successfully to ${configFilePath}:\n`);
const coreConfig = await evmCoreReader.deriveCoreConfig(mailbox); logYamlIfUnderMaxLines(coreConfig);
writeYamlOrJson(configFilePath, coreConfig, 'yaml');
logGreen(`✅ Core config written successfully to ${configFilePath}:\n`); process.exit(0);
logYamlIfUnderMaxLines(coreConfig); },
} catch (e: any) { };
errorRed(
`❌ Failed to read core config for mailbox ${mailbox} on ${chain}:`, export const check: CommandModuleWithContext<{
e, chain: string;
); config: string;
mailbox?: string;
}> = {
command: 'check',
describe:
'Reads onchain Core configuration for a given mailbox address and compares it with a provided file',
builder: {
chain: {
...chainCommandOption,
demandOption: true,
},
mailbox: {
type: 'string',
description:
'Mailbox address used to derive the core config. If not provided it will be inferred from the registry',
},
config: inputFileCommandOption({
defaultPath: DEFAULT_CORE_DEPLOYMENT_CONFIG_PATH,
description: 'The path to a a Core Config JSON or YAML file.',
demandOption: false,
}),
},
handler: async ({ context, chain, mailbox, config: configFilePath }) => {
logCommandHeader('Hyperlane Core Check');
const expectedCoreConfig: CoreConfig = await readYamlOrJson(configFilePath);
const onChainCoreConfig = await executeCoreRead({
context,
chain,
mailbox,
});
const { mergedObject, isInvalid } = diffObjMerge(
normalizeConfig(onChainCoreConfig),
normalizeConfig(expectedCoreConfig),
);
if (isInvalid) {
log(formatYamlViolationsOutput(yamlStringify(mergedObject, null, 2)));
process.exit(1); process.exit(1);
} }
logGreen(`No violations found`);
process.exit(0); process.exit(0);
}, },
}; };

@ -94,6 +94,8 @@ export const hookCommandOption: Options = {
export const DEFAULT_WARP_ROUTE_DEPLOYMENT_CONFIG_PATH = export const DEFAULT_WARP_ROUTE_DEPLOYMENT_CONFIG_PATH =
'./configs/warp-route-deployment.yaml'; './configs/warp-route-deployment.yaml';
export const DEFAULT_CORE_DEPLOYMENT_CONFIG_PATH = './configs/core-config.yaml';
export const warpDeploymentConfigCommandOption: Options = { export const warpDeploymentConfigCommandOption: Options = {
type: 'string', type: 'string',
description: description:

@ -5,6 +5,7 @@ import { stringify as yamlStringify } from 'yaml';
import { import {
ChainMetadata, ChainMetadata,
ChainMetadataSchema, ChainMetadataSchema,
EthJsonRpcBlockParameterTag,
ExplorerFamily, ExplorerFamily,
ZChainName, ZChainName,
} from '@hyperlane-xyz/sdk'; } from '@hyperlane-xyz/sdk';
@ -168,6 +169,13 @@ async function addBlockOrGasConfig(metadata: ChainMetadata): Promise<void> {
} }
async function addBlockConfig(metadata: ChainMetadata): Promise<void> { async function addBlockConfig(metadata: ChainMetadata): Promise<void> {
const parseReorgPeriod = (
value: string,
): number | EthJsonRpcBlockParameterTag => {
const parsed = parseInt(value, 10);
return isNaN(parsed) ? (value as EthJsonRpcBlockParameterTag) : parsed;
};
const wantBlockConfig = await confirm({ const wantBlockConfig = await confirm({
message: 'Do you want to add block config for this chain', message: 'Do you want to add block config for this chain',
}); });
@ -179,8 +187,16 @@ async function addBlockConfig(metadata: ChainMetadata): Promise<void> {
}); });
const blockReorgPeriod = await input({ const blockReorgPeriod = await input({
message: message:
'Enter no. of blocks before a transaction has a near-zero chance of reverting (0-500):', 'Enter no. of blocks before a transaction has a near-zero chance of reverting (0-500) or block tag (earliest, latest, safe, finalized, pending):',
validate: (value) => parseInt(value) >= 0 && parseInt(value) <= 500, validate: (value) => {
const parsedInt = parseInt(value, 10);
return (
Object.values(EthJsonRpcBlockParameterTag).includes(
value as EthJsonRpcBlockParameterTag,
) ||
(!isNaN(parsedInt) && parsedInt >= 0 && parsedInt <= 500)
);
},
}); });
const blockTimeEstimate = await input({ const blockTimeEstimate = await input({
message: 'Enter the rough estimate of time per block in seconds (0-20):', message: 'Enter the rough estimate of time per block in seconds (0-20):',
@ -188,7 +204,7 @@ async function addBlockConfig(metadata: ChainMetadata): Promise<void> {
}); });
metadata.blocks = { metadata.blocks = {
confirmations: parseInt(blockConfirmation, 10), confirmations: parseInt(blockConfirmation, 10),
reorgPeriod: parseInt(blockReorgPeriod, 10), reorgPeriod: parseReorgPeriod(blockReorgPeriod),
estimateBlockTime: parseInt(blockTimeEstimate, 10), estimateBlockTime: parseInt(blockTimeEstimate, 10),
}; };
} }

@ -0,0 +1,36 @@
import { ChainName, CoreConfig, EvmCoreReader } from '@hyperlane-xyz/sdk';
import { Address, assert } from '@hyperlane-xyz/utils';
import { CommandContext } from '../context/types.js';
import { errorRed } from '../logger.js';
export async function executeCoreRead({
context,
chain,
mailbox,
}: {
context: CommandContext;
chain: ChainName;
mailbox?: Address;
}): Promise<CoreConfig> {
if (!mailbox) {
const addresses = await context.registry.getChainAddresses(chain);
mailbox = addresses?.mailbox;
assert(
mailbox,
`${chain} mailbox not provided and none found in registry.`,
);
}
const evmCoreReader = new EvmCoreReader(context.multiProvider, chain);
try {
return evmCoreReader.deriveCoreConfig(mailbox);
} catch (e: any) {
errorRed(
`❌ Failed to read core config for mailbox ${mailbox} on ${chain}:`,
e,
);
process.exit(1);
}
}

@ -1 +1 @@
export const VERSION = '5.5.0'; export const VERSION = '5.6.1';

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save