From f0295844904427392384fe4295383611a1b7070f Mon Sep 17 00:00:00 2001 From: James Kong Date: Thu, 29 Jan 2026 12:02:33 +0800 Subject: [PATCH] feat: add network type helpers to BlockChain interface This adds the `NetworkType` and `IsNetworkType` helpers to the BlockChain interface, and updates all implementations to adhere to the updated interface. --- .changeset/rich-ants-grow.md | 8 ++++++ chain/aptos/aptos_chain.go | 11 +++++++++ chain/aptos/aptos_chain_test.go | 23 +++++++++++++++++ chain/blockchain.go | 26 +++++++++++++++++++- chain/evm/evm_chain.go | 11 +++++++++ chain/evm/evm_chain_test.go | 23 +++++++++++++++++ chain/internal/common/chain_metadata.go | 21 ++++++++++++++++ chain/internal/common/chain_metadata_test.go | 23 +++++++++++++++++ chain/solana/solana_chain.go | 22 ++++++++++++----- chain/solana/solana_chain_test.go | 23 +++++++++++++++++ chain/sui/provider/ctf_provider.go | 3 +-- engine/test/internal/testutils/testutils.go | 8 ++++++ go.mod | 2 +- go.sum | 4 +-- 14 files changed, 196 insertions(+), 12 deletions(-) create mode 100644 .changeset/rich-ants-grow.md diff --git a/.changeset/rich-ants-grow.md b/.changeset/rich-ants-grow.md new file mode 100644 index 00000000..78bd7ddb --- /dev/null +++ b/.changeset/rich-ants-grow.md @@ -0,0 +1,8 @@ +--- +"chainlink-deployments-framework": minor +--- + +Adds methods to determine the network type of a Chain + +- `chain.NetworkType()` - Returns the network type determined by delegating to the `chain-selectors` package +- `chain.IsNetworkType(chainsel.NetworkTypeMainnet)` - Returns a boolean if the network type matches diff --git a/chain/aptos/aptos_chain.go b/chain/aptos/aptos_chain.go index e5475dcc..f781f84b 100644 --- a/chain/aptos/aptos_chain.go +++ b/chain/aptos/aptos_chain.go @@ -2,6 +2,7 @@ package aptos import ( aptoslib "github.com/aptos-labs/aptos-go-sdk" + chainsel "github.com/smartcontractkit/chain-selectors" chaincommon "github.com/smartcontractkit/chainlink-deployments-framework/chain/internal/common" ) @@ -39,3 +40,13 @@ func (c Chain) Name() string { func (c Chain) Family() string { return chaincommon.ChainMetadata{Selector: c.Selector}.Family() } + +// NetworkType returns the type of network the chain is on (e.g. mainnet, testnet) +func (c Chain) NetworkType() (chainsel.NetworkType, error) { + return chaincommon.ChainMetadata{Selector: c.Selector}.NetworkType() +} + +// IsNetworkType checks if the chain is on the given network type +func (c Chain) IsNetworkType(networkType chainsel.NetworkType) bool { + return chaincommon.ChainMetadata{Selector: c.Selector}.IsNetworkType(networkType) +} diff --git a/chain/aptos/aptos_chain_test.go b/chain/aptos/aptos_chain_test.go index 31d2220d..2524371f 100644 --- a/chain/aptos/aptos_chain_test.go +++ b/chain/aptos/aptos_chain_test.go @@ -5,6 +5,7 @@ import ( chainsel "github.com/smartcontractkit/chain-selectors" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink-deployments-framework/chain/aptos" ) @@ -42,3 +43,25 @@ func TestChain_ChainInfot(t *testing.T) { }) } } + +func TestChainMetadata_NetworkType(t *testing.T) { + t.Parallel() + + c := aptos.Chain{Selector: chainsel.APTOS_MAINNET.Selector} + got, err := c.NetworkType() + require.NoError(t, err) + assert.Equal(t, chainsel.NetworkTypeMainnet, got) + + c = aptos.Chain{Selector: 0} + _, err = c.NetworkType() + require.Error(t, err) +} + +func TestChainMetadata_IsNetworkType(t *testing.T) { + t.Parallel() + + c := aptos.Chain{Selector: chainsel.APTOS_MAINNET.Selector} + + assert.True(t, c.IsNetworkType(chainsel.NetworkTypeMainnet)) + assert.False(t, c.IsNetworkType(chainsel.NetworkTypeTestnet)) +} diff --git a/chain/blockchain.go b/chain/blockchain.go index 4c98acb5..12cad92d 100644 --- a/chain/blockchain.go +++ b/chain/blockchain.go @@ -7,6 +7,8 @@ import ( "reflect" "slices" + chainsel "github.com/smartcontractkit/chain-selectors" + "github.com/smartcontractkit/chainlink-deployments-framework/chain/aptos" "github.com/smartcontractkit/chainlink-deployments-framework/chain/canton" "github.com/smartcontractkit/chainlink-deployments-framework/chain/evm" @@ -26,15 +28,37 @@ var _ BlockChain = ton.Chain{} var _ BlockChain = tron.Chain{} var _ BlockChain = canton.Chain{} +// NetworkType represents the type of network, which can either be mainnet or testnet. +type NetworkType string + +var ( + // NetworkTypeMainnet represents the 'mainnet' network type + NetworkTypeMainnet NetworkType = "mainnet" + + // NetworkTypeTestnet represents the 'testnet' network type + NetworkTypeTestnet NetworkType = "testnet" +) + // BlockChain is an interface that represents a chain. // A chain can be an EVM chain, Solana chain Aptos chain or others. type BlockChain interface { // String returns chain name and selector " ()" String() string - // Name returns the name of the chain + + // Name returns the name of the chain (e.g. Ethereum Mainnet, Solana Mainnet, Aptos Mainnet, etc.) Name() string + + // ChainSelector returns the chain's selector ChainSelector() uint64 + + // Family returns the family of the chain (e.g. evm, solana, aptos, etc.) Family() string + + // NetworkType returns the type of network the chain is on (e.g. mainnet, testnet) + NetworkType() (chainsel.NetworkType, error) + + // IsNetworkType checks if the chain is on the given network type + IsNetworkType(networkType chainsel.NetworkType) bool } // BlockChains represents a collection of chains. diff --git a/chain/evm/evm_chain.go b/chain/evm/evm_chain.go index d02f6c8d..8ad61624 100644 --- a/chain/evm/evm_chain.go +++ b/chain/evm/evm_chain.go @@ -7,6 +7,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/zksync-sdk/zksync2-go/accounts" "github.com/zksync-sdk/zksync2-go/clients" @@ -74,3 +75,13 @@ func (c Chain) Name() string { func (c Chain) Family() string { return chaincommon.ChainMetadata{Selector: c.Selector}.Family() } + +// NetworkType returns the type of network the chain is on (e.g. mainnet, testnet) +func (c Chain) NetworkType() (chainsel.NetworkType, error) { + return chaincommon.ChainMetadata{Selector: c.Selector}.NetworkType() +} + +// IsNetworkType checks if the chain is on the given network type +func (c Chain) IsNetworkType(networkType chainsel.NetworkType) bool { + return chaincommon.ChainMetadata{Selector: c.Selector}.IsNetworkType(networkType) +} diff --git a/chain/evm/evm_chain_test.go b/chain/evm/evm_chain_test.go index cade0f7e..c9dbfeb5 100644 --- a/chain/evm/evm_chain_test.go +++ b/chain/evm/evm_chain_test.go @@ -5,6 +5,7 @@ import ( chainsel "github.com/smartcontractkit/chain-selectors" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink-deployments-framework/chain/evm" ) @@ -42,3 +43,25 @@ func TestChain_ChainInfo(t *testing.T) { }) } } + +func TestChainMetadata_NetworkType(t *testing.T) { + t.Parallel() + + c := evm.Chain{Selector: chainsel.ETHEREUM_MAINNET.Selector} + got, err := c.NetworkType() + require.NoError(t, err) + assert.Equal(t, chainsel.NetworkTypeMainnet, got) + + c = evm.Chain{Selector: 0} + _, err = c.NetworkType() + require.Error(t, err) +} + +func TestChainMetadata_IsNetworkType(t *testing.T) { + t.Parallel() + + c := evm.Chain{Selector: chainsel.ETHEREUM_MAINNET.Selector} + + assert.True(t, c.IsNetworkType(chainsel.NetworkTypeMainnet)) + assert.False(t, c.IsNetworkType(chainsel.NetworkTypeTestnet)) +} diff --git a/chain/internal/common/chain_metadata.go b/chain/internal/common/chain_metadata.go index bb5515b7..1f0af78f 100644 --- a/chain/internal/common/chain_metadata.go +++ b/chain/internal/common/chain_metadata.go @@ -51,3 +51,24 @@ func (c ChainMetadata) Family() string { return family } + +// NetworkType returns the type of network the chain represents. +func (c ChainMetadata) NetworkType() (chainsel.NetworkType, error) { + networkType, err := chainsel.GetNetworkType(c.Selector) + if err != nil { + return "", err + } + + return networkType, nil +} + +// IsNetworkType checks if the chain is on the given network type +func (c ChainMetadata) IsNetworkType(networkType chainsel.NetworkType) bool { + // Get the network type of the chain + t, err := c.NetworkType() + if err != nil { + return false + } + + return t == networkType +} diff --git a/chain/internal/common/chain_metadata_test.go b/chain/internal/common/chain_metadata_test.go index 21902ae2..d8171adb 100644 --- a/chain/internal/common/chain_metadata_test.go +++ b/chain/internal/common/chain_metadata_test.go @@ -5,6 +5,7 @@ import ( chainsel "github.com/smartcontractkit/chain-selectors" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink-deployments-framework/chain/internal/common" ) @@ -48,3 +49,25 @@ func TestChainMetadata(t *testing.T) { }) } } + +func TestChainMetadata_NetworkType(t *testing.T) { + t.Parallel() + + c := common.ChainMetadata{Selector: chainsel.ETHEREUM_MAINNET.Selector} + got, err := c.NetworkType() + require.NoError(t, err) + assert.Equal(t, chainsel.NetworkTypeMainnet, got) + + c = common.ChainMetadata{Selector: 0} + _, err = c.NetworkType() + require.Error(t, err) +} + +func TestChainMetadata_IsNetworkType(t *testing.T) { + t.Parallel() + + c := common.ChainMetadata{Selector: chainsel.ETHEREUM_MAINNET.Selector} + + assert.True(t, c.IsNetworkType(chainsel.NetworkTypeMainnet)) + assert.False(t, c.IsNetworkType(chainsel.NetworkTypeTestnet)) +} diff --git a/chain/solana/solana_chain.go b/chain/solana/solana_chain.go index dfb4e722..a98102f2 100644 --- a/chain/solana/solana_chain.go +++ b/chain/solana/solana_chain.go @@ -14,12 +14,12 @@ import ( sollib "github.com/gagliardetto/solana-go" solrpc "github.com/gagliardetto/solana-go/rpc" + chainsel "github.com/smartcontractkit/chain-selectors" solCommonUtil "github.com/smartcontractkit/chainlink-ccip/chains/solana/utils/common" - "github.com/smartcontractkit/chainlink-deployments-framework/pkg/logger" - - "github.com/smartcontractkit/chainlink-deployments-framework/chain/internal/common" + chaincommon "github.com/smartcontractkit/chainlink-deployments-framework/chain/internal/common" "github.com/smartcontractkit/chainlink-deployments-framework/chain/solana/provider/rpcclient" + "github.com/smartcontractkit/chainlink-deployments-framework/pkg/logger" ) const ( @@ -197,15 +197,25 @@ func (c Chain) ChainSelector() uint64 { // String returns chain name and selector " ()" func (c Chain) String() string { - return common.ChainMetadata{Selector: c.Selector}.String() + return chaincommon.ChainMetadata{Selector: c.Selector}.String() } // Name returns the name of the chain func (c Chain) Name() string { - return common.ChainMetadata{Selector: c.Selector}.Name() + return chaincommon.ChainMetadata{Selector: c.Selector}.Name() } // Family returns the family of the chain func (c Chain) Family() string { - return common.ChainMetadata{Selector: c.Selector}.Family() + return chaincommon.ChainMetadata{Selector: c.Selector}.Family() +} + +// NetworkType returns the type of network the chain is on (e.g. mainnet, testnet) +func (c Chain) NetworkType() (chainsel.NetworkType, error) { + return chaincommon.ChainMetadata{Selector: c.Selector}.NetworkType() +} + +// IsNetworkType checks if the chain is on the given network type +func (c Chain) IsNetworkType(networkType chainsel.NetworkType) bool { + return chaincommon.ChainMetadata{Selector: c.Selector}.IsNetworkType(networkType) } diff --git a/chain/solana/solana_chain_test.go b/chain/solana/solana_chain_test.go index ec7f3e5b..0e491072 100644 --- a/chain/solana/solana_chain_test.go +++ b/chain/solana/solana_chain_test.go @@ -5,6 +5,7 @@ import ( chainsel "github.com/smartcontractkit/chain-selectors" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink-deployments-framework/chain/solana" ) @@ -42,3 +43,25 @@ func TestChain_ChainInfot(t *testing.T) { }) } } + +func TestChainMetadata_NetworkType(t *testing.T) { + t.Parallel() + + c := solana.Chain{Selector: chainsel.SOLANA_MAINNET.Selector} + got, err := c.NetworkType() + require.NoError(t, err) + assert.Equal(t, chainsel.NetworkTypeMainnet, got) + + c = solana.Chain{Selector: 0} + _, err = c.NetworkType() + require.Error(t, err) +} + +func TestChainMetadata_IsNetworkType(t *testing.T) { + t.Parallel() + + c := solana.Chain{Selector: chainsel.SOLANA_MAINNET.Selector} + + assert.True(t, c.IsNetworkType(chainsel.NetworkTypeMainnet)) + assert.False(t, c.IsNetworkType(chainsel.NetworkTypeTestnet)) +} diff --git a/chain/sui/provider/ctf_provider.go b/chain/sui/provider/ctf_provider.go index 824769d9..c97853c4 100644 --- a/chain/sui/provider/ctf_provider.go +++ b/chain/sui/provider/ctf_provider.go @@ -10,11 +10,10 @@ import ( "testing" "time" - "github.com/go-resty/resty/v2" - "github.com/avast/retry-go/v4" "github.com/block-vision/sui-go-sdk/models" sui_sdk "github.com/block-vision/sui-go-sdk/sui" + "github.com/go-resty/resty/v2" chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/chainlink-testing-framework/framework" "github.com/smartcontractkit/chainlink-testing-framework/framework/components/blockchain" diff --git a/engine/test/internal/testutils/testutils.go b/engine/test/internal/testutils/testutils.go index fbe1a1c9..aed0acdb 100644 --- a/engine/test/internal/testutils/testutils.go +++ b/engine/test/internal/testutils/testutils.go @@ -4,6 +4,8 @@ package testutils import ( "fmt" + chainsel "github.com/smartcontractkit/chain-selectors" + fchain "github.com/smartcontractkit/chainlink-deployments-framework/chain" ) @@ -24,3 +26,9 @@ func (c *StubChain) ChainSelector() uint64 { return c.selector } func (c *StubChain) Family() string { return "test" } func (c *StubChain) Name() string { return "test" } func (c *StubChain) String() string { return fmt.Sprintf("testChain(%d)", c.selector) } +func (c *StubChain) NetworkType() (chainsel.NetworkType, error) { + return chainsel.NetworkTypeTestnet, nil +} +func (c *StubChain) IsNetworkType(networkType chainsel.NetworkType) bool { + return networkType == chainsel.NetworkTypeTestnet +} diff --git a/go.mod b/go.mod index e8f4aa5d..6663dbc0 100644 --- a/go.mod +++ b/go.mod @@ -27,7 +27,7 @@ require ( github.com/pelletier/go-toml/v2 v2.2.4 github.com/segmentio/ksuid v1.0.4 github.com/smartcontractkit/ccip-owner-contracts v0.1.0 - github.com/smartcontractkit/chain-selectors v1.0.89 + github.com/smartcontractkit/chain-selectors v1.0.91 github.com/smartcontractkit/chainlink-aptos v0.0.0-20251024142440-51f2ad2652a2 github.com/smartcontractkit/chainlink-ccip v0.1.1-solana.0.20260107192940-0be702ef3ff5 github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260119161343-499241536dea diff --git a/go.sum b/go.sum index 52f7756c..e7a7d9ff 100644 --- a/go.sum +++ b/go.sum @@ -690,8 +690,8 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartcontractkit/ccip-owner-contracts v0.1.0 h1:GiBDtlx7539o7AKlDV+9LsA7vTMPv+0n7ClhSFnZFAk= github.com/smartcontractkit/ccip-owner-contracts v0.1.0/go.mod h1:NnT6w4Kj42OFFXhSx99LvJZWPpMjmo4+CpDEWfw61xY= -github.com/smartcontractkit/chain-selectors v1.0.89 h1:L9oWZGqQXWyTPnC6ODXgu3b0DFyLmJ9eHv+uJrE9IZY= -github.com/smartcontractkit/chain-selectors v1.0.89/go.mod h1:qy7whtgG5g+7z0jt0nRyii9bLND9m15NZTzuQPkMZ5w= +github.com/smartcontractkit/chain-selectors v1.0.91 h1:Aip7IZTv40RtbHgZ9mTjm5KyhYrpPefG7iVMzLZ27M4= +github.com/smartcontractkit/chain-selectors v1.0.91/go.mod h1:qy7whtgG5g+7z0jt0nRyii9bLND9m15NZTzuQPkMZ5w= github.com/smartcontractkit/chainlink-aptos v0.0.0-20251024142440-51f2ad2652a2 h1:vGdeMwHO3ow88HvxfhA4DDPYNY0X9jmdux7L83UF/W8= github.com/smartcontractkit/chainlink-aptos v0.0.0-20251024142440-51f2ad2652a2/go.mod h1:iteU0WORHkArACVh/HoY/1bipV4TcNcJdTmom9uIT0E= github.com/smartcontractkit/chainlink-ccip v0.1.1-solana.0.20260107192940-0be702ef3ff5 h1:zn5uuemiuL/Rda48li8Gql929DeYPTRhR2ZGrO3Tgz4=