From b5142fb148e86c2e9f1aee4ef694eaafe9e4a4d2 Mon Sep 17 00:00:00 2001 From: Pablo Date: Fri, 6 Feb 2026 12:15:35 -0600 Subject: [PATCH 1/2] feat: refactor usages of chain selectors API to use remote API Signed-off-by: Pablo --- docs/docs/usage/building-proposals.md | 24 +++++++++------- docs/docs/usage/executing-proposals.md | 6 ++-- docs/docs/usage/set-config.md | 4 +-- docs/docs/usage/signing-proposals.md | 6 ++-- docs/docs/usage/timelock-proposal-flow.md | 6 ++-- e2e/ledger/ledger_test.go | 6 ++-- e2e/tests/aptos/common.go | 5 ++-- e2e/tests/evm/executable.go | 6 ++-- e2e/tests/evm/set_root.go | 4 +-- e2e/tests/solana/common.go | 5 ++-- e2e/tests/sui/common.go | 4 +-- e2e/tests/ton/executable.go | 9 +++--- e2e/tests/ton/set_root.go | 4 +-- e2e/tests/ton/timelock_inspection.go | 4 +-- factory.go | 22 +++++++-------- internal/testutils/chaintest/testchain.go | 34 +++++++++++------------ sdk/aptos/configurer.go | 6 ++-- sdk/aptos/configurer_test.go | 6 ++-- sdk/aptos/encoder.go | 6 ++-- sdk/aptos/executor.go | 11 ++++---- sdk/aptos/executor_test.go | 8 +++--- sdk/aptos/timelock_executor.go | 4 +-- sdk/aptos/timelock_executor_test.go | 4 +-- sdk/evm/configurer.go | 4 +-- sdk/evm/encoder.go | 10 +++++-- sdk/evm/encoder_test.go | 10 ++++--- sdk/evm/executor.go | 10 +++---- sdk/evm/executor_test.go | 14 +++++----- sdk/evm/timelock_converter_test.go | 10 +++---- sdk/evm/timelock_executor.go | 6 ++-- sdk/evm/utils.go | 11 +++++--- sdk/evm/utils_test.go | 2 +- sdk/solana/common_test.go | 4 +-- sdk/solana/configurer.go | 4 +-- sdk/solana/configurer_test.go | 6 ++-- sdk/solana/executor.go | 6 ++-- sdk/solana/executor_test.go | 8 +++--- sdk/solana/inspector_test.go | 4 +-- sdk/solana/simulator_test.go | 4 +-- sdk/solana/timelock_executor.go | 4 +-- sdk/solana/timelock_executor_test.go | 4 +-- sdk/sui/configurer.go | 7 +++-- timelock_executable_test.go | 6 ++-- validation.go | 22 +++++++-------- validation_test.go | 16 +++++------ 45 files changed, 193 insertions(+), 173 deletions(-) diff --git a/docs/docs/usage/building-proposals.md b/docs/docs/usage/building-proposals.md index 7daa3b789..e71550529 100644 --- a/docs/docs/usage/building-proposals.md +++ b/docs/docs/usage/building-proposals.md @@ -20,11 +20,15 @@ object. package main import ( - "log" - "os" - "io" +"io" +"log" +"os" - "github.com/smartcontractkit/mcms" + + + + +"github.com/smartcontractkit/mcms" ) func main() { @@ -49,7 +53,7 @@ For the JSON structure of the proposal please check the [MCMS Proposal Format Do ### Build Proposal Given Staged but Non-Executed Predecessor Proposals -In scenarios where a proposal is generated with the assumption that multiple proposals are executed beforehand, +In scenarios where a proposal is generated with the assumption that multiple proposals are executed beforehand, you can enable proposals to be signed in parallel with a pre-determined execution order. This can be achieved by passing a list of files using the `WithPredecessors` functional option, as shown below: @@ -57,9 +61,9 @@ by passing a list of files using the `WithPredecessors` functional option, as sh package main import ( + "io" "log" "os" - "io" "github.com/smartcontractkit/mcms" ) @@ -102,7 +106,7 @@ package main import ( "log" - chain_selectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/mcms" "github.com/smartcontractkit/mcms/types" @@ -111,7 +115,7 @@ import ( func main() { // Step 1: Initialize the ProposalBuilder timelockBuilder := mcms.NewProposalBuilder() - selector := types.ChainSelector(chain_selectors.ETHEREUM_TESTNET_SEPOLIA.Selector) + selector := types.ChainSelector(chainsel.ETHEREUM_TESTNET_SEPOLIA.Selector) // Step 2: Set Proposal Details timelockBuilder. @@ -198,7 +202,7 @@ package main import ( "log" - chain_selectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/mcms" "github.com/smartcontractkit/mcms/types" @@ -207,7 +211,7 @@ import ( func main() { // Step 1: Initialize the ProposalBuilder builder := mcms.NewTimelockProposalBuilder() - selector := types.ChainSelector(chain_selectors.ETHEREUM_TESTNET_SEPOLIA.Selector) + selector := types.ChainSelector(chainsel.ETHEREUM_TESTNET_SEPOLIA.Selector) delay, err := types.ParseDuration("1h") if err != nil { diff --git a/docs/docs/usage/executing-proposals.md b/docs/docs/usage/executing-proposals.md index f86edc136..5bf574f0d 100644 --- a/docs/docs/usage/executing-proposals.md +++ b/docs/docs/usage/executing-proposals.md @@ -13,7 +13,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" "github.com/gagliardetto/solana-go" "github.com/gagliardetto/solana-go/rpc" - chain_selectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/mcms" "github.com/smartcontractkit/mcms/sdk" @@ -38,8 +38,8 @@ func main() { } // Step 2: Initialize the Chain Family Executors - evmSelector := chain_selectors.ETHEREUM_TESTNET_SEPOLIA.Selector - solanaSelector := chain_selectors.SOLANA_DEVNET.Selector + evmSelector := chainsel.ETHEREUM_TESTNET_SEPOLIA.Selector + solanaSelector := chainsel.SOLANA_DEVNET.Selector // EVM executor backend := backends.SimulatedBackend{} diff --git a/docs/docs/usage/set-config.md b/docs/docs/usage/set-config.md index f3a495616..35f3229ad 100644 --- a/docs/docs/usage/set-config.md +++ b/docs/docs/usage/set-config.md @@ -14,7 +14,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/gagliardetto/solana-go" rpc2 "github.com/gagliardetto/solana-go/rpc" - chain_selectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/mcms/sdk/evm" mcmsSolana "github.com/smartcontractkit/mcms/sdk/solana" @@ -45,7 +45,7 @@ func main() { ctx := context.Background() // On EVM - solanaSelector := chain_selectors.SOLANA_DEVNET.Selector + solanaSelector := chainsel.SOLANA_DEVNET.Selector mcmsContractAddr := "0x123" backend := backends.SimulatedBackend{} auth := &bind.TransactOpts{} diff --git a/docs/docs/usage/signing-proposals.md b/docs/docs/usage/signing-proposals.md index 543ca4127..18deff9b0 100644 --- a/docs/docs/usage/signing-proposals.md +++ b/docs/docs/usage/signing-proposals.md @@ -13,7 +13,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" "github.com/gagliardetto/solana-go/rpc" - chain_selectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/mcms" "github.com/smartcontractkit/mcms/sdk" @@ -36,7 +36,7 @@ func main() { } // 2. Create the signable type from the proposal - selector := chain_selectors.ETHEREUM_TESTNET_SEPOLIA.Selector + selector := chainsel.ETHEREUM_TESTNET_SEPOLIA.Selector // if evm required: Add EVM Inspector backend := backends.SimulatedBackend{} @@ -45,7 +45,7 @@ func main() { // if solana required: Add Solana Inspector client := rpc.New("https://api.devnet.solana.com") - inspectorsMap[types.ChainSelector(chain_selectors.SOLANA_DEVNET.Selector)] = solana.NewInspector(client) + inspectorsMap[types.ChainSelector(chainsel.SOLANA_DEVNET.Selector)] = solana.NewInspector(client) // Create Signable signable, err := mcms.NewSignable(proposal, inspectorsMap) diff --git a/docs/docs/usage/timelock-proposal-flow.md b/docs/docs/usage/timelock-proposal-flow.md index 611c8c3dc..8ba904a71 100644 --- a/docs/docs/usage/timelock-proposal-flow.md +++ b/docs/docs/usage/timelock-proposal-flow.md @@ -27,7 +27,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" rpc2 "github.com/gagliardetto/solana-go/rpc" - chain_selectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/mcms" "github.com/smartcontractkit/mcms/sdk" @@ -52,8 +52,8 @@ func main() { } // 1.1 Convert to MCMS proposal - selectorEVM := types.ChainSelector(chain_selectors.ETHEREUM_TESTNET_SEPOLIA.Selector) - selectorSolana := types.ChainSelector(chain_selectors.SOLANA_DEVNET.Selector) + selectorEVM := types.ChainSelector(chainsel.ETHEREUM_TESTNET_SEPOLIA.Selector) + selectorSolana := types.ChainSelector(chainsel.SOLANA_DEVNET.Selector) convertersMap := make(map[types.ChainSelector]sdk.TimelockConverter) convertersMap[selectorEVM] = &evm.TimelockConverter{} diff --git a/e2e/ledger/ledger_test.go b/e2e/ledger/ledger_test.go index cbfec273c..c9d364030 100644 --- a/e2e/ledger/ledger_test.go +++ b/e2e/ledger/ledger_test.go @@ -11,7 +11,7 @@ import ( "github.com/stretchr/testify/suite" - cselectors "github.com/smartcontractkit/chain-selectors" + chainselremote "github.com/smartcontractkit/chain-selectors/remote" "github.com/smartcontractkit/mcms" e2e "github.com/smartcontractkit/mcms/e2e/tests" @@ -151,9 +151,9 @@ func (s *ManualLedgerSigningTestSuite) TestManualLedgerSigning() { ctx := context.Background() s.TestSetup = *e2e.InitializeSharedTestSetup(s.T()) - chainDetailsEVM, err := cselectors.GetChainDetailsByChainIDAndFamily(s.BlockchainA.Out.ChainID, s.BlockchainA.Out.Family) + chainDetailsEVM, err := chainselremote.GetChainDetailsByChainIDAndFamily(s.T().Context(), s.BlockchainA.Out.ChainID, s.BlockchainA.Out.Family) s.Require().NoError(err) - chainDetailsSolana, err := cselectors.GetChainDetailsByChainIDAndFamily(s.SolanaChain.ChainID, s.SolanaChain.Out.Family) + chainDetailsSolana, err := chainselremote.GetChainDetailsByChainIDAndFamily(s.T().Context(), s.SolanaChain.ChainID, s.SolanaChain.Out.Family) s.Require().NoError(err) s.chainSelectorEVM = types.ChainSelector(chainDetailsEVM.ChainSelector) diff --git a/e2e/tests/aptos/common.go b/e2e/tests/aptos/common.go index d6787bb23..2612a6d48 100644 --- a/e2e/tests/aptos/common.go +++ b/e2e/tests/aptos/common.go @@ -7,7 +7,8 @@ import ( "github.com/stretchr/testify/suite" - cselectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" + chainselremote "github.com/smartcontractkit/chain-selectors/remote" "github.com/smartcontractkit/chainlink-testing-framework/framework/components/blockchain" @@ -34,7 +35,7 @@ type TestSuite struct { func (a *TestSuite) SetupSuite() { a.TestSetup = *e2e.InitializeSharedTestSetup(a.T()) - details, err := cselectors.GetChainDetailsByChainIDAndFamily(a.AptosChain.ChainID, cselectors.FamilyAptos) + details, err := chainselremote.GetChainDetailsByChainIDAndFamily(a.T().Context(), a.AptosChain.ChainID, chainsel.FamilyAptos) a.Require().NoError(err) a.ChainSelector = types.ChainSelector(details.ChainSelector) diff --git a/e2e/tests/evm/executable.go b/e2e/tests/evm/executable.go index bfae1beed..6b604355f 100644 --- a/e2e/tests/evm/executable.go +++ b/e2e/tests/evm/executable.go @@ -14,7 +14,7 @@ import ( "github.com/samber/lo" "github.com/stretchr/testify/suite" - cselectors "github.com/smartcontractkit/chain-selectors" + chainselremote "github.com/smartcontractkit/chain-selectors/remote" "github.com/smartcontractkit/mcms" e2e "github.com/smartcontractkit/mcms/e2e/tests" @@ -76,7 +76,7 @@ func (s *ExecutionTestSuite) SetupSuite() { s.ChainA.auth, err = bind.NewKeyedTransactorWithChainID(privateKey, chainIDA) s.Require().NoError(err, "Failed to create transactor for Chain A") - chainDetailsA, err := cselectors.GetChainDetailsByChainIDAndFamily(s.BlockchainA.Out.ChainID, s.BlockchainA.Out.Family) + chainDetailsA, err := chainselremote.GetChainDetailsByChainIDAndFamily(s.T().Context(), s.BlockchainA.Out.ChainID, s.BlockchainA.Out.Family) s.Require().NoError(err) s.ChainA.chainSelector = mcmtypes.ChainSelector(chainDetailsA.ChainSelector) @@ -87,7 +87,7 @@ func (s *ExecutionTestSuite) SetupSuite() { s.ChainB.auth, err = bind.NewKeyedTransactorWithChainID(privateKey, chainIDB) s.Require().NoError(err, "Failed to create transactor for Chain B") - chainDetailsB, err := cselectors.GetChainDetailsByChainIDAndFamily(s.BlockchainB.Out.ChainID, s.BlockchainB.Out.Family) + chainDetailsB, err := chainselremote.GetChainDetailsByChainIDAndFamily(s.T().Context(), s.BlockchainB.Out.ChainID, s.BlockchainB.Out.Family) s.Require().NoError(err) s.ChainB.chainSelector = mcmtypes.ChainSelector(chainDetailsB.ChainSelector) diff --git a/e2e/tests/evm/set_root.go b/e2e/tests/evm/set_root.go index 94c98c327..0e26b04a5 100644 --- a/e2e/tests/evm/set_root.go +++ b/e2e/tests/evm/set_root.go @@ -9,7 +9,7 @@ import ( "github.com/stretchr/testify/suite" - cselectors "github.com/smartcontractkit/chain-selectors" + chainselremote "github.com/smartcontractkit/chain-selectors/remote" "github.com/smartcontractkit/mcms" e2e "github.com/smartcontractkit/mcms/e2e/tests" @@ -61,7 +61,7 @@ func (s *SetRootTestSuite) SetupSuite() { s.mcmsContract = s.deployMCMSContract() s.timelockContract = s.deployTimelockContract(s.mcmsContract.Address().String()) - chainDetails, err := cselectors.GetChainDetailsByChainIDAndFamily(s.BlockchainA.Out.ChainID, s.BlockchainA.Out.Family) + chainDetails, err := chainselremote.GetChainDetailsByChainIDAndFamily(s.T().Context(), s.BlockchainA.Out.ChainID, s.BlockchainA.Out.Family) s.Require().NoError(err) s.chainSelector = mcmtypes.ChainSelector(chainDetails.ChainSelector) } diff --git a/e2e/tests/solana/common.go b/e2e/tests/solana/common.go index 0d1e8450b..b749b5dc3 100644 --- a/e2e/tests/solana/common.go +++ b/e2e/tests/solana/common.go @@ -14,7 +14,8 @@ import ( "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" - cselectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" + chainselremote "github.com/smartcontractkit/chain-selectors/remote" "go.uber.org/zap" @@ -123,7 +124,7 @@ func (s *TestSuite) SetupSuite() { s.AccessControllerProgramID = solana.MustPublicKeyFromBase58(s.SolanaChain.SolanaPrograms["access_controller"]) s.CPIStubProgramID = solana.MustPublicKeyFromBase58(s.SolanaChain.SolanaPrograms["external_program_cpi_stub"]) - details, err := cselectors.GetChainDetailsByChainIDAndFamily(s.SolanaChain.ChainID, cselectors.FamilySolana) + details, err := chainselremote.GetChainDetailsByChainIDAndFamily(s.T().Context(), s.SolanaChain.ChainID, chainsel.FamilySolana) s.Require().NoError(err) s.ChainSelector = types.ChainSelector(details.ChainSelector) } diff --git a/e2e/tests/sui/common.go b/e2e/tests/sui/common.go index 8aa36fb2f..86721f5d4 100644 --- a/e2e/tests/sui/common.go +++ b/e2e/tests/sui/common.go @@ -10,7 +10,7 @@ import ( "github.com/block-vision/sui-go-sdk/transaction" "github.com/stretchr/testify/suite" - cselectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/chainlink-sui/bindings/bind" modulemcms "github.com/smartcontractkit/chainlink-sui/bindings/generated/mcms/mcms" @@ -77,7 +77,7 @@ func (s *TestSuite) SetupSuite() { s.client = s.SuiClient // TODO: Find funded accounts s.signer = testSigner - s.chainSelector = types.ChainSelector(cselectors.SUI_TESTNET.Selector) + s.chainSelector = types.ChainSelector(chainsel.SUI_TESTNET.Selector) } func (s *TestSuite) DeployMCMSContract() { diff --git a/e2e/tests/ton/executable.go b/e2e/tests/ton/executable.go index edc9c4a2b..686b3ff01 100644 --- a/e2e/tests/ton/executable.go +++ b/e2e/tests/ton/executable.go @@ -11,7 +11,8 @@ import ( "github.com/stretchr/testify/suite" - cselectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" + chainselremote "github.com/smartcontractkit/chain-selectors/remote" "github.com/xssnick/tonutils-go/address" "github.com/xssnick/tonutils-go/tlb" @@ -72,12 +73,12 @@ func (s *ExecutionTestSuite) SetupSuite() { s.signers = testutils.MakeNewECDSASigners(2) // Initialize chains - details, err := cselectors.GetChainDetailsByChainIDAndFamily(s.TonBlockchain.ChainID, s.TonBlockchain.Family) + details, err := chainselremote.GetChainDetailsByChainIDAndFamily(s.T().Context(), s.TonBlockchain.ChainID, s.TonBlockchain.Family) s.Require().NoError(err) s.ChainA = types.ChainSelector(details.ChainSelector) - s.ChainB = types.ChainSelector(cselectors.GETH_TESTNET.Selector) - s.ChainC = types.ChainSelector(cselectors.GETH_DEVNET_2.Selector) + s.ChainB = types.ChainSelector(chainsel.GETH_TESTNET.Selector) + s.ChainC = types.ChainSelector(chainsel.GETH_DEVNET_2.Selector) // Deploy contracts on chain A (the one we execute on) s.deployMCMSContract(hash.CRC32("test.executable.mcms")) diff --git a/e2e/tests/ton/set_root.go b/e2e/tests/ton/set_root.go index 04920cd28..b8699192d 100644 --- a/e2e/tests/ton/set_root.go +++ b/e2e/tests/ton/set_root.go @@ -9,7 +9,7 @@ import ( "github.com/stretchr/testify/suite" - cselectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/chainlink-ton/pkg/bindings/mcms/mcms" "github.com/smartcontractkit/chainlink-ton/pkg/ton/hash" @@ -69,7 +69,7 @@ func (s *SetRootTestSuite) SetupSuite() { s.deployMCMSContract() - chainDetails, err := cselectors.GetChainDetailsByChainIDAndFamily(s.TonBlockchain.ChainID, s.TonBlockchain.Family) + chainDetails, err := chainsel.GetChainDetailsByChainIDAndFamily(s.TonBlockchain.ChainID, s.TonBlockchain.Family) s.Require().NoError(err) s.chainSelector = types.ChainSelector(chainDetails.ChainSelector) } diff --git a/e2e/tests/ton/timelock_inspection.go b/e2e/tests/ton/timelock_inspection.go index edd61e461..1e1475099 100644 --- a/e2e/tests/ton/timelock_inspection.go +++ b/e2e/tests/ton/timelock_inspection.go @@ -14,7 +14,7 @@ import ( "github.com/ethereum/go-ethereum/common" - cselectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/xssnick/tonutils-go/address" "github.com/xssnick/tonutils-go/tlb" @@ -381,7 +381,7 @@ func (s *TimelockInspectionTestSuite) TestIsOperationDone() { s.Require().NoError(err, "Failed to create TimelockExecutor") bop := types.BatchOperation{ - ChainSelector: types.ChainSelector(cselectors.TON_LOCALNET.Selector), + ChainSelector: types.ChainSelector(chainsel.TON_LOCALNET.Selector), Transactions: []types.Transaction{ { To: counterAddr.String(), diff --git a/factory.go b/factory.go index 37cc1cb1a..0abc9b1aa 100644 --- a/factory.go +++ b/factory.go @@ -3,7 +3,7 @@ package mcms import ( "fmt" - cselectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/mcms/sdk" "github.com/smartcontractkit/mcms/sdk/aptos" @@ -27,33 +27,33 @@ func newEncoder( var encoder sdk.Encoder switch family { - case cselectors.FamilyEVM: + case chainsel.FamilyEVM: encoder = evm.NewEncoder( csel, txCount, overridePreviousRoot, isSim, ) - case cselectors.FamilySolana: + case chainsel.FamilySolana: encoder = solana.NewEncoder( csel, txCount, overridePreviousRoot, // isSim, ) - case cselectors.FamilyAptos: + case chainsel.FamilyAptos: encoder = aptos.NewEncoder( csel, txCount, overridePreviousRoot, ) - case cselectors.FamilySui: + case chainsel.FamilySui: encoder = sui.NewEncoder( csel, txCount, overridePreviousRoot, ) - case cselectors.FamilyTon: + case chainsel.FamilyTon: encoder = ton.NewEncoder( csel, txCount, @@ -73,19 +73,19 @@ func newTimelockConverter(csel types.ChainSelector) (sdk.TimelockConverter, erro } switch family { - case cselectors.FamilyEVM: + case chainsel.FamilyEVM: return &evm.TimelockConverter{}, nil - case cselectors.FamilySolana: + case chainsel.FamilySolana: return &solana.TimelockConverter{}, nil - case cselectors.FamilyAptos: + case chainsel.FamilyAptos: return aptos.NewTimelockConverter(), nil - case cselectors.FamilySui: + case chainsel.FamilySui: return &sui.TimelockConverter{}, nil - case cselectors.FamilyTon: + case chainsel.FamilyTon: // Notice: we need to define the send amount from MCMS to Timelock, // to cover gas fees. We use a static default value here for now. return ton.NewTimelockConverter(ton.DefaultSendAmount), nil diff --git a/internal/testutils/chaintest/testchain.go b/internal/testutils/chaintest/testchain.go index 0c27fb075..d786ec86f 100644 --- a/internal/testutils/chaintest/testchain.go +++ b/internal/testutils/chaintest/testchain.go @@ -1,39 +1,39 @@ package chaintest import ( - cselectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/mcms/types" ) var ( - Chain1RawSelector = cselectors.GETH_TESTNET.Selector // 3379446385462418246 + Chain1RawSelector = chainsel.GETH_TESTNET.Selector // 3379446385462418246 Chain1Selector = types.ChainSelector(Chain1RawSelector) // 3379446385462418246 - Chain1EVMID = cselectors.GETH_TESTNET.EvmChainID // 1337 + Chain1EVMID = chainsel.GETH_TESTNET.EvmChainID // 1337 - Chain2RawSelector = cselectors.ETHEREUM_TESTNET_SEPOLIA.Selector // 16015286601757825753 - Chain2Selector = types.ChainSelector(Chain2RawSelector) // 16015286601757825753 - Chain2EVMID = cselectors.ETHEREUM_TESTNET_SEPOLIA.EvmChainID // 11155111 + Chain2RawSelector = chainsel.ETHEREUM_TESTNET_SEPOLIA.Selector // 16015286601757825753 + Chain2Selector = types.ChainSelector(Chain2RawSelector) // 16015286601757825753 + Chain2EVMID = chainsel.ETHEREUM_TESTNET_SEPOLIA.EvmChainID // 11155111 - Chain3RawSelector = cselectors.ETHEREUM_TESTNET_SEPOLIA_BASE_1.Selector // 10344971235874465080 - Chain3Selector = types.ChainSelector(Chain3RawSelector) // 10344971235874465080 - Chain3EVMID = cselectors.ETHEREUM_TESTNET_SEPOLIA_BASE_1.EvmChainID // 84532 + Chain3RawSelector = chainsel.ETHEREUM_TESTNET_SEPOLIA_BASE_1.Selector // 10344971235874465080 + Chain3Selector = types.ChainSelector(Chain3RawSelector) // 10344971235874465080 + Chain3EVMID = chainsel.ETHEREUM_TESTNET_SEPOLIA_BASE_1.EvmChainID // 84532 - Chain4RawSelector = cselectors.SOLANA_DEVNET.Selector // 16423721717087811551 + Chain4RawSelector = chainsel.SOLANA_DEVNET.Selector // 16423721717087811551 Chain4Selector = types.ChainSelector(Chain4RawSelector) // 16423721717087811551 - Chain4SolanaID = cselectors.SOLANA_DEVNET.ChainID // EtWTRABZaYq6iMfeYKouRu166VU2xqa1wcaWoxPkrZBG + Chain4SolanaID = chainsel.SOLANA_DEVNET.ChainID // EtWTRABZaYq6iMfeYKouRu166VU2xqa1wcaWoxPkrZBG - Chain5RawSelector = cselectors.APTOS_TESTNET.Selector + Chain5RawSelector = chainsel.APTOS_TESTNET.Selector Chain5Selector = types.ChainSelector(Chain5RawSelector) - Chain5AptosID = cselectors.APTOS_TESTNET.ChainID + Chain5AptosID = chainsel.APTOS_TESTNET.ChainID - Chain6RawSelector = cselectors.SUI_TESTNET.Selector + Chain6RawSelector = chainsel.SUI_TESTNET.Selector Chain6Selector = types.ChainSelector(Chain6RawSelector) - Chain6SuiID = cselectors.SUI_TESTNET.ChainID + Chain6SuiID = chainsel.SUI_TESTNET.ChainID - Chain7RawSelector = cselectors.TON_TESTNET.Selector + Chain7RawSelector = chainsel.TON_TESTNET.Selector Chain7Selector = types.ChainSelector(Chain7RawSelector) - Chain7TONID = cselectors.TON_TESTNET.ChainID + Chain7TONID = chainsel.TON_TESTNET.ChainID // ChainInvalidSelector is a chain selector that doesn't exist. ChainInvalidSelector = types.ChainSelector(0) diff --git a/sdk/aptos/configurer.go b/sdk/aptos/configurer.go index 46d6e3e48..e96e54d6e 100644 --- a/sdk/aptos/configurer.go +++ b/sdk/aptos/configurer.go @@ -4,7 +4,7 @@ import ( "context" "fmt" - chain_selectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/aptos-labs/aptos-go-sdk" @@ -103,7 +103,7 @@ func (c Configurer) SetConfig(ctx context.Context, mcmsAddr string, cfg *types.C return types.TransactionResult{ Hash: "", // Returning no hash since the transaction hasn't been sent yet. - ChainFamily: chain_selectors.FamilyAptos, + ChainFamily: chainsel.FamilyAptos, RawData: tx, // will be of type types.Transaction }, nil } @@ -123,7 +123,7 @@ func (c Configurer) SetConfig(ctx context.Context, mcmsAddr string, cfg *types.C return types.TransactionResult{ Hash: tx.Hash, - ChainFamily: chain_selectors.FamilyAptos, + ChainFamily: chainsel.FamilyAptos, RawData: tx, // will be of type *api.PendingTransaction }, nil } diff --git a/sdk/aptos/configurer_test.go b/sdk/aptos/configurer_test.go index 1bab8f3af..e7d99e193 100644 --- a/sdk/aptos/configurer_test.go +++ b/sdk/aptos/configurer_test.go @@ -13,7 +13,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - cselectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/chainlink-aptos/bindings/bind" "github.com/smartcontractkit/chainlink-aptos/bindings/mcms" @@ -115,7 +115,7 @@ func TestConfigurer_SetConfig(t *testing.T) { }, want: types.TransactionResult{ Hash: "0x123456789", - ChainFamily: cselectors.FamilyAptos, + ChainFamily: chainsel.FamilyAptos, RawData: &api.PendingTransaction{ Hash: "0x123456789", }, @@ -215,7 +215,7 @@ func TestConfigurer_SetConfig(t *testing.T) { }, want: types.TransactionResult{ Hash: "", // Hash is empty when not sending transaction - ChainFamily: cselectors.FamilyAptos, + ChainFamily: chainsel.FamilyAptos, RawData: types.Transaction{ OperationMetadata: types.OperationMetadata{}, To: mustHexToAddress("0x1234").StringLong(), diff --git a/sdk/aptos/encoder.go b/sdk/aptos/encoder.go index 4caed209f..d98916944 100644 --- a/sdk/aptos/encoder.go +++ b/sdk/aptos/encoder.go @@ -9,7 +9,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" - chain_selectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/mcms/sdk" "github.com/smartcontractkit/mcms/types" @@ -41,7 +41,7 @@ func NewEncoder( } func (e *Encoder) HashOperation(opCount uint32, metadata types.ChainMetadata, op types.Operation) (common.Hash, error) { - chainID, err := chain_selectors.AptosChainIdFromSelector(uint64(e.ChainSelector)) + chainID, err := chainsel.AptosChainIdFromSelector(uint64(e.ChainSelector)) if err != nil { return common.Hash{}, err } @@ -80,7 +80,7 @@ func (e *Encoder) HashOperation(opCount uint32, metadata types.ChainMetadata, op } func (e *Encoder) HashMetadata(metadata types.ChainMetadata) (common.Hash, error) { - chainID, err := chain_selectors.AptosChainIdFromSelector(uint64(e.ChainSelector)) + chainID, err := chainsel.AptosChainIdFromSelector(uint64(e.ChainSelector)) if err != nil { return common.Hash{}, err } diff --git a/sdk/aptos/executor.go b/sdk/aptos/executor.go index f26bd9631..4595b6c57 100644 --- a/sdk/aptos/executor.go +++ b/sdk/aptos/executor.go @@ -11,7 +11,8 @@ import ( "github.com/aptos-labs/aptos-go-sdk/api" "github.com/ethereum/go-ethereum/common" - chain_selectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" + "github.com/smartcontractkit/chainlink-aptos/bindings/bind" "github.com/smartcontractkit/chainlink-aptos/bindings/mcms" @@ -73,7 +74,7 @@ func (e Executor) ExecuteOperation( return types.TransactionResult{}, fmt.Errorf("failed to unmarshal additional fields metadata: %w", err) } } - chainID, err := chain_selectors.AptosChainIdFromSelector(uint64(e.ChainSelector)) + chainID, err := chainsel.AptosChainIdFromSelector(uint64(e.ChainSelector)) if err != nil { return types.TransactionResult{}, err } @@ -161,7 +162,7 @@ func (e Executor) ExecuteOperation( return types.TransactionResult{ Hash: tx.Hash, - ChainFamily: chain_selectors.FamilyAptos, + ChainFamily: chainsel.FamilyAptos, RawData: tx, }, nil } @@ -185,7 +186,7 @@ func (e Executor) SetRoot( return types.TransactionResult{}, fmt.Errorf("failed to unmarshal additional fields metadata: %w", err) } } - chainID, err := chain_selectors.AptosChainIdFromSelector(uint64(e.ChainSelector)) + chainID, err := chainsel.AptosChainIdFromSelector(uint64(e.ChainSelector)) if err != nil { return types.TransactionResult{}, err } @@ -218,7 +219,7 @@ func (e Executor) SetRoot( return types.TransactionResult{ Hash: tx.Hash, - ChainFamily: chain_selectors.FamilyAptos, + ChainFamily: chainsel.FamilyAptos, RawData: tx, }, nil } diff --git a/sdk/aptos/executor_test.go b/sdk/aptos/executor_test.go index 72ebb52cd..361dc989b 100644 --- a/sdk/aptos/executor_test.go +++ b/sdk/aptos/executor_test.go @@ -15,7 +15,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - cselectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/chainlink-aptos/bindings/bind" "github.com/smartcontractkit/chainlink-aptos/bindings/mcms" @@ -95,7 +95,7 @@ func TestExecutor_ExecuteOperation(t *testing.T) { }, want: types.TransactionResult{ Hash: "0xdeadbeef", - ChainFamily: cselectors.FamilyAptos, + ChainFamily: chainsel.FamilyAptos, RawData: &api.PendingTransaction{Hash: "0xdeadbeef"}, }, wantErr: assert.NoError, @@ -159,7 +159,7 @@ func TestExecutor_ExecuteOperation(t *testing.T) { }, want: types.TransactionResult{ Hash: "0xdeadbeef3", - ChainFamily: cselectors.FamilyAptos, + ChainFamily: chainsel.FamilyAptos, RawData: &api.PendingTransaction{Hash: "0xdeadbeef3"}, }, wantErr: assert.NoError, @@ -465,7 +465,7 @@ func TestExecutor_SetRoot(t *testing.T) { }, want: types.TransactionResult{ Hash: "0x111111", - ChainFamily: cselectors.FamilyAptos, + ChainFamily: chainsel.FamilyAptos, RawData: &api.PendingTransaction{Hash: "0x111111"}, }, wantErr: assert.NoError, diff --git a/sdk/aptos/timelock_executor.go b/sdk/aptos/timelock_executor.go index 2464b43f8..6d1017650 100644 --- a/sdk/aptos/timelock_executor.go +++ b/sdk/aptos/timelock_executor.go @@ -8,7 +8,7 @@ import ( "github.com/smartcontractkit/mcms/sdk" "github.com/smartcontractkit/mcms/types" - chain_selectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/ethereum/go-ethereum/common" @@ -78,7 +78,7 @@ func (t *TimelockExecutor) Execute( return types.TransactionResult{ Hash: tx.Hash, - ChainFamily: chain_selectors.FamilyAptos, + ChainFamily: chainsel.FamilyAptos, RawData: tx, }, nil } diff --git a/sdk/aptos/timelock_executor_test.go b/sdk/aptos/timelock_executor_test.go index 5c5006eb5..484d39372 100644 --- a/sdk/aptos/timelock_executor_test.go +++ b/sdk/aptos/timelock_executor_test.go @@ -9,7 +9,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - cselectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/mcms/internal/testutils/chaintest" "github.com/smartcontractkit/mcms/types" @@ -95,7 +95,7 @@ func TestExecutor_Execute(t *testing.T) { }, want: types.TransactionResult{ Hash: "0xcoffee", - ChainFamily: cselectors.FamilyAptos, + ChainFamily: chainsel.FamilyAptos, RawData: &api.PendingTransaction{Hash: "0xcoffee"}, }, wantErr: assert.NoError, diff --git a/sdk/evm/configurer.go b/sdk/evm/configurer.go index 9cbbc39f0..ceaeb809f 100644 --- a/sdk/evm/configurer.go +++ b/sdk/evm/configurer.go @@ -6,7 +6,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" - chain_selectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/mcms/sdk" "github.com/smartcontractkit/mcms/sdk/evm/bindings" @@ -59,7 +59,7 @@ func (c *Configurer) SetConfig(ctx context.Context, mcmAddr string, cfg *types.C return types.TransactionResult{ Hash: tx.Hash().Hex(), - ChainFamily: chain_selectors.FamilyEVM, + ChainFamily: chainsel.FamilyEVM, RawData: tx, }, nil } diff --git a/sdk/evm/encoder.go b/sdk/evm/encoder.go index 778baacea..f005356d0 100644 --- a/sdk/evm/encoder.go +++ b/sdk/evm/encoder.go @@ -1,6 +1,7 @@ package evm import ( + "context" "encoding/json" "math/big" @@ -95,7 +96,10 @@ func (e *Encoder) ToGethOperation( metadata types.ChainMetadata, op types.Operation, ) (bindings.ManyChainMultiSigOp, error) { - evmChainID, err := getEVMChainID(e.ChainSelector, e.IsSim) + + // TODO: passing this as param requires a breaking change to the Encoder interfaces + // which requires changes too all chain specific SDKs. Consider refactoring later. + evmChainID, err := getEVMChainID(context.Background(), e.ChainSelector, e.IsSim) if err != nil { return bindings.ManyChainMultiSigOp{}, err } @@ -119,7 +123,9 @@ func (e *Encoder) ToGethOperation( // ToGethRootMetadata converts the MCMS ChainMetadata into the format expected by the EVM // ManyChainMultiSig contract. func (e *Encoder) ToGethRootMetadata(metadata types.ChainMetadata) (bindings.ManyChainMultiSigRootMetadata, error) { - evmChainID, err := getEVMChainID(e.ChainSelector, e.IsSim) + // TODO: passing this as param requires a breaking change to the Encoder interfaces + // which requires changes too all chain specific SDKs. Consider refactoring later. + evmChainID, err := getEVMChainID(context.Background(), e.ChainSelector, e.IsSim) if err != nil { return bindings.ManyChainMultiSigRootMetadata{}, err } diff --git a/sdk/evm/encoder_test.go b/sdk/evm/encoder_test.go index 0583fcee8..e5bb65e4f 100644 --- a/sdk/evm/encoder_test.go +++ b/sdk/evm/encoder_test.go @@ -7,7 +7,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - cselectors "github.com/smartcontractkit/chain-selectors" + chainselremote "github.com/smartcontractkit/chain-selectors/remote" "github.com/ethereum/go-ethereum/common" @@ -124,10 +124,12 @@ func TestEncoder_HashMetadata(t *testing.T) { func TestEncoder_ToGethOperation(t *testing.T) { t.Parallel() - + mapsels, err := chainselremote.EvmChainIdToChainSelector(t.Context()) + require.NoError(t, err) var ( - evmChainID = uint64(1) - chainSelector = types.ChainSelector(cselectors.EvmChainIdToChainSelector()[evmChainID]) + evmChainID = uint64(1) + + chainSelector = types.ChainSelector(mapsels[evmChainID]) // Static argument values to ToGethOperation since they don't affect the test giveOpCount = uint32(0) diff --git a/sdk/evm/executor.go b/sdk/evm/executor.go index 2cc3e5564..c091f9fa0 100644 --- a/sdk/evm/executor.go +++ b/sdk/evm/executor.go @@ -10,7 +10,7 @@ import ( "github.com/ethereum/go-ethereum/common" gethtypes "github.com/ethereum/go-ethereum/core/types" - chain_selectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/mcms/sdk/evm/bindings" "github.com/smartcontractkit/mcms/types" @@ -72,13 +72,13 @@ func (e *Executor) ExecuteOperation( execErr := BuildExecutionError(ctx, err, txPreview, &opts, mcmsAddr, e.client, timelockAddr, timelockCallData) return types.TransactionResult{ - ChainFamily: chain_selectors.FamilyEVM, + ChainFamily: chainsel.FamilyEVM, }, execErr } return types.TransactionResult{ Hash: tx.Hash().Hex(), - ChainFamily: chain_selectors.FamilyEVM, + ChainFamily: chainsel.FamilyEVM, RawData: tx, }, err } @@ -135,13 +135,13 @@ func (e *Executor) SetRoot( // SetRoot doesn't involve timelock, so pass empty values execErr := BuildExecutionError(ctx, err, txPreview, &opts, mcmsAddr, e.client, common.Address{}, nil) return types.TransactionResult{ - ChainFamily: chain_selectors.FamilyEVM, + ChainFamily: chainsel.FamilyEVM, }, execErr } return types.TransactionResult{ Hash: tx.Hash().Hex(), - ChainFamily: chain_selectors.FamilyEVM, + ChainFamily: chainsel.FamilyEVM, RawData: tx, }, err } diff --git a/sdk/evm/executor_test.go b/sdk/evm/executor_test.go index 828a8e22a..b0fd6bcab 100644 --- a/sdk/evm/executor_test.go +++ b/sdk/evm/executor_test.go @@ -14,7 +14,7 @@ import ( "github.com/ethereum/go-ethereum/common" evmTypes "github.com/ethereum/go-ethereum/core/types" - chain_selectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/mcms/internal/testutils/chaintest" "github.com/smartcontractkit/mcms/sdk/evm" @@ -202,7 +202,7 @@ func TestExecutor_ExecuteOperation(t *testing.T) { require.ErrorAs(t, err, &execErr, errMsgExecErrType) if execErr != nil { require.NotNil(t, execErr.Transaction, errMsgExecErrTxData) - require.Equal(t, chain_selectors.FamilyEVM, tx.ChainFamily) + require.Equal(t, chainsel.FamilyEVM, tx.ChainFamily) } } else { // For other errors, just check the error message matches @@ -276,7 +276,7 @@ func TestExecutor_ExecuteOperationWithEIP1559GasFees(t *testing.T) { require.ErrorAs(t, err, &execErr, errMsgExecErrType) require.NotNil(t, execErr, errMsgExecErrNotNil) require.NotNil(t, execErr.Transaction, errMsgExecErrTxData) - require.Equal(t, chain_selectors.FamilyEVM, tx.ChainFamily) + require.Equal(t, chainsel.FamilyEVM, tx.ChainFamily) // Verify it's a DynamicFeeTx (EIP-1559) require.Equal(t, uint8(2), execErr.Transaction.Type(), "transaction should be EIP-1559 type") } @@ -336,7 +336,7 @@ func TestExecutor_SetRootWithEIP1559GasFees(t *testing.T) { require.ErrorAs(t, err, &execErr, errMsgExecErrType) require.NotNil(t, execErr, errMsgExecErrNotNil) require.NotNil(t, execErr.Transaction, errMsgExecErrTxData) - require.Equal(t, chain_selectors.FamilyEVM, tx.ChainFamily) + require.Equal(t, chainsel.FamilyEVM, tx.ChainFamily) // Verify it's a DynamicFeeTx (EIP-1559) require.Equal(t, uint8(2), execErr.Transaction.Type(), "transaction should be EIP-1559 type") } @@ -400,7 +400,7 @@ func TestExecutor_ExecuteOperationWithLegacyGasPrice(t *testing.T) { require.ErrorAs(t, err, &execErr, errMsgExecErrType) require.NotNil(t, execErr, errMsgExecErrNotNil) require.NotNil(t, execErr.Transaction, errMsgExecErrTxData) - require.Equal(t, chain_selectors.FamilyEVM, tx.ChainFamily) + require.Equal(t, chainsel.FamilyEVM, tx.ChainFamily) // Verify it's a LegacyTx require.Equal(t, uint8(0), execErr.Transaction.Type(), "transaction should be legacy type") } @@ -459,7 +459,7 @@ func TestExecutor_SetRootWithLegacyGasPrice(t *testing.T) { require.ErrorAs(t, err, &execErr, errMsgExecErrType) require.NotNil(t, execErr, errMsgExecErrNotNil) require.NotNil(t, execErr.Transaction, errMsgExecErrTxData) - require.Equal(t, chain_selectors.FamilyEVM, tx.ChainFamily) + require.Equal(t, chainsel.FamilyEVM, tx.ChainFamily) // Verify it's a LegacyTx require.Equal(t, uint8(0), execErr.Transaction.Type(), "transaction should be legacy type") } @@ -691,7 +691,7 @@ func TestExecutor_SetRoot(t *testing.T) { require.ErrorAs(t, err, &execErr, errMsgExecErrType) if execErr != nil { require.NotNil(t, execErr.Transaction, errMsgExecErrTxData) - require.Equal(t, chain_selectors.FamilyEVM, tx.ChainFamily) + require.Equal(t, chainsel.FamilyEVM, tx.ChainFamily) } } else { require.EqualError(t, err, tt.wantErr.Error()) diff --git a/sdk/evm/timelock_converter_test.go b/sdk/evm/timelock_converter_test.go index 30c6199c5..c225a8271 100644 --- a/sdk/evm/timelock_converter_test.go +++ b/sdk/evm/timelock_converter_test.go @@ -7,7 +7,7 @@ import ( "github.com/stretchr/testify/require" - cselectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/ethereum/go-ethereum/common" @@ -45,7 +45,7 @@ func TestTimelockConverter_ConvertBatchToChainOperation(t *testing.T) { []string{"tag1", "tag2"}, ), }, - ChainSelector: types.ChainSelector(cselectors.ETHEREUM_TESTNET_SEPOLIA.Selector), + ChainSelector: types.ChainSelector(chainsel.ETHEREUM_TESTNET_SEPOLIA.Selector), }, delay: "1h", operation: types.TimelockActionSchedule, @@ -65,7 +65,7 @@ func TestTimelockConverter_ConvertBatchToChainOperation(t *testing.T) { []string{"tag1", "tag2"}, ), }, - ChainSelector: types.ChainSelector(cselectors.ETHEREUM_TESTNET_SEPOLIA.Selector), + ChainSelector: types.ChainSelector(chainsel.ETHEREUM_TESTNET_SEPOLIA.Selector), }, delay: "1h", operation: types.TimelockActionCancel, @@ -85,7 +85,7 @@ func TestTimelockConverter_ConvertBatchToChainOperation(t *testing.T) { []string{"tag1", "tag2"}, ), }, - ChainSelector: types.ChainSelector(cselectors.ETHEREUM_TESTNET_SEPOLIA.Selector), + ChainSelector: types.ChainSelector(chainsel.ETHEREUM_TESTNET_SEPOLIA.Selector), }, delay: "1h", operation: types.TimelockAction("invalid"), @@ -103,7 +103,7 @@ func TestTimelockConverter_ConvertBatchToChainOperation(t *testing.T) { Data: []byte("0x1234"), AdditionalFields: []byte("invalid"), }}, - ChainSelector: types.ChainSelector(cselectors.ETHEREUM_TESTNET_SEPOLIA.Selector), + ChainSelector: types.ChainSelector(chainsel.ETHEREUM_TESTNET_SEPOLIA.Selector), }, delay: "1h", operation: types.TimelockActionSchedule, diff --git a/sdk/evm/timelock_executor.go b/sdk/evm/timelock_executor.go index 7bade02e7..cb6b316dd 100644 --- a/sdk/evm/timelock_executor.go +++ b/sdk/evm/timelock_executor.go @@ -9,7 +9,7 @@ import ( "github.com/ethereum/go-ethereum/common" gethtypes "github.com/ethereum/go-ethereum/core/types" - chain_selectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/mcms/sdk" "github.com/smartcontractkit/mcms/sdk/evm/bindings" @@ -76,13 +76,13 @@ func (t *TimelockExecutor) Execute( execErr := BuildExecutionError(ctx, err, txPreview, &opts, timelockAddr, t.client, timelockAddr, timelockCallData) return types.TransactionResult{ - ChainFamily: chain_selectors.FamilyEVM, + ChainFamily: chainsel.FamilyEVM, }, execErr } return types.TransactionResult{ Hash: tx.Hash().Hex(), - ChainFamily: chain_selectors.FamilyEVM, + ChainFamily: chainsel.FamilyEVM, RawData: tx, }, nil } diff --git a/sdk/evm/utils.go b/sdk/evm/utils.go index 05bab6f6c..5a6e3538f 100644 --- a/sdk/evm/utils.go +++ b/sdk/evm/utils.go @@ -1,9 +1,12 @@ package evm import ( + "context" + "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" - cselectors "github.com/smartcontractkit/chain-selectors" + + chainselremote "github.com/smartcontractkit/chain-selectors/remote" sdkerrors "github.com/smartcontractkit/mcms/sdk/errors" "github.com/smartcontractkit/mcms/types" @@ -63,17 +66,17 @@ func toGethSignature(s types.Signature) bindings.ManyChainMultiSigSignature { // To support simulated chains in testing, the isSim flag can be set to true. Simulated chains // always have EVM chain ID of 1337. We need to override the chain ID for setRoot to execute and // not throw WrongChainId. -func getEVMChainID(sel types.ChainSelector, isSim bool) (uint64, error) { +func getEVMChainID(ctx context.Context, sel types.ChainSelector, isSim bool) (uint64, error) { if isSim { return SimulatedEVMChainID, nil } - evmChainID, err := cselectors.ChainIdFromSelector(uint64(sel)) + evmChain, _, err := chainselremote.EvmChainBySelector(ctx, uint64(sel)) if err != nil { return 0, &sdkerrors.InvalidChainIDError{ ReceivedChainID: sel, } } - return evmChainID, nil + return evmChain.EvmChainID, nil } diff --git a/sdk/evm/utils_test.go b/sdk/evm/utils_test.go index 582bc459b..f89858642 100644 --- a/sdk/evm/utils_test.go +++ b/sdk/evm/utils_test.go @@ -160,7 +160,7 @@ func TestGetEVMChainID(t *testing.T) { t.Run(tt.name, func(t *testing.T) { t.Parallel() - got, err := getEVMChainID(tt.giveSel, tt.giveIsSim) + got, err := getEVMChainID(t.Context(), tt.giveSel, tt.giveIsSim) if tt.wantErr { require.Error(t, err) } else { diff --git a/sdk/solana/common_test.go b/sdk/solana/common_test.go index 11d5dd83e..c75073e96 100644 --- a/sdk/solana/common_test.go +++ b/sdk/solana/common_test.go @@ -9,7 +9,7 @@ import ( "github.com/smartcontractkit/mcms/types" - cselectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/ethereum/go-ethereum/common" "github.com/google/go-cmp/cmp" @@ -25,7 +25,7 @@ import ( ) var ( - testChainSelector = types.ChainSelector(cselectors.SOLANA_DEVNET.Selector) + testChainSelector = types.ChainSelector(chainsel.SOLANA_DEVNET.Selector) testTimelockProgramID = solana.MustPublicKeyFromBase58("LoCoNsJFuhTkSQjfdDfn3yuwqhSYoPujmviRHVCzsqn") testMCMProgramID = solana.MustPublicKeyFromBase58("6UmMZr5MEqiKWD5jqTJd1WCR5kT8oZuFYBLJFi1o6GQX") testCPIStubProgramID = solana.MustPublicKeyFromBase58("4HeqEoSyfYpeC2goFLj9eHgkxV33mR5G7JYAbRsN14uQ") diff --git a/sdk/solana/configurer.go b/sdk/solana/configurer.go index 29bfb1283..98b4d3630 100644 --- a/sdk/solana/configurer.go +++ b/sdk/solana/configurer.go @@ -4,7 +4,7 @@ import ( "context" "fmt" - chain_selectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" evmCommon "github.com/ethereum/go-ethereum/common" @@ -152,7 +152,7 @@ func (c *Configurer) SetConfig( return types.TransactionResult{ Hash: signature, - ChainFamily: chain_selectors.FamilySolana, + ChainFamily: chainsel.FamilySolana, RawData: c.solanaInstructions(), }, nil } diff --git a/sdk/solana/configurer_test.go b/sdk/solana/configurer_test.go index 033e20030..65680d38c 100644 --- a/sdk/solana/configurer_test.go +++ b/sdk/solana/configurer_test.go @@ -7,7 +7,7 @@ import ( "github.com/stretchr/testify/require" - cselectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/ethereum/go-ethereum/common" @@ -30,7 +30,7 @@ func TestNewConfigurer(t *testing.T) { client := &rpc.Client{} auth := solana.MustPrivateKeyFromBase58("DmPfeHBC8Brf8s5qQXi25bmJ996v6BHRtaLc6AH51yFGSqQpUMy1oHkbbXobPNBdgGH2F29PAmoq9ZZua4K9vCc") - chainSelector := types.ChainSelector(cselectors.SOLANA_DEVNET.Selector) + chainSelector := types.ChainSelector(chainsel.SOLANA_DEVNET.Selector) newAuthorityAccount := solana.NewWallet().PublicKey() @@ -79,7 +79,7 @@ func TestNewConfigurer(t *testing.T) { func TestConfigurer_SetConfig(t *testing.T) { //nolint:paralleltest // https://github.com/kunwardeep/paralleltest/issues/49 ctx := context.Background() - chainSelector := types.ChainSelector(cselectors.SOLANA_DEVNET.Selector) + chainSelector := types.ChainSelector(chainsel.SOLANA_DEVNET.Selector) auth, err := solana.NewRandomPrivateKey() require.NoError(t, err) defaultMcmConfig := &types.Config{Quorum: 1, Signers: []common.Address{common.HexToAddress("0x1")}} diff --git a/sdk/solana/executor.go b/sdk/solana/executor.go index b201b39df..9dd1ed4f7 100644 --- a/sdk/solana/executor.go +++ b/sdk/solana/executor.go @@ -7,7 +7,7 @@ import ( "math" "regexp" - chain_selectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/mcms/sdk" "github.com/smartcontractkit/mcms/types" @@ -121,7 +121,7 @@ func (e *Executor) ExecuteOperation( return types.TransactionResult{ Hash: signature, - ChainFamily: chain_selectors.FamilySolana, + ChainFamily: chainsel.FamilySolana, RawData: tx, }, nil } @@ -202,7 +202,7 @@ func (e *Executor) SetRoot( return types.TransactionResult{ Hash: signature, - ChainFamily: chain_selectors.FamilySolana, + ChainFamily: chainsel.FamilySolana, RawData: tx, }, nil } diff --git a/sdk/solana/executor_test.go b/sdk/solana/executor_test.go index e66face6b..99278322f 100644 --- a/sdk/solana/executor_test.go +++ b/sdk/solana/executor_test.go @@ -10,7 +10,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - cselectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/ethereum/go-ethereum/common" "github.com/google/go-cmp/cmp" @@ -31,7 +31,7 @@ func TestNewExecutor(t *testing.T) { client := &rpc.Client{} auth := solana.MustPrivateKeyFromBase58("DmPfeHBC8Brf8s5qQXi25bmJ996v6BHRtaLc6AH51yFGSqQpUMy1oHkbbXobPNBdgGH2F29PAmoq9ZZua4K9vCc") - chainSelector := types.ChainSelector(cselectors.SOLANA_DEVNET.Selector) + chainSelector := types.ChainSelector(chainsel.SOLANA_DEVNET.Selector) encoder := NewEncoder(chainSelector, 1, false) executor := NewExecutor(encoder, client, auth) @@ -46,7 +46,7 @@ func TestExecutor_ExecuteOperation(t *testing.T) { //nolint:paralleltest proof []common.Hash op types.Operation } - selector := cselectors.SOLANA_DEVNET.Selector + selector := chainsel.SOLANA_DEVNET.Selector auth, err := solana.PrivateKeyFromBase58(dummyPrivateKey) require.NoError(t, err) contractID := fmt.Sprintf("%s.%s", testMCMProgramID.String(), testPDASeed) @@ -186,7 +186,7 @@ func TestExecutor_ExecuteOperation(t *testing.T) { //nolint:paralleltest func TestExecutor_SetRoot(t *testing.T) { //nolint:paralleltest ctx := context.Background() - chainSelector := types.ChainSelector(cselectors.SOLANA_DEVNET.Selector) + chainSelector := types.ChainSelector(chainsel.SOLANA_DEVNET.Selector) auth, err := solana.NewRandomPrivateKey() require.NoError(t, err) diff --git a/sdk/solana/inspector_test.go b/sdk/solana/inspector_test.go index d29907724..a80042bf3 100644 --- a/sdk/solana/inspector_test.go +++ b/sdk/solana/inspector_test.go @@ -7,7 +7,7 @@ import ( "github.com/stretchr/testify/require" - cselectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/ethereum/go-ethereum/common" "github.com/google/go-cmp/cmp" @@ -32,7 +32,7 @@ func TestInspector_GetConfig(t *testing.T) { t.Parallel() ctx := context.Background() - chainSelector := cselectors.SOLANA_DEVNET.Selector + chainSelector := chainsel.SOLANA_DEVNET.Selector configPDA, err := FindConfigPDA(testMCMProgramID, testPDASeed) require.NoError(t, err) diff --git a/sdk/solana/simulator_test.go b/sdk/solana/simulator_test.go index 6fbe12dd2..22bff9b7b 100644 --- a/sdk/solana/simulator_test.go +++ b/sdk/solana/simulator_test.go @@ -10,7 +10,7 @@ import ( "github.com/ethereum/go-ethereum/common" - cselectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/gagliardetto/solana-go" "github.com/gagliardetto/solana-go/programs/system" @@ -117,7 +117,7 @@ func TestSimulator_SimulateOperation(t *testing.T) { auth, err := solana.NewRandomPrivateKey() require.NoError(t, err) - selector := cselectors.SOLANA_DEVNET.Selector + selector := chainsel.SOLANA_DEVNET.Selector testWallet, err := solana.NewRandomPrivateKey() require.NoError(t, err) diff --git a/sdk/solana/timelock_executor.go b/sdk/solana/timelock_executor.go index 837b7d60e..267e94361 100644 --- a/sdk/solana/timelock_executor.go +++ b/sdk/solana/timelock_executor.go @@ -7,7 +7,7 @@ import ( "github.com/smartcontractkit/mcms/sdk" "github.com/smartcontractkit/mcms/types" - chain_selectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/ethereum/go-ethereum/common" @@ -99,7 +99,7 @@ func (e *TimelockExecutor) Execute( return types.TransactionResult{ Hash: signature, - ChainFamily: chain_selectors.FamilySolana, + ChainFamily: chainsel.FamilySolana, RawData: tx, }, nil } diff --git a/sdk/solana/timelock_executor_test.go b/sdk/solana/timelock_executor_test.go index 44525e94a..fb50e343e 100644 --- a/sdk/solana/timelock_executor_test.go +++ b/sdk/solana/timelock_executor_test.go @@ -14,7 +14,7 @@ import ( "github.com/gagliardetto/solana-go" "github.com/gagliardetto/solana-go/rpc" - cselectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/mcms/sdk/solana/mocks" "github.com/smartcontractkit/mcms/types" @@ -39,7 +39,7 @@ func TestTimelockExecutor_Execute(t *testing.T) { //nolint:paralleltest predecessor [32]byte timelockAddress string } - selector := cselectors.SOLANA_DEVNET.Selector + selector := chainsel.SOLANA_DEVNET.Selector auth, err := solana.PrivateKeyFromBase58(dummyPrivateKey) require.NoError(t, err) diff --git a/sdk/sui/configurer.go b/sdk/sui/configurer.go index 1ddaf8d85..5d6fde939 100644 --- a/sdk/sui/configurer.go +++ b/sdk/sui/configurer.go @@ -5,7 +5,8 @@ import ( "fmt" "math/big" - cselectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" + chainselremote "github.com/smartcontractkit/chain-selectors/remote" "github.com/block-vision/sui-go-sdk/sui" @@ -45,7 +46,7 @@ func NewConfigurer(client sui.ISuiAPI, signer bindutils.SuiSigner, role Timelock } func (c Configurer) SetConfig(ctx context.Context, mcmsAddr string, cfg *types.Config, clearRoot bool) (types.TransactionResult, error) { - chainID, err := cselectors.SuiChainIdFromSelector(c.chainSelector) + chainID, err := chainsel.SuiChainIdFromSelector(c.chainSelector) if err != nil { return types.TransactionResult{}, err } @@ -82,7 +83,7 @@ func (c Configurer) SetConfig(ctx context.Context, mcmsAddr string, cfg *types.C return types.TransactionResult{ Hash: tx.Digest, - ChainFamily: cselectors.FamilySui, + ChainFamily: chainsel.FamilySui, RawData: tx, }, nil } diff --git a/timelock_executable_test.go b/timelock_executable_test.go index a8769b15f..aa23f1f34 100644 --- a/timelock_executable_test.go +++ b/timelock_executable_test.go @@ -15,7 +15,7 @@ import ( "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" - chain_selectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" testutils "github.com/smartcontractkit/mcms/e2e/utils" "github.com/smartcontractkit/mcms/internal/testutils/chaintest" @@ -207,7 +207,7 @@ func TestTimelockExecutable_Execute(t *testing.T) { Execute(ctx, mock.Anything, "0x5678", mock.Anything, mock.Anything). Return(types.TransactionResult{ Hash: "signature", - ChainFamily: chain_selectors.FamilyEVM, + ChainFamily: chainsel.FamilyEVM, }, nil).Once() executors := map[types.ChainSelector]sdk.TimelockExecutor{chaintest.Chain1Selector: executor} @@ -225,7 +225,7 @@ func TestTimelockExecutable_Execute(t *testing.T) { Execute(ctx, mock.Anything, "0xABCD", mock.Anything, mock.Anything). Return(types.TransactionResult{ Hash: "signature", - ChainFamily: chain_selectors.FamilyEVM, + ChainFamily: chainsel.FamilyEVM, }, nil).Once() executors := map[types.ChainSelector]sdk.TimelockExecutor{chaintest.Chain1Selector: executor} diff --git a/validation.go b/validation.go index f5355bcdc..4901edf75 100644 --- a/validation.go +++ b/validation.go @@ -4,7 +4,7 @@ import ( "encoding/json" "fmt" - cselectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/mcms/types" @@ -22,19 +22,19 @@ func validateAdditionalFields(additionalFields json.RawMessage, csel types.Chain } switch chainFamily { - case cselectors.FamilyEVM: + case chainsel.FamilyEVM: return evm.ValidateAdditionalFields(additionalFields) - case cselectors.FamilySolana: + case chainsel.FamilySolana: return solana.ValidateAdditionalFields(additionalFields) - case cselectors.FamilyAptos: + case chainsel.FamilyAptos: return aptos.ValidateAdditionalFields(additionalFields) - case cselectors.FamilySui: + case chainsel.FamilySui: return sui.ValidateAdditionalFields(additionalFields) - case cselectors.FamilyTon: + case chainsel.FamilyTon: return ton.ValidateAdditionalFields(additionalFields) } @@ -49,15 +49,15 @@ func validateChainMetadata(metadata types.ChainMetadata, csel types.ChainSelecto } switch chainFamily { - case cselectors.FamilySolana: + case chainsel.FamilySolana: return solana.ValidateChainMetadata(metadata) - case cselectors.FamilyEVM: + case chainsel.FamilyEVM: return nil - case cselectors.FamilyAptos: + case chainsel.FamilyAptos: return nil - case cselectors.FamilySui: + case chainsel.FamilySui: return sui.ValidateChainMetadata(metadata) - case cselectors.FamilyTon: + case chainsel.FamilyTon: // TODO (ton): do we need special chain metadata for TON? // Yes! We could attach MCMS -> Timelock value here which is now hardcoded default in timelock converter return nil diff --git a/validation_test.go b/validation_test.go index 5b9851277..b2e164f9a 100644 --- a/validation_test.go +++ b/validation_test.go @@ -11,7 +11,7 @@ import ( solana2 "github.com/gagliardetto/solana-go" - cselectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/mcms/internal/testutils/chaintest" "github.com/smartcontractkit/mcms/sdk/aptos" @@ -73,13 +73,13 @@ func TestValidateChainMetadata(t *testing.T) { }{ { name: "valid Solana metadata", - chainSelector: types.ChainSelector(cselectors.SOLANA_DEVNET.Selector), + chainSelector: types.ChainSelector(chainsel.SOLANA_DEVNET.Selector), additionalFields: types.ChainMetadata{AdditionalFields: validMetadataJSON}, expectedErr: nil, }, { name: "invalid Solana metadata value", - chainSelector: types.ChainSelector(cselectors.SOLANA_DEVNET.Selector), + chainSelector: types.ChainSelector(chainsel.SOLANA_DEVNET.Selector), additionalFields: types.ChainMetadata{AdditionalFields: invalidMetadataJSON}, expectedErr: errors.New("Key: 'AdditionalFieldsMetadata.ProposerRoleAccessController' Error:Field validation for 'ProposerRoleAccessController' failed on the 'required' tag\nKey: 'AdditionalFieldsMetadata.CancellerRoleAccessController' Error:Field validation for 'CancellerRoleAccessController' failed on the 'required' tag\nKey: 'AdditionalFieldsMetadata.BypasserRoleAccessController' Error:Field validation for 'BypasserRoleAccessController' failed on the 'required' tag"), }, @@ -109,7 +109,7 @@ func TestValidateChainMetadata(t *testing.T) { }, { name: "invalid JSON for Solana metadata", - chainSelector: types.ChainSelector(cselectors.SOLANA_DEVNET.Selector), + chainSelector: types.ChainSelector(chainsel.SOLANA_DEVNET.Selector), additionalFields: types.ChainMetadata{AdditionalFields: []byte("invalid JSON")}, expectedErr: errors.New("unable to unmarshal additional fields: invalid character 'i' looking for beginning of value"), }, @@ -194,7 +194,7 @@ func TestValidateAdditionalFields(t *testing.T) { { name: "valid EVM fields", operation: types.Operation{ - ChainSelector: types.ChainSelector(cselectors.ETHEREUM_TESTNET_SEPOLIA.Selector), + ChainSelector: types.ChainSelector(chainsel.ETHEREUM_TESTNET_SEPOLIA.Selector), Transaction: types.Transaction{ AdditionalFields: validEVMFieldsJSON, }, @@ -205,7 +205,7 @@ func TestValidateAdditionalFields(t *testing.T) { { name: "invalid EVM fields", operation: types.Operation{ - ChainSelector: types.ChainSelector(cselectors.ETHEREUM_TESTNET_SEPOLIA.Selector), + ChainSelector: types.ChainSelector(chainsel.ETHEREUM_TESTNET_SEPOLIA.Selector), Transaction: types.Transaction{ AdditionalFields: invalidEVMFieldsJSON, }, @@ -215,7 +215,7 @@ func TestValidateAdditionalFields(t *testing.T) { { name: "valid Solana fields", operation: types.Operation{ - ChainSelector: types.ChainSelector(cselectors.SOLANA_DEVNET.Selector), + ChainSelector: types.ChainSelector(chainsel.SOLANA_DEVNET.Selector), Transaction: types.Transaction{ AdditionalFields: validSolanaFieldsJSON, }, @@ -275,7 +275,7 @@ func TestValidateAdditionalFields(t *testing.T) { { name: "invalid JSON for EVM fields", operation: types.Operation{ - ChainSelector: types.ChainSelector(cselectors.ETHEREUM_TESTNET_SEPOLIA.Selector), + ChainSelector: types.ChainSelector(chainsel.ETHEREUM_TESTNET_SEPOLIA.Selector), Transaction: types.Transaction{ AdditionalFields: []byte("invalid JSON"), }, From 6148b74e9cb9a9081d321a9a06190f9193323d4e Mon Sep 17 00:00:00 2001 From: Pablo Date: Fri, 6 Feb 2026 16:44:06 -0600 Subject: [PATCH 2/2] feat: standardize imports and use remote chain selector API Signed-off-by: Pablo --- e2e/tests/ton/set_root.go | 4 ++-- executable_test.go | 6 +++--- sdk/sui/configurer.go | 1 - sdk/sui/configurer_test.go | 18 +++++++++--------- sdk/sui/encoder.go | 6 +++--- sdk/sui/executor.go | 10 +++++----- sdk/sui/executor_test.go | 14 +++++++------- sdk/sui/timelock_executor.go | 4 ++-- sdk/sui/timelock_executor_test.go | 4 ++-- sdk/ton/common.go | 4 ++-- sdk/ton/configurer.go | 4 ++-- sdk/ton/encoder.go | 6 +++--- sdk/ton/encoder_test.go | 4 ++-- sdk/ton/timelock_converter_test.go | 8 ++++---- timelock_proposal.go | 10 +++++----- types/chain_selector.go | 26 ++++++++++++++++---------- types/chain_selector_test.go | 14 +++++++------- 17 files changed, 74 insertions(+), 69 deletions(-) diff --git a/e2e/tests/ton/set_root.go b/e2e/tests/ton/set_root.go index b8699192d..a61e0fffd 100644 --- a/e2e/tests/ton/set_root.go +++ b/e2e/tests/ton/set_root.go @@ -9,7 +9,7 @@ import ( "github.com/stretchr/testify/suite" - chainsel "github.com/smartcontractkit/chain-selectors" + chainselremote "github.com/smartcontractkit/chain-selectors/remote" "github.com/smartcontractkit/chainlink-ton/pkg/bindings/mcms/mcms" "github.com/smartcontractkit/chainlink-ton/pkg/ton/hash" @@ -69,7 +69,7 @@ func (s *SetRootTestSuite) SetupSuite() { s.deployMCMSContract() - chainDetails, err := chainsel.GetChainDetailsByChainIDAndFamily(s.TonBlockchain.ChainID, s.TonBlockchain.Family) + chainDetails, err := chainselremote.GetChainDetailsByChainIDAndFamily(s.T().Context(), s.TonBlockchain.ChainID, s.TonBlockchain.Family) s.Require().NoError(err) s.chainSelector = types.ChainSelector(chainDetails.ChainSelector) } diff --git a/executable_test.go b/executable_test.go index 4d1881470..3afb4ae05 100644 --- a/executable_test.go +++ b/executable_test.go @@ -6,7 +6,7 @@ import ( "math/big" "testing" - cselectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/stretchr/testify/require" @@ -645,8 +645,8 @@ func TestExecutor_ExecuteE2E_SingleChainMultipleSignerMultipleTX_Success(t *test func TestExecutable_TxNonce(t *testing.T) { t.Parallel() - chainSelector1 := types.ChainSelector(cselectors.GETH_TESTNET.Selector) - chainSelector2 := types.ChainSelector(cselectors.GETH_DEVNET_2.Selector) + chainSelector1 := types.ChainSelector(chainsel.GETH_TESTNET.Selector) + chainSelector2 := types.ChainSelector(chainsel.GETH_DEVNET_2.Selector) executor := mocks.NewExecutor(t) executors := map[types.ChainSelector]sdk.Executor{ chainSelector1: executor, diff --git a/sdk/sui/configurer.go b/sdk/sui/configurer.go index 5d6fde939..ac2e09664 100644 --- a/sdk/sui/configurer.go +++ b/sdk/sui/configurer.go @@ -6,7 +6,6 @@ import ( "math/big" chainsel "github.com/smartcontractkit/chain-selectors" - chainselremote "github.com/smartcontractkit/chain-selectors/remote" "github.com/block-vision/sui-go-sdk/sui" diff --git a/sdk/sui/configurer_test.go b/sdk/sui/configurer_test.go index 63e8a9cea..d4aef378e 100644 --- a/sdk/sui/configurer_test.go +++ b/sdk/sui/configurer_test.go @@ -13,7 +13,7 @@ import ( "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" - cselectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/chainlink-sui/bindings/bind" mockbindutils "github.com/smartcontractkit/mcms/sdk/sui/mocks/bindutils" @@ -47,7 +47,7 @@ func TestNewConfigurer(t *testing.T) { // Test successful creation mcmsPackageID := "0x123456789abcdef" ownerCap := "0xabcdef123456789" - chainSelector := cselectors.SUI_TESTNET.Selector + chainSelector := chainsel.SUI_TESTNET.Selector configurer, err := NewConfigurer(mockClient, mockSigner, TimelockRoleBypasser, mcmsPackageID, ownerCap, chainSelector) require.NoError(t, err) @@ -115,9 +115,9 @@ func TestConfigurer_SetConfig(t *testing.T) { clearRoot: true, }, role: TimelockRoleBypasser, - chainID: cselectors.SUI_TESTNET.Selector, + chainID: chainsel.SUI_TESTNET.Selector, mockSetup: func(mockmcms *mockmodulemcms.IMcms) { - expectedChainID := new(big.Int).SetUint64(cselectors.SUI_TESTNET.ChainID) + expectedChainID := new(big.Int).SetUint64(chainsel.SUI_TESTNET.ChainID) mockmcms.EXPECT().SetConfig( mock.Anything, mock.Anything, @@ -147,7 +147,7 @@ func TestConfigurer_SetConfig(t *testing.T) { }, want: types.TransactionResult{ Hash: "0x123456789abcdef", - ChainFamily: cselectors.FamilySui, + ChainFamily: chainsel.FamilySui, RawData: expectedTx, }, wantErr: assert.NoError, @@ -163,9 +163,9 @@ func TestConfigurer_SetConfig(t *testing.T) { clearRoot: false, }, role: TimelockRoleCanceller, - chainID: cselectors.SUI_TESTNET.Selector, + chainID: chainsel.SUI_TESTNET.Selector, mockSetup: func(mockmcms *mockmodulemcms.IMcms) { - expectedChainID := new(big.Int).SetUint64(cselectors.SUI_TESTNET.ChainID) + expectedChainID := new(big.Int).SetUint64(chainsel.SUI_TESTNET.ChainID) mockmcms.EXPECT().SetConfig( mock.Anything, mock.Anything, @@ -184,7 +184,7 @@ func TestConfigurer_SetConfig(t *testing.T) { }, want: types.TransactionResult{ Hash: "0x123456789abcdef", - ChainFamily: cselectors.FamilySui, + ChainFamily: chainsel.FamilySui, RawData: expectedTx, }, wantErr: assert.NoError, @@ -213,7 +213,7 @@ func TestConfigurer_SetConfig(t *testing.T) { }, }, role: TimelockRoleProposer, - chainID: cselectors.SUI_TESTNET.Selector, + chainID: chainsel.SUI_TESTNET.Selector, mockSetup: func(mockmcms *mockmodulemcms.IMcms) { mockmcms.EXPECT().SetConfig(mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil, errors.New("transaction failed")) }, diff --git a/sdk/sui/encoder.go b/sdk/sui/encoder.go index 2d440d273..79ca18314 100644 --- a/sdk/sui/encoder.go +++ b/sdk/sui/encoder.go @@ -13,7 +13,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" - cselectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/mcms/sdk" "github.com/smartcontractkit/mcms/types" @@ -58,7 +58,7 @@ func NewEncoder( } func (e *Encoder) HashOperation(opCount uint32, metadata types.ChainMetadata, op types.Operation) (common.Hash, error) { - chainID, err := cselectors.SuiChainIdFromSelector(uint64(e.ChainSelector)) + chainID, err := chainsel.SuiChainIdFromSelector(uint64(e.ChainSelector)) if err != nil { return common.Hash{}, err } @@ -98,7 +98,7 @@ func (e *Encoder) HashOperation(opCount uint32, metadata types.ChainMetadata, op } func (e *Encoder) HashMetadata(metadata types.ChainMetadata) (common.Hash, error) { - chainID, err := cselectors.SuiChainIdFromSelector(uint64(e.ChainSelector)) + chainID, err := chainsel.SuiChainIdFromSelector(uint64(e.ChainSelector)) if err != nil { return common.Hash{}, fmt.Errorf("failed to get chain ID from selector %d: %w", e.ChainSelector, err) } diff --git a/sdk/sui/executor.go b/sdk/sui/executor.go index 31b8628a2..d39a2f5f0 100644 --- a/sdk/sui/executor.go +++ b/sdk/sui/executor.go @@ -12,7 +12,7 @@ import ( "github.com/block-vision/sui-go-sdk/transaction" "github.com/ethereum/go-ethereum/common" - cselectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/chainlink-sui/bindings/bind" modulemcms "github.com/smartcontractkit/chainlink-sui/bindings/generated/mcms/mcms" @@ -99,7 +99,7 @@ func (e Executor) ExecuteOperation( } } - chainID, err := cselectors.SuiChainIdFromSelector(uint64(e.ChainSelector)) + chainID, err := chainsel.SuiChainIdFromSelector(uint64(e.ChainSelector)) if err != nil { return types.TransactionResult{}, err } @@ -217,7 +217,7 @@ func (e Executor) ExecuteOperation( return types.TransactionResult{ Hash: tx.Digest, - ChainFamily: cselectors.FamilySui, + ChainFamily: chainsel.FamilySui, RawData: tx, }, nil } @@ -237,7 +237,7 @@ func (e Executor) SetRoot( } } - chainID, err := cselectors.SuiChainIdFromSelector(uint64(e.ChainSelector)) + chainID, err := chainsel.SuiChainIdFromSelector(uint64(e.ChainSelector)) if err != nil { return types.TransactionResult{}, err } @@ -280,7 +280,7 @@ func (e Executor) SetRoot( return types.TransactionResult{ Hash: tx.Digest, - ChainFamily: cselectors.FamilySui, + ChainFamily: chainsel.FamilySui, RawData: tx, }, nil } diff --git a/sdk/sui/executor_test.go b/sdk/sui/executor_test.go index 2303c8706..5b64bd6e1 100644 --- a/sdk/sui/executor_test.go +++ b/sdk/sui/executor_test.go @@ -13,7 +13,7 @@ import ( "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" - cselectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/chainlink-sui/bindings/bind" mockbindutils "github.com/smartcontractkit/mcms/sdk/sui/mocks/bindutils" @@ -226,7 +226,7 @@ func TestExecutor_SetRoot(t *testing.T) { mcmsPackageID: "0x123456789abcdef", mcmsObj: mcmsObj, Encoder: &Encoder{ - ChainSelector: types.ChainSelector(cselectors.SUI_TESTNET.Selector), + ChainSelector: types.ChainSelector(chainsel.SUI_TESTNET.Selector), TxCount: 5, OverridePreviousRoot: false, }, @@ -296,7 +296,7 @@ func TestExecutor_ExecuteOperation_InvalidAdditionalFields(t *testing.T) { mcmsObj: mcmsObj, client: mockClient, Encoder: &Encoder{ - ChainSelector: types.ChainSelector(cselectors.SUI_TESTNET.Selector), + ChainSelector: types.ChainSelector(chainsel.SUI_TESTNET.Selector), TxCount: 5, }, } @@ -343,7 +343,7 @@ func TestExecutor_ExecuteOperation_Success_ScheduleBatch(t *testing.T) { accountObj: accountObj, client: mockClient, Encoder: &Encoder{ - ChainSelector: types.ChainSelector(cselectors.SUI_TESTNET.Selector), + ChainSelector: types.ChainSelector(chainsel.SUI_TESTNET.Selector), TxCount: 5, }, // Mock ExecutePTB function directly in the struct @@ -437,7 +437,7 @@ func TestExecutor_ExecuteOperation_Success_Bypass(t *testing.T) { accountObj: accountObj, client: mockClient, Encoder: &Encoder{ - ChainSelector: types.ChainSelector(cselectors.SUI_TESTNET.Selector), + ChainSelector: types.ChainSelector(chainsel.SUI_TESTNET.Selector), TxCount: 5, }, // Mock ExecutePTB function directly in the struct @@ -543,7 +543,7 @@ func TestExecutor_ExecuteOperation_Success_Cancel(t *testing.T) { accountObj: accountObj, client: mockClient, Encoder: &Encoder{ - ChainSelector: types.ChainSelector(cselectors.SUI_TESTNET.Selector), + ChainSelector: types.ChainSelector(chainsel.SUI_TESTNET.Selector), TxCount: 5, }, // Mock ExecutePTB function directly in the struct @@ -638,7 +638,7 @@ func TestExecutor_ExecuteOperation_Cancel_InvalidOperationID(t *testing.T) { accountObj: accountObj, client: mockClient, Encoder: &Encoder{ - ChainSelector: types.ChainSelector(cselectors.SUI_TESTNET.Selector), + ChainSelector: types.ChainSelector(chainsel.SUI_TESTNET.Selector), TxCount: 5, }, } diff --git a/sdk/sui/timelock_executor.go b/sdk/sui/timelock_executor.go index 1f93accf7..c9eb081f2 100644 --- a/sdk/sui/timelock_executor.go +++ b/sdk/sui/timelock_executor.go @@ -13,7 +13,7 @@ import ( "github.com/smartcontractkit/chainlink-sui/bindings/bind" bindutils "github.com/smartcontractkit/chainlink-sui/bindings/utils" - cselectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/mcms/sdk" "github.com/smartcontractkit/mcms/types" @@ -140,7 +140,7 @@ func (t *TimelockExecutor) Execute( return types.TransactionResult{ Hash: tx.Digest, - ChainFamily: cselectors.FamilySui, + ChainFamily: chainsel.FamilySui, RawData: tx, }, nil } diff --git a/sdk/sui/timelock_executor_test.go b/sdk/sui/timelock_executor_test.go index 768e50100..029695d7a 100644 --- a/sdk/sui/timelock_executor_test.go +++ b/sdk/sui/timelock_executor_test.go @@ -13,7 +13,7 @@ import ( "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" - cselectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/chainlink-sui/bindings/bind" mockbindutils "github.com/smartcontractkit/mcms/sdk/sui/mocks/bindutils" @@ -197,7 +197,7 @@ func TestTimelockExecutor_Execute_Success(t *testing.T) { // Verify the result require.NoError(t, err) assert.Equal(t, "9WzSXdwbky8tNbH7juvyaui4QzMUYEjdCEKMrMgLhXHT", result.Hash) - assert.Equal(t, cselectors.FamilySui, result.ChainFamily) + assert.Equal(t, chainsel.FamilySui, result.ChainFamily) assert.NotNil(t, result.RawData) } diff --git a/sdk/ton/common.go b/sdk/ton/common.go index c4330f601..55ad11a62 100644 --- a/sdk/ton/common.go +++ b/sdk/ton/common.go @@ -6,7 +6,7 @@ import ( "fmt" "time" - cselectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/xssnick/tonutils-go/address" "github.com/xssnick/tonutils-go/tlb" @@ -43,7 +43,7 @@ func SendTx(ctx context.Context, opts TxOpts) (types.TransactionResult, error) { return types.TransactionResult{ Hash: hex.EncodeToString(tx.Hash), - ChainFamily: cselectors.FamilyTon, + ChainFamily: chainsel.FamilyTon, RawData: tx, // *tlb.Transaction }, nil } diff --git a/sdk/ton/configurer.go b/sdk/ton/configurer.go index c85d4cb38..9881be011 100644 --- a/sdk/ton/configurer.go +++ b/sdk/ton/configurer.go @@ -4,7 +4,7 @@ import ( "context" "fmt" - cselectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/chainlink-ton/pkg/bindings/mcms/mcms" "github.com/smartcontractkit/chainlink-ton/pkg/ton/tlbe" "github.com/smartcontractkit/chainlink-ton/pkg/ton/tvm" @@ -118,7 +118,7 @@ func (c configurer) SetConfig(ctx context.Context, mcmsAddr string, cfg *types.C return types.TransactionResult{ Hash: "", // Returning no hash since the transaction hasn't been sent yet. - ChainFamily: cselectors.FamilyTon, + ChainFamily: chainsel.FamilyTon, RawData: tx, // will be of type types.Transaction }, nil } diff --git a/sdk/ton/encoder.go b/sdk/ton/encoder.go index 066c0a665..658b1bedb 100644 --- a/sdk/ton/encoder.go +++ b/sdk/ton/encoder.go @@ -10,7 +10,7 @@ import ( "github.com/xssnick/tonutils-go/tlb" "github.com/xssnick/tonutils-go/tvm/cell" - chain_selectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/chainlink-ton/pkg/bindings/mcms/mcms" "github.com/smartcontractkit/chainlink-ton/pkg/ton/tlbe" @@ -124,7 +124,7 @@ func (e *Encoder) HashMetadata(metadata types.ChainMetadata) (common.Hash, error } func (e *Encoder) ToOperation(opCount uint32, metadata types.ChainMetadata, op types.Operation) (mcms.Op, error) { - chainID, err := chain_selectors.TonChainIdFromSelector(uint64(e.ChainSelector)) + chainID, err := chainsel.TonChainIdFromSelector(uint64(e.ChainSelector)) if err != nil { return mcms.Op{}, &sdkerrors.InvalidChainIDError{ReceivedChainID: e.ChainSelector} } @@ -162,7 +162,7 @@ func (e *Encoder) ToOperation(opCount uint32, metadata types.ChainMetadata, op t } func (e *Encoder) ToRootMetadata(metadata types.ChainMetadata) (mcms.RootMetadata, error) { - chainID, err := chain_selectors.TonChainIdFromSelector(uint64(e.ChainSelector)) + chainID, err := chainsel.TonChainIdFromSelector(uint64(e.ChainSelector)) if err != nil { return mcms.RootMetadata{}, &sdkerrors.InvalidChainIDError{ReceivedChainID: e.ChainSelector} } diff --git a/sdk/ton/encoder_test.go b/sdk/ton/encoder_test.go index 5c7bc0a3c..14ebcd6d6 100644 --- a/sdk/ton/encoder_test.go +++ b/sdk/ton/encoder_test.go @@ -7,7 +7,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - cselectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/mcms/internal/testutils/chaintest" "github.com/smartcontractkit/mcms/sdk/ton" @@ -131,7 +131,7 @@ func TestEncoder_ToOperation(t *testing.T) { var ( chainID = int32(-217) - chainSelector = types.ChainSelector(cselectors.TonChainIdToChainSelector()[chainID]) + chainSelector = types.ChainSelector(chainsel.TonChainIdToChainSelector()[chainID]) // Static argument values to ToGethOperation since they don't affect the test giveOpCount = uint32(0) diff --git a/sdk/ton/timelock_converter_test.go b/sdk/ton/timelock_converter_test.go index 34b9f31f5..0af2e5e37 100644 --- a/sdk/ton/timelock_converter_test.go +++ b/sdk/ton/timelock_converter_test.go @@ -7,7 +7,7 @@ import ( "github.com/ethereum/go-ethereum/common" - cselectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -37,7 +37,7 @@ func TestTimelockConverter_ConvertBatchToChainOperation(t *testing.T) { "RBACTimelock", []string{"tag1", "tag2"}, ))}, - ChainSelector: types.ChainSelector(cselectors.TON_TESTNET.Selector), + ChainSelector: types.ChainSelector(chainsel.TON_TESTNET.Selector), } testCases := []struct { @@ -97,7 +97,7 @@ func TestTimelockConverter_ConvertBatchToChainOperation(t *testing.T) { Data: []byte("0x1234"), AdditionalFields: []byte("invalid"), }}, - ChainSelector: types.ChainSelector(cselectors.TON_TESTNET.Selector), + ChainSelector: types.ChainSelector(chainsel.TON_TESTNET.Selector), }, delay: "1h", operation: types.TimelockActionSchedule, @@ -114,7 +114,7 @@ func TestTimelockConverter_ConvertBatchToChainOperation(t *testing.T) { Data: []byte("0x1234"), AdditionalFields: []byte("{\"value\":1000}"), }}, - ChainSelector: types.ChainSelector(cselectors.TON_TESTNET.Selector), + ChainSelector: types.ChainSelector(chainsel.TON_TESTNET.Selector), }, delay: "1h", operation: types.TimelockActionSchedule, diff --git a/timelock_proposal.go b/timelock_proposal.go index af52f8287..d566ef37c 100644 --- a/timelock_proposal.go +++ b/timelock_proposal.go @@ -13,7 +13,7 @@ import ( "github.com/go-playground/validator/v10" - chain_selectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/mcms/chainwrappers" "github.com/smartcontractkit/mcms/internal/utils/safecast" @@ -288,13 +288,13 @@ func (m *TimelockProposal) buildTimelockConverters() (map[types.ChainSelector]sd var converter sdk.TimelockConverter switch fam { - case chain_selectors.FamilyEVM: + case chainsel.FamilyEVM: converter = evm.NewTimelockConverter() - case chain_selectors.FamilySolana: + case chainsel.FamilySolana: converter = solana.NewTimelockConverter() - case chain_selectors.FamilyAptos: + case chainsel.FamilyAptos: converter = aptos.NewTimelockConverter() - case chain_selectors.FamilySui: + case chainsel.FamilySui: converter, err = sui.NewTimelockConverter() if err != nil { return nil, fmt.Errorf("failed to create Sui timelock converter: %w", err) diff --git a/types/chain_selector.go b/types/chain_selector.go index 1bf0cdf0d..cbaec4f45 100644 --- a/types/chain_selector.go +++ b/types/chain_selector.go @@ -1,11 +1,13 @@ package types //nolint:revive,nolintlint // allow pkg name 'types' import ( + "context" "errors" "fmt" "slices" - cselectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" + chainselremote "github.com/smartcontractkit/chain-selectors/remote" ) // ChainSelector is a unique identifier for a chain. @@ -24,23 +26,27 @@ var ( // supportedFamilies is a list of supported chain families that MCMS supports var supportedFamilies = []string{ - cselectors.FamilyEVM, - cselectors.FamilySolana, - cselectors.FamilyAptos, - cselectors.FamilySui, - cselectors.FamilyTon, + chainsel.FamilyEVM, + chainsel.FamilySolana, + chainsel.FamilyAptos, + chainsel.FamilySui, + chainsel.FamilyTon, } // GetChainSelectorFamily returns the family of the chain selector. func GetChainSelectorFamily(sel ChainSelector) (string, error) { - f, err := cselectors.GetSelectorFamily(uint64(sel)) + // TODO: pass this ctx as a parameter. + // this function is used in a lot of places, and passing the context through all of them would be a big breaking change + // so a bigger refactor may be needed to properly pass context through all the layers that use this function + ctx := context.Background() + details, err := chainselremote.GetChainDetailsBySelector(ctx, uint64(sel)) if err != nil { return "", fmt.Errorf("%w for selector %d", ErrChainFamilyNotFound, sel) } - if !slices.Contains(supportedFamilies, f) { - return "", fmt.Errorf("%w: %s", ErrUnsupportedChainFamily, f) + if !slices.Contains(supportedFamilies, details.Family) { + return "", fmt.Errorf("%w: %s", ErrUnsupportedChainFamily, details.Family) } - return f, nil + return details.Family, nil } diff --git a/types/chain_selector_test.go b/types/chain_selector_test.go index ed49b555d..0d1d4a726 100644 --- a/types/chain_selector_test.go +++ b/types/chain_selector_test.go @@ -6,7 +6,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - cselectors "github.com/smartcontractkit/chain-selectors" + chainsel "github.com/smartcontractkit/chain-selectors" ) func TestGetChainSelectorFamily(t *testing.T) { @@ -20,18 +20,18 @@ func TestGetChainSelectorFamily(t *testing.T) { }{ { name: "success: evm", - give: ChainSelector(cselectors.ETHEREUM_TESTNET_SEPOLIA.Selector), - want: cselectors.FamilyEVM, + give: ChainSelector(chainsel.ETHEREUM_TESTNET_SEPOLIA.Selector), + want: chainsel.FamilyEVM, }, { name: "success: solana", - give: ChainSelector(cselectors.SOLANA_DEVNET.Selector), - want: cselectors.FamilySolana, + give: ChainSelector(chainsel.SOLANA_DEVNET.Selector), + want: chainsel.FamilySolana, }, { name: "success: aptos", - give: ChainSelector(cselectors.APTOS_TESTNET.Selector), - want: cselectors.FamilyAptos, + give: ChainSelector(chainsel.APTOS_TESTNET.Selector), + want: chainsel.FamilyAptos, }, { name: "invalid chain selector",