|
| 1 | +/* |
| 2 | +Package chain provides the core blockchain abstraction layer for the Chainlink Deployments Framework, |
| 3 | +supporting multiple blockchain families through a unified interface. |
| 4 | +
|
| 5 | +# Overview |
| 6 | +
|
| 7 | +The chain package serves as the foundation for blockchain interactions in the Chainlink Deployments Framework. |
| 8 | +It defines the core BlockChain interface that all blockchain implementations must satisfy, and provides |
| 9 | +a powerful collection system for managing and querying multiple chains across different blockchain families. |
| 10 | +
|
| 11 | +# Architecture |
| 12 | +
|
| 13 | +The package consists of several key components: |
| 14 | +
|
| 15 | + 1. BlockChain Interface (blockchain.go) - Core abstraction for all blockchains |
| 16 | + 2. BlockChains Collection (blockchain.go) - Container for managing multiple chains |
| 17 | + 3. Provider Interface (provider.go) - Abstraction for blockchain providers |
| 18 | + 4. Chain Family Support - Type-safe access to specific blockchain implementations |
| 19 | +
|
| 20 | +# Basic Usage |
| 21 | +
|
| 22 | +# Core BlockChain Interface |
| 23 | +
|
| 24 | +Every blockchain implementation satisfies the BlockChain interface: |
| 25 | +
|
| 26 | + import "github.com/smartcontractkit/chainlink-deployments-framework/chain" |
| 27 | +
|
| 28 | + // BlockChain interface provides basic chain information |
| 29 | + type BlockChain interface { |
| 30 | + String() string // Human-readable chain info |
| 31 | + Name() string // Chain name |
| 32 | + ChainSelector() uint64 // Unique chain identifier |
| 33 | + Family() string // Blockchain family (evm, solana, etc.) |
| 34 | + } |
| 35 | +
|
| 36 | + // Example usage with any blockchain |
| 37 | + func printChainInfo(bc chain.BlockChain) { |
| 38 | + fmt.Printf("Chain: %s\n", bc.String()) // "Ethereum Mainnet (1)" |
| 39 | + fmt.Printf("Name: %s\n", bc.Name()) // "Ethereum Mainnet" |
| 40 | + fmt.Printf("Selector: %d\n", bc.ChainSelector()) // 1 |
| 41 | + fmt.Printf("Family: %s\n", bc.Family()) // "evm" |
| 42 | + } |
| 43 | +
|
| 44 | +# BlockChains Collection |
| 45 | +
|
| 46 | +The BlockChains collection provides powerful querying and management capabilities: |
| 47 | +
|
| 48 | + import ( |
| 49 | + "github.com/smartcontractkit/chainlink-deployments-framework/chain" |
| 50 | + "github.com/smartcontractkit/chainlink-deployments-framework/chain/evm" |
| 51 | + "github.com/smartcontractkit/chainlink-deployments-framework/chain/solana" |
| 52 | + ) |
| 53 | +
|
| 54 | + // Create a collection of chains |
| 55 | + := chain.NewBlockChains(map[uint64]chain.BlockChain{ |
| 56 | + 1: evmMainnet, // Ethereum mainnet |
| 57 | + 1151111081099710: solanaMainnet, // Solana mainnet |
| 58 | + 42161: arbChain, // Arbitrum |
| 59 | + }) |
| 60 | +
|
| 61 | + // Check if chains exist |
| 62 | + if chains.Exists(1) { |
| 63 | + fmt.Println("Ethereum mainnet is available") |
| 64 | + } |
| 65 | +
|
| 66 | + // Check multiple chains at once |
| 67 | + if chains.ExistsN(1, 42161) { |
| 68 | + fmt.Println("Both Ethereum and Arbitrum are available") |
| 69 | + } |
| 70 | +
|
| 71 | +# Family-Specific Chain Access |
| 72 | +
|
| 73 | +Retrieve chains by their blockchain family with type safety: |
| 74 | +
|
| 75 | + // Get all EVM chains |
| 76 | + evmChains := chains.EVMChains() |
| 77 | + for selector, evmChain := range evmChains { |
| 78 | + fmt.Printf("EVM Chain %d: %s\n", selector, evmChain.String()) |
| 79 | + // evmChain is typed as evm.Chain |
| 80 | + } |
| 81 | +
|
| 82 | + // Get all Solana chains |
| 83 | + solanaChains := chains.SolanaChains() |
| 84 | + for selector, solChain := range solanaChains { |
| 85 | + fmt.Printf("Solana Chain %d: %s\n", selector, solChain.String()) |
| 86 | + // solChain is typed as solana.Chain |
| 87 | + } |
| 88 | +
|
| 89 | + // Similarly for other families |
| 90 | + aptosChains := chains.AptosChains() |
| 91 | + suiChains := chains.SuiChains() |
| 92 | + tonChains := chains.TonChains() |
| 93 | + tronChains := chains.TronChains() |
| 94 | +
|
| 95 | +# Iterating Over All Chains |
| 96 | +
|
| 97 | +Use the iterator interface to process all chains: |
| 98 | +
|
| 99 | + // Iterate over all chains |
| 100 | + for selector, blockchain := range chains.All() { |
| 101 | + fmt.Printf("Processing chain %d (%s) from family %s\n", |
| 102 | + selector, blockchain.Name(), blockchain.Family()) |
| 103 | +
|
| 104 | + // Handle each chain based on its family |
| 105 | + switch blockchain.Family() { |
| 106 | + case "evm": |
| 107 | + // Handle EVM-specific logic |
| 108 | + case "solana": |
| 109 | + // Handle Solana-specific logic |
| 110 | + case "aptos": |
| 111 | + // Handle Aptos-specific logic |
| 112 | + } |
| 113 | +
|
| 114 | +# Advanced Querying |
| 115 | +
|
| 116 | +# Chain Selector Filtering |
| 117 | +
|
| 118 | +The package provides flexible filtering options for chain selectors: |
| 119 | +
|
| 120 | + // Get all chain selectors |
| 121 | + allSelectors := chains.ListChainSelectors() |
| 122 | + fmt.Printf("All chains: %v\n", allSelectors) |
| 123 | +
|
| 124 | + // Filter by blockchain family |
| 125 | + evmSelectors := chains.ListChainSelectors( |
| 126 | + chain.WithFamily("evm"), |
| 127 | + ) |
| 128 | + fmt.Printf("EVM chains: %v\n", evmSelectors) |
| 129 | +
|
| 130 | + // Exclude specific chains |
| 131 | + filteredSelectors := chains.ListChainSelectors( |
| 132 | + chain.WithFamily("evm"), |
| 133 | + chain.WithChainSelectorsExclusion([]uint64{42161}), // Exclude Arbitrum |
| 134 | + ) |
| 135 | + fmt.Printf("EVM chains excluding Arbitrum: %v\n", filteredSelectors) |
| 136 | +
|
| 137 | + // Combine multiple families |
| 138 | + testnetSelectors := chains.ListChainSelectors( |
| 139 | + chain.WithFamily("evm"), |
| 140 | + chain.WithFamily("solana"), |
| 141 | + chain.WithChainSelectorsExclusion([]uint64{1, 1151111081099710}), // Exclude mainnets |
| 142 | + ) |
| 143 | +
|
| 144 | +# Creating Collections from Slices |
| 145 | +
|
| 146 | + // Create from slice of chains |
| 147 | + chainList := []chain.BlockChain{evmChain, solanaChain, aptosChain} |
| 148 | + chainsFromSlice := chain.NewBlockChainsFromSlice(chainList) |
| 149 | +
|
| 150 | + // Equivalent to map-based creation |
| 151 | + chainsFromMap := chain.NewBlockChains(map[uint64]chain.BlockChain{ |
| 152 | + evmChain.ChainSelector(): evmChain, |
| 153 | + solanaChain.ChainSelector(): solanaChain, |
| 154 | + aptosChain.ChainSelector(): aptosChain, |
| 155 | + }) |
| 156 | +
|
| 157 | +# Provider System |
| 158 | +
|
| 159 | +The Provider interface enables pluggable blockchain implementations: |
| 160 | +
|
| 161 | + import "context" |
| 162 | +
|
| 163 | + // Provider interface for blockchain providers |
| 164 | + type Provider interface { |
| 165 | + Initialize(ctx context.Context) (BlockChain, error) |
| 166 | + Name() string |
| 167 | + ChainSelector() uint64 |
| 168 | + BlockChain() BlockChain |
| 169 | + } |
| 170 | +
|
| 171 | + // Example provider usage |
| 172 | + func setupChain(provider chain.Provider) (chain.BlockChain, error) { |
| 173 | + ctx := context.Background() |
| 174 | +
|
| 175 | + // Initialize the provider |
| 176 | + blockchain, err := provider.Initialize(ctx) |
| 177 | + if err != nil { |
| 178 | + return nil, fmt.Errorf("failed to initialize %s: %w", |
| 179 | + provider.Name(), err) |
| 180 | + } |
| 181 | +
|
| 182 | + fmt.Printf("Initialized %s chain with selector %d\n", |
| 183 | + provider.Name(), provider.ChainSelector()) |
| 184 | +
|
| 185 | + return blockchain, nil |
| 186 | + } |
| 187 | +
|
| 188 | +# Integration with Deployment Framework |
| 189 | +
|
| 190 | +The chain package integrates seamlessly with the broader deployment framework: |
| 191 | +
|
| 192 | + import "github.com/smartcontractkit/chainlink-deployments-framework/deployment" |
| 193 | +
|
| 194 | + // Create deployment environment with multiple chains |
| 195 | + env := &deployment.Environment{ |
| 196 | + Chains: chains, // BlockChains collection |
| 197 | + // ... other environment fields |
| 198 | + } |
| 199 | +
|
| 200 | + // Access chains in deployment operations |
| 201 | + evmChains := env.Chains.EVMChains() |
| 202 | + solanaChains := env.Chains.SolanaChains() |
| 203 | +*/ |
| 204 | +package chain |
0 commit comments