diff --git a/aptos_test.go b/aptos_test.go index 23b25bb..8a275d3 100644 --- a/aptos_test.go +++ b/aptos_test.go @@ -49,7 +49,10 @@ func Test_AptosYmlAreValid(t *testing.T) { func Test_AptosChainSelectors(t *testing.T) { for selector, chainId := range aptosChainIdBySelector { - family, err := GetSelectorFamily(selector) + csObj, err := NewChainSelectorsObj(ChainInfo{}) + assert.NoError(t, err) + + family, err := csObj.GetSelectorFamily(selector) require.NoError(t, err, "selector %v should be returned as aptos family, but received %v", selector, err) @@ -64,7 +67,10 @@ func Test_AptosChainSelectors(t *testing.T) { func Test_AptosGetChainDetailsByChainIDAndFamily(t *testing.T) { for k, v := range aptosSelectorsMap { - details, err := GetChainDetailsByChainIDAndFamily(fmt.Sprint(k), FamilyAptos) + csObj, err := NewChainSelectorsObj(ChainInfo{}) + assert.NoError(t, err) + + details, err := csObj.GetChainDetailsByChainIDAndFamily(fmt.Sprint(k), FamilyAptos) assert.NoError(t, err) assert.Equal(t, v, details) } @@ -72,7 +78,10 @@ func Test_AptosGetChainDetailsByChainIDAndFamily(t *testing.T) { func Test_AptosGetChainIDByChainSelector(t *testing.T) { for k, v := range aptosSelectorsMap { - chainID, err := GetChainIDFromSelector(v.ChainSelector) + csObj, err := NewChainSelectorsObj(ChainInfo{}) + assert.NoError(t, err) + + chainID, err := csObj.GetChainIDFromSelector(v.ChainSelector) assert.NoError(t, err) assert.Equal(t, chainID, fmt.Sprintf("%v", k)) } diff --git a/evm_test.go b/evm_test.go index 69ed399..4eb6435 100644 --- a/evm_test.go +++ b/evm_test.go @@ -51,7 +51,10 @@ func TestEvmChainIdToChainSelectorReturningCopiedMap(t *testing.T) { func TestAllChainSelectorsHaveFamilies(t *testing.T) { for _, ch := range ALL { - family, err := GetSelectorFamily(ch.Selector) + csObj, err := NewChainSelectorsObj(ChainInfo{}) + assert.NoError(t, err) + + family, err := csObj.GetSelectorFamily(ch.Selector) require.NoError(t, err, "Family not found for selector %d (chain id %d, name %s), please update selector.yml with the appropriate chain family for this chain", ch.Selector, ch.EvmChainID, ch.Name) @@ -231,7 +234,10 @@ func Test_IsEvm(t *testing.T) { func Test_EVMGetChainDetailsByChainIDAndFamily(t *testing.T) { for k, v := range evmChainIdToChainSelector { strChainID := strconv.FormatUint(k, 10) - details, err := GetChainDetailsByChainIDAndFamily(strChainID, FamilyEVM) + csObj, err := NewChainSelectorsObj(ChainInfo{}) + assert.NoError(t, err) + + details, err := csObj.GetChainDetailsByChainIDAndFamily(strChainID, FamilyEVM) assert.NoError(t, err) assert.Equal(t, v, details) } @@ -239,7 +245,10 @@ func Test_EVMGetChainDetailsByChainIDAndFamily(t *testing.T) { func Test_EVMGetChainIDByChainSelector(t *testing.T) { for k, v := range evmSelectorsMap { - chainID, err := GetChainIDFromSelector(v.ChainSelector) + csObj, err := NewChainSelectorsObj(ChainInfo{}) + assert.NoError(t, err) + + chainID, err := csObj.GetChainIDFromSelector(v.ChainSelector) assert.NoError(t, err) assert.Equal(t, chainID, fmt.Sprintf("%v", k)) } diff --git a/generated_chains_aptos.go b/generated_chains_aptos.go index 5da5ced..2319449 100644 --- a/generated_chains_aptos.go +++ b/generated_chains_aptos.go @@ -12,10 +12,12 @@ var ( APTOS_LOCALNET = AptosChain{ChainID: 4, Selector: 4457093679053095497, Name: "aptos-localnet"} APTOS_MAINNET = AptosChain{ChainID: 1, Selector: 4741433654826277614, Name: "aptos-mainnet"} APTOS_TESTNET = AptosChain{ChainID: 2, Selector: 743186221051783445, Name: "aptos-testnet"} + SISH_TESTNET = AptosChain{ChainID: 5, Selector: 7953668971247136127, Name: "sish-testnet"} ) var AptosALL = []AptosChain{ APTOS_LOCALNET, APTOS_MAINNET, APTOS_TESTNET, + SISH_TESTNET, } diff --git a/generated_chains_evm.go b/generated_chains_evm.go index 0f65a6d..b4b3ad1 100644 --- a/generated_chains_evm.go +++ b/generated_chains_evm.go @@ -275,6 +275,7 @@ var ( WEMIX_TESTNET = Chain{EvmChainID: 1112, Selector: 9284632837123596123, Name: "wemix-testnet"} ZKLINK_NOVA_MAINNET = Chain{EvmChainID: 810180, Selector: 4350319965322101699, Name: "zklink_nova-mainnet"} ZKLINK_NOVA_TESTNET = Chain{EvmChainID: 810181, Selector: 5837261596322416298, Name: "zklink_nova-testnet"} + ZORA_TESTNET = Chain{EvmChainID: 999999999, Selector: 1293555114858065859, Name: "zora-testnet"} ) var ALL = []Chain{ @@ -544,4 +545,5 @@ var ALL = []Chain{ WEMIX_TESTNET, ZKLINK_NOVA_MAINNET, ZKLINK_NOVA_TESTNET, + ZORA_TESTNET, } diff --git a/selectors.go b/selectors.go index e4d9f13..bdb9569 100644 --- a/selectors.go +++ b/selectors.go @@ -14,13 +14,56 @@ const ( FamilyTron = "tron" ) -type chainInfo struct { +type ChainInfo struct { Family string ChainID string ChainDetails ChainDetails } -func getChainInfo(selector uint64) (chainInfo, error) { +type ChainSelectorsObj struct { + ExtraChains_evm []ChainInfo +} + +func NewChainSelectorsObj(chainDetails ChainInfo) (*ChainSelectorsObj, error) { + var extraChainsEVM []ChainInfo + // currentChains_Aptos := AptosALL + // currentChains_Solana := SolanaALL + // currentChains_Tron := TronALL + + if chainDetails.Family == FamilyEVM { + // search through EVM + // TODO can we do this search in O(1) after we sort them out + for _, chain := range ALL { + evmChainID, err := strconv.ParseUint(chainDetails.ChainID, 10, 64) + if err != nil { + return &ChainSelectorsObj{}, fmt.Errorf("error converting string to uint64: %v", err) + } + + if chain.EvmChainID == evmChainID || chain.Selector == chainDetails.ChainDetails.ChainSelector { + // TODO: add chainselector related validation to check that the random number is valid + + // Conflict detected, return currentChains without adding the new one, donot error + // TODO: maybe throw a warning log + return &ChainSelectorsObj{}, nil + } + } + + // No conflict, add the new chain + extraChainsEVM = append(extraChainsEVM, chainDetails) + + return &ChainSelectorsObj{ExtraChains_evm: extraChainsEVM}, nil + } + + // To extend to new family we can extend the logic like below + // if chainDetails.Family == FamilyAptos { + // // search through aptos + // currentChains_Aptos + // } + + return &ChainSelectorsObj{}, nil +} + +func getChainInfo(selector uint64, csObj *ChainSelectorsObj) (ChainInfo, error) { // check EVM _, exist := evmChainsBySelector[selector] if exist { @@ -28,21 +71,35 @@ func getChainInfo(selector uint64) (chainInfo, error) { evmChainId, err := ChainIdFromSelector(selector) if err != nil { - return chainInfo{}, fmt.Errorf("failed to get %v chain ID from selector %d: %w", family, selector, err) + return ChainInfo{}, fmt.Errorf("failed to get %v chain ID from selector %d: %w", family, selector, err) } details, exist := evmChainIdToChainSelector[evmChainId] if !exist { - return chainInfo{}, fmt.Errorf("invalid chain id %d for %s", evmChainId, family) + return ChainInfo{}, fmt.Errorf("invalid chain id %d for %s", evmChainId, family) } - return chainInfo{ + return ChainInfo{ Family: family, ChainID: fmt.Sprintf("%d", evmChainId), ChainDetails: details, }, nil } + // check if the chain exist in extraChains_evm, return if it does + for _, chain := range csObj.ExtraChains_evm { + if chain.ChainDetails.ChainSelector == selector { + return ChainInfo{ + Family: FamilyEVM, // currently assumes every override is EVM chain + ChainID: chain.ChainID, + ChainDetails: ChainDetails{ + ChainSelector: chain.ChainDetails.ChainSelector, + ChainName: chain.ChainDetails.ChainName, + }, + }, nil + } + } + // check solana _, exist = solanaChainsBySelector[selector] if exist { @@ -50,20 +107,19 @@ func getChainInfo(selector uint64) (chainInfo, error) { chainID, err := SolanaChainIdFromSelector(selector) if err != nil { - return chainInfo{}, fmt.Errorf("failed to get %s chain ID from selector %d: %w", chainID, selector, err) + return ChainInfo{}, fmt.Errorf("failed to get %s chain ID from selector %d: %w", chainID, selector, err) } details, exist := solanaChainIdToChainSelector[chainID] if !exist { - return chainInfo{}, fmt.Errorf("invalid chain id %s for %s", chainID, family) + return ChainInfo{}, fmt.Errorf("invalid chain id %s for %s", chainID, family) } - return chainInfo{ + return ChainInfo{ Family: family, ChainID: chainID, ChainDetails: details, }, nil - } // check aptos @@ -73,15 +129,15 @@ func getChainInfo(selector uint64) (chainInfo, error) { chainID, err := AptosChainIdFromSelector(selector) if err != nil { - return chainInfo{}, fmt.Errorf("failed to get %v chain ID from selector %d: %w", chainID, selector, err) + return ChainInfo{}, fmt.Errorf("failed to get %v chain ID from selector %d: %w", chainID, selector, err) } details, exist := aptosSelectorsMap[chainID] if !exist { - return chainInfo{}, fmt.Errorf("invalid chain id %d for %s", chainID, family) + return ChainInfo{}, fmt.Errorf("invalid chain id %d for %s", chainID, family) } - return chainInfo{ + return ChainInfo{ Family: family, ChainID: fmt.Sprintf("%d", chainID), ChainDetails: details, @@ -95,43 +151,43 @@ func getChainInfo(selector uint64) (chainInfo, error) { chainID, err := TronChainIdFromSelector(selector) if err != nil { - return chainInfo{}, fmt.Errorf("failed to get %v chain ID from selector %d: %w", chainID, selector, err) + return ChainInfo{}, fmt.Errorf("failed to get %v chain ID from selector %d: %w", chainID, selector, err) } details, exist := tronSelectorsMap[chainID] if !exist { - return chainInfo{}, fmt.Errorf("invalid chain id %d for %s", chainID, family) + return ChainInfo{}, fmt.Errorf("invalid chain id %d for %s", chainID, family) } - return chainInfo{ + return ChainInfo{ Family: family, ChainID: fmt.Sprintf("%d", chainID), ChainDetails: details, }, nil } - return chainInfo{}, fmt.Errorf("unknown chain selector %d", selector) + return ChainInfo{}, fmt.Errorf("unknown chain selector %d", selector) } -func GetSelectorFamily(selector uint64) (string, error) { - chainInfo, err := getChainInfo(selector) +func (obj *ChainSelectorsObj) GetSelectorFamily(selector uint64) (string, error) { + ChainInfo, err := getChainInfo(selector, obj) if err != nil { return "", fmt.Errorf("unknown chain selector %d", selector) } - return chainInfo.Family, nil + return ChainInfo.Family, nil } -func GetChainIDFromSelector(selector uint64) (string, error) { - chainInfo, err := getChainInfo(selector) +func (obj *ChainSelectorsObj) GetChainIDFromSelector(selector uint64) (string, error) { + ChainInfo, err := getChainInfo(selector, obj) if err != nil { return "", fmt.Errorf("unknown chain selector %d", selector) } - return chainInfo.ChainID, nil + return ChainInfo.ChainID, nil } -func GetChainDetailsByChainIDAndFamily(chainID string, family string) (ChainDetails, error) { +func (obj *ChainSelectorsObj) GetChainDetailsByChainIDAndFamily(chainID string, family string) (ChainDetails, error) { switch family { case FamilyEVM: evmChainId, err := strconv.ParseUint(chainID, 10, 64) @@ -141,6 +197,12 @@ func GetChainDetailsByChainIDAndFamily(chainID string, family string) (ChainDeta details, exist := evmChainIdToChainSelector[evmChainId] if !exist { + // Iterate through ExtraChains_evm to find a valid ChainDetails if it doesnot already exist + for _, extra := range obj.ExtraChains_evm { + if extra.ChainDetails.ChainSelector != 0 { + return extra.ChainDetails, nil // Return first valid ExtraChain found + } + } return ChainDetails{}, fmt.Errorf("invalid chain id %s for %s", chainID, family) } diff --git a/selectors.yml b/selectors.yml index 26d10fc..0d5c719 100644 --- a/selectors.yml +++ b/selectors.yml @@ -278,6 +278,9 @@ selectors: 4801: selector: 5299555114858065850 name: "ethereum-testnet-sepolia-worldchain-1" + 999999999: + selector: 1293555114858065859 + name: "zora-testnet" # Mainnets 1: diff --git a/selectors_aptos.yml b/selectors_aptos.yml index 6012a4e..74dac76 100644 --- a/selectors_aptos.yml +++ b/selectors_aptos.yml @@ -8,3 +8,6 @@ selectors: 4: name: aptos-localnet selector: 4457093679053095497 + 5: + name: 'sish-testnet' + selector: 7953668971247136127 \ No newline at end of file diff --git a/solana_test.go b/solana_test.go index 8a664b9..0501e7a 100644 --- a/solana_test.go +++ b/solana_test.go @@ -56,7 +56,9 @@ func Test_YmlAreValid(t *testing.T) { func Test_SolanaChainSelectors(t *testing.T) { for selector, chain := range solanaChainsBySelector { - family, err := GetSelectorFamily(selector) + csObj, err := NewChainSelectorsObj(ChainInfo{}) + require.NoError(t, err) + family, err := csObj.GetSelectorFamily(selector) require.NoError(t, err, "selector %v should be returned as solana family, but received %v", selector, err) @@ -77,7 +79,10 @@ func Test_SolanaChainSelectors(t *testing.T) { func Test_SolanaGetChainDetailsByChainIDAndFamily(t *testing.T) { for k, v := range solanaSelectorsMap { - details, err := GetChainDetailsByChainIDAndFamily(k, FamilySolana) + csObj, err := NewChainSelectorsObj(ChainInfo{}) + assert.NoError(t, err) + + details, err := csObj.GetChainDetailsByChainIDAndFamily(k, FamilySolana) assert.NoError(t, err) assert.Equal(t, v, details) } @@ -85,7 +90,9 @@ func Test_SolanaGetChainDetailsByChainIDAndFamily(t *testing.T) { func Test_SolanaGetChainIDByChainSelector(t *testing.T) { for k, v := range solanaSelectorsMap { - chainID, err := GetChainIDFromSelector(v.ChainSelector) + csObj, err := NewChainSelectorsObj(ChainInfo{}) + require.NoError(t, err) + chainID, err := csObj.GetChainIDFromSelector(v.ChainSelector) assert.NoError(t, err) assert.Equal(t, chainID, fmt.Sprintf("%v", k)) } diff --git a/tron_test.go b/tron_test.go index 165c696..2014a24 100644 --- a/tron_test.go +++ b/tron_test.go @@ -55,7 +55,10 @@ func Test_TronYmlAreValid(t *testing.T) { func Test_TronChainSelectors(t *testing.T) { for selector, chainId := range tronChainIdBySelector { - family, err := GetSelectorFamily(selector) + csObj, err := NewChainSelectorsObj(ChainInfo{}) + assert.NoError(t, err) + + family, err := csObj.GetSelectorFamily(selector) require.NoError(t, err, "selector %v should be returned as tron family, but received %v", selector, err) @@ -70,7 +73,10 @@ func Test_TronChainSelectors(t *testing.T) { func Test_TronGetChainDetailsByChainIDAndFamily(t *testing.T) { for k, v := range tronSelectorsMap { - details, err := GetChainDetailsByChainIDAndFamily(fmt.Sprint(k), FamilyTron) + csObj, err := NewChainSelectorsObj(ChainInfo{}) + assert.NoError(t, err) + + details, err := csObj.GetChainDetailsByChainIDAndFamily(fmt.Sprint(k), FamilyTron) assert.NoError(t, err) assert.Equal(t, v, details) } @@ -78,7 +84,10 @@ func Test_TronGetChainDetailsByChainIDAndFamily(t *testing.T) { func Test_TronGetChainIDByChainSelector(t *testing.T) { for k, v := range tronSelectorsMap { - chainID, err := GetChainIDFromSelector(v.ChainSelector) + csObj, err := NewChainSelectorsObj(ChainInfo{}) + assert.NoError(t, err) + + chainID, err := csObj.GetChainIDFromSelector(v.ChainSelector) assert.NoError(t, err) assert.Equal(t, chainID, fmt.Sprintf("%v", k)) }