From f88cde454dbab5e7c94966accf9fa7f3139a55a6 Mon Sep 17 00:00:00 2001 From: Chase Coleman Date: Fri, 19 Sep 2025 14:58:51 +0000 Subject: [PATCH 1/2] ENH: Update packages so that they can be generated via JSON files --- README.md | 164 +++++++- data/chains.json | 513 +++++++++++++++++++++++++ data/schemas/chains-schema.json | 158 ++++++++ data/schemas/tokens-schema.json | 60 +++ data/tokens.json | 631 +++++++++++++++++++++++++++++++ package.json | 11 +- scripts/generate-all.cjs | 28 ++ scripts/generate-python.cjs | 339 +++++++++++++++++ scripts/generate-rust.cjs | 319 ++++++++++++++++ scripts/generate-typescript.cjs | 183 +++++++++ scripts/validate-data.cjs | 59 +++ scripts/watch-data.cjs | 41 ++ src/index.ts | 2 - src/networks.ts | 527 -------------------------- src/tokens.ts | 642 -------------------------------- 15 files changed, 2502 insertions(+), 1175 deletions(-) create mode 100644 data/chains.json create mode 100644 data/schemas/chains-schema.json create mode 100644 data/schemas/tokens-schema.json create mode 100644 data/tokens.json create mode 100755 scripts/generate-all.cjs create mode 100755 scripts/generate-python.cjs create mode 100755 scripts/generate-rust.cjs create mode 100755 scripts/generate-typescript.cjs create mode 100755 scripts/validate-data.cjs create mode 100755 scripts/watch-data.cjs delete mode 100644 src/index.ts delete mode 100644 src/networks.ts delete mode 100644 src/tokens.ts diff --git a/README.md b/README.md index 618bb88..989f1e6 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,163 @@ -# Across Constants +# Across Protocol Constants -Export commonly used constant files +Multi-language constants package for chain and token information used by the Across Protocol. + +## šŸ“¦ Available Packages + +This repository generates constants packages for multiple programming languages from a single JSON source of truth: + +- **TypeScript/JavaScript**: Published to npm as `@across-protocol/constants` +- **Python**: Available as `across-constants` (generated package) +- **Rust**: Available as `across-constants` (generated crate) + +## šŸ—ļø Architecture + +### Single Source of Truth + +All chain and token information is maintained in JSON files: + +- `data/chains.json` - Chain IDs, network configurations, RPC endpoints +- `data/tokens.json` - Token symbols, addresses, decimals, CoinGecko IDs + +### Code Generation + +Language-specific packages are automatically generated from the JSON data using: + +- `scripts/generate-typescript.js` - Generates TypeScript constants +- `scripts/generate-python.js` - Generates Python package +- `scripts/generate-rust.js` - Generates Rust crate + +### Type Safety & Validation + +- JSON Schema validation ensures data consistency +- Generated code maintains strict typing in each language +- Constants are preserved (readonly/const/static) + +## šŸš€ Usage + +### TypeScript/JavaScript + +```typescript +import { CHAIN_IDs, TOKEN_SYMBOLS_MAP, ChainFamily } from "@across-protocol/constants" + +const arbitrumChainId = CHAIN_IDs.ARBITRUM // 42161 +const usdcConfig = TOKEN_SYMBOLS_MAP.USDC +const usdcArbitrumAddress = usdcConfig.addresses[CHAIN_IDs.ARBITRUM] +``` + +### Python + +```python +from across_constants import CHAIN_IDS, TOKEN_SYMBOLS_MAP, ChainFamily + +arbitrum_chain_id = CHAIN_IDS["ARBITRUM"] # 42161 +usdc_config = TOKEN_SYMBOLS_MAP["USDC"] +usdc_arbitrum_address = usdc_config.addresses[arbitrum_chain_id] +``` + +### Rust + +```rust +use across_constants::{MAINNET_CHAIN_IDS, TOKEN_SYMBOLS_MAP}; + +let arbitrum_chain_id = MAINNET_CHAIN_IDS.get("ARBITRUM").unwrap(); // &42161 +let usdc_config = TOKEN_SYMBOLS_MAP.get("USDC").unwrap(); +let usdc_arbitrum_address = usdc_config.addresses.get(arbitrum_chain_id).unwrap(); +``` + +## šŸ› ļø Development + +### Setup + +```bash +yarn install +``` + +### Generate All Packages + +```bash +yarn generate +``` + +### Generate Specific Language + +```bash +yarn generate:typescript +yarn generate:python +yarn generate:rust +``` + +### Validate Data + +```bash +yarn validate +``` + +### Watch Mode (Auto-regenerate) + +```bash +yarn watch +``` + +### Build TypeScript Package + +```bash +yarn build +``` + +## šŸ“‚ Project Structure + +``` +ā”œā”€ā”€ data/ # Source of truth JSON data +│ ā”œā”€ā”€ chains.json # Chain configurations +│ ā”œā”€ā”€ tokens.json # Token configurations +│ └── schemas/ # JSON Schema validation +ā”œā”€ā”€ scripts/ # Code generation scripts +│ ā”œā”€ā”€ generate-all.js # Generate all languages +│ ā”œā”€ā”€ generate-typescript.js # TypeScript generator +│ ā”œā”€ā”€ generate-python.js # Python generator +│ ā”œā”€ā”€ generate-rust.js # Rust generator +│ ā”œā”€ā”€ validate-data.js # Schema validation +│ └── watch-data.js # File watcher +ā”œā”€ā”€ src-generated/ # Generated code output +│ ā”œā”€ā”€ typescript/ # Generated TS files +│ ā”œā”€ā”€ python/ # Generated Python package +│ └── rust/ # Generated Rust crate +└── src/ # TypeScript source (copied from generated) +``` + +## ✨ Benefits + +- **Single Source of Truth**: Update once, generate everywhere +- **Type Safety**: Strict typing preserved across all languages +- **Consistency**: Guaranteed consistency across language packages +- **Maintainability**: Easy to add new chains/tokens or support new languages +- **Validation**: JSON Schema ensures data integrity +- **Performance**: Constants are compile-time optimized in each language + +## šŸ”„ Adding New Data + +### Adding a New Chain + +1. Edit `data/chains.json` +2. Add chain ID to appropriate section (mainnet/testnet) +3. Add network configuration +4. Run `yarn generate` to update all packages + +### Adding a New Token + +1. Edit `data/tokens.json` +2. Add token configuration with addresses per chain +3. Add CoinGecko ID for pricing +4. Run `yarn generate` to update all packages + +### Adding a New Language + +1. Create `scripts/generate-[language].js` +2. Implement language-specific code generation +3. Add language target to `scripts/generate-all.js` +4. Update documentation + +## šŸ“„ License + +AGPL-3.0-only diff --git a/data/chains.json b/data/chains.json new file mode 100644 index 0000000..624bfcf --- /dev/null +++ b/data/chains.json @@ -0,0 +1,513 @@ +{ + "$schema": "./schemas/chains-schema.json", + "chainFamilies": { + "NONE": 0, + "OP_STACK": 1, + "ORBIT": 2, + "ZK_STACK": 3, + "SVM": 4 + }, + "testnetSepoliaChainIds": { + "ARBITRUM_SEPOLIA": 421614, + "BASE_SEPOLIA": 84532, + "BLAST_SEPOLIA": 168587773, + "BOB_SEPOLIA": 808813, + "HYPEREVM_TESTNET": 998, + "INK_SEPOLIA": 763373, + "TATARA": 129399, + "LENS_SEPOLIA": 37111, + "LISK_SEPOLIA": 4202, + "MODE_SEPOLIA": 919, + "OPTIMISM_SEPOLIA": 11155420, + "POLYGON_AMOY": 80002, + "SCROLL_SEPOLIA": 534351, + "SEPOLIA": 11155111, + "UNICHAIN_SEPOLIA": 1301, + "ZK_SYNC_SEPOLIA": 300 + }, + "testnetChainIds": { + "ARBITRUM_SEPOLIA": 421614, + "BASE_SEPOLIA": 84532, + "BLAST_SEPOLIA": 168587773, + "BOB_SEPOLIA": 808813, + "HYPEREVM_TESTNET": 998, + "INK_SEPOLIA": 763373, + "TATARA": 129399, + "LENS_SEPOLIA": 37111, + "LISK_SEPOLIA": 4202, + "MODE_SEPOLIA": 919, + "OPTIMISM_SEPOLIA": 11155420, + "POLYGON_AMOY": 80002, + "SCROLL_SEPOLIA": 534351, + "SEPOLIA": 11155111, + "UNICHAIN_SEPOLIA": 1301, + "ZK_SYNC_SEPOLIA": 300, + "SOLANA_DEVNET": 133268194659241 + }, + "mainnetChainIds": { + "ALEPH_ZERO": 41455, + "ARBITRUM": 42161, + "BASE": 8453, + "BLAST": 81457, + "BOB": 60808, + "BSC": 56, + "BOBA": 288, + "HYPEREVM": 999, + "INK": 57073, + "LENS": 232, + "LINEA": 59144, + "LISK": 1135, + "MAINNET": 1, + "MODE": 34443, + "OPTIMISM": 10, + "POLYGON": 137, + "REDSTONE": 690, + "SCROLL": 534352, + "SONEIUM": 1868, + "SUPERSEED": 5330, + "UNICHAIN": 130, + "WORLD_CHAIN": 480, + "ZK_SYNC": 324, + "ZORA": 7777777, + "SOLANA": 34268394551451 + }, + "productionOftEids": { + "ARBITRUM": 30110, + "BASE": 30184, + "BLAST": 30243, + "BSC": 30102, + "HYPEREVM": 30367, + "MAINNET": 30101, + "OPTIMISM": 30111, + "POLYGON": 30109, + "SONEIUM": 30340, + "UNICHAIN": 30320, + "WORLD_CHAIN": 30319, + "SOLANA": 30168 + }, + "testnetOftEids": { + "ARBITRUM_SEPOLIA": 40231, + "BASE_SEPOLIA": 40245, + "OPTIMISM_SEPOLIA": 40232, + "HYPEREVM_TESTNET": 40362, + "POLYGON_AMOY": 40267, + "SEPOLIA": 40161, + "UNICHAIN_SEPOLIA": 40333, + "SOLANA_DEVNET": 40168 + }, + "hyperlaneDomainIdOverrides": { + "SOLANA": 1399811149, + "SOLANA_DEVNET": 1399811151 + }, + "constants": { + "CCTP_NO_DOMAIN": -1, + "OFT_NO_EID": -1, + "HYPERLANE_NO_DOMAIN_ID": -1 + }, + "networks": { + "production": { + "41455": { + "name": "Aleph Zero", + "family": 2, + "nativeToken": "AZERO", + "publicRPC": "https://rpc.alephzero.raas.gelato.cloud", + "blockExplorer": "https://evm-explorer.alephzero.org", + "cctpDomain": -1, + "oftEid": -1, + "hypDomainId": -1 + }, + "42161": { + "name": "Arbitrum One", + "family": 0, + "nativeToken": "ETH", + "publicRPC": "https://arb1.arbitrum.io/rpc", + "blockExplorer": "https://arbiscan.io", + "cctpDomain": 3, + "oftEid": 30110, + "hypDomainId": 42161 + }, + "8453": { + "name": "Base", + "family": 1, + "nativeToken": "ETH", + "publicRPC": "https://mainnet.base.org", + "blockExplorer": "https://basescan.org", + "cctpDomain": 6, + "oftEid": 30184, + "hypDomainId": 8453 + }, + "81457": { + "name": "Blast", + "family": 1, + "nativeToken": "ETH", + "publicRPC": "https://rpc.blast.io", + "blockExplorer": "https://blastscan.io", + "cctpDomain": -1, + "oftEid": 30243, + "hypDomainId": 81457 + }, + "56": { + "name": "BNB Smart Chain", + "family": 0, + "nativeToken": "BNB", + "publicRPC": "https://bsc-dataseed1.binance.org", + "blockExplorer": "https://bscscan.com", + "cctpDomain": -1, + "oftEid": 30102, + "hypDomainId": 56 + }, + "288": { + "name": "Boba", + "family": 1, + "nativeToken": "ETH", + "publicRPC": "https://mainnet.boba.network", + "blockExplorer": "https://blockexplorer.boba.network", + "cctpDomain": -1, + "oftEid": -1, + "hypDomainId": -1 + }, + "999": { + "name": "HyperEVM", + "family": 0, + "nativeToken": "HYPE", + "publicRPC": "https://rpc.hyperliquid.xyz/evm", + "blockExplorer": "https://hyperevmscan.io/", + "cctpDomain": 19, + "oftEid": 30367, + "hypDomainId": 999 + }, + "130": { + "name": "Unichain", + "family": 1, + "nativeToken": "ETH", + "publicRPC": "https://mainnet.unichain.org/", + "blockExplorer": "https://uniscan.xyz", + "cctpDomain": 10, + "oftEid": 30320, + "hypDomainId": 130 + }, + "57073": { + "name": "Ink", + "family": 1, + "nativeToken": "ETH", + "publicRPC": "https://rpc-gel.inkonchain.com", + "blockExplorer": "https://explorer.inkonchain.com", + "cctpDomain": -1, + "oftEid": -1, + "hypDomainId": 57073 + }, + "129399": { + "name": "Tatara", + "family": 0, + "nativeToken": "ETH", + "publicRPC": "https://rpc.tatara.katanarpc.com/", + "blockExplorer": "https://explorer.tatara.katana.network", + "cctpDomain": -1, + "oftEid": -1, + "hypDomainId": -1 + }, + "232": { + "name": "Lens", + "family": 3, + "nativeToken": "WGHO", + "publicRPC": "https://api.lens.matterhosted.dev", + "blockExplorer": "https://explorer.lens.xyz", + "cctpDomain": -1, + "oftEid": -1, + "hypDomainId": -1 + }, + "59144": { + "name": "Linea", + "family": 0, + "nativeToken": "ETH", + "publicRPC": "https://rpc.linea.build", + "blockExplorer": "https://lineascan.build", + "cctpDomain": 11, + "oftEid": -1, + "hypDomainId": 59144 + }, + "1135": { + "name": "Lisk", + "family": 1, + "nativeToken": "ETH", + "publicRPC": "https://rpc.api.lisk.com", + "blockExplorer": "https://blockscout.lisk.com", + "cctpDomain": -1, + "oftEid": -1, + "hypDomainId": -1 + }, + "1": { + "name": "Mainnet", + "family": 0, + "nativeToken": "ETH", + "publicRPC": "https://eth.llamarpc.com", + "blockExplorer": "https://etherscan.io", + "cctpDomain": 0, + "oftEid": 30101, + "hypDomainId": 1 + }, + "34443": { + "name": "Mode", + "family": 1, + "nativeToken": "ETH", + "publicRPC": "https://mainnet.mode.network", + "blockExplorer": "https://explorer.mode.network", + "cctpDomain": -1, + "oftEid": -1, + "hypDomainId": 34443 + }, + "10": { + "name": "Optimism", + "family": 1, + "nativeToken": "ETH", + "publicRPC": "https://mainnet.optimism.io", + "blockExplorer": "https://optimistic.etherscan.io", + "cctpDomain": 2, + "oftEid": 30111, + "hypDomainId": 10 + }, + "137": { + "name": "Polygon", + "family": 0, + "nativeToken": "MATIC", + "publicRPC": "https://polygon-rpc.com", + "blockExplorer": "https://polygonscan.com", + "cctpDomain": 7, + "oftEid": 30109, + "hypDomainId": 137 + }, + "690": { + "name": "Redstone", + "family": 1, + "nativeToken": "ETH", + "publicRPC": "https://rpc.redstonechain.com", + "blockExplorer": "https://explorer.redstone.xyz", + "cctpDomain": -1, + "oftEid": -1, + "hypDomainId": 690 + }, + "534352": { + "name": "Scroll", + "family": 0, + "nativeToken": "ETH", + "publicRPC": "https://rpc.scroll.io", + "blockExplorer": "https://scrollscan.com", + "cctpDomain": -1, + "oftEid": -1, + "hypDomainId": -1 + }, + "34268394551451": { + "name": "Solana", + "family": 4, + "nativeToken": "SOL", + "publicRPC": "https://api.mainnet-beta.solana.com", + "blockExplorer": "https://solscan.io", + "cctpDomain": 5, + "oftEid": 30168, + "hypDomainId": 1399811149 + }, + "1868": { + "name": "Soneium", + "family": 1, + "nativeToken": "ETH", + "publicRPC": "https://rpc.soneium.org", + "blockExplorer": "https://soneium.blockscout.com", + "cctpDomain": -1, + "oftEid": 30340, + "hypDomainId": -1 + }, + "5330": { + "name": "Superseed", + "family": 1, + "nativeToken": "ETH", + "publicRPC": "https://mainnet.superseed.xyz", + "blockExplorer": "", + "cctpDomain": -1, + "oftEid": -1, + "hypDomainId": -1 + }, + "480": { + "name": "World Chain", + "family": 1, + "nativeToken": "ETH", + "publicRPC": "https://worldchain-mainnet.g.alchemy.com/public", + "blockExplorer": "https://worldchain-mainnet-explorer.alchemy.com", + "cctpDomain": 14, + "oftEid": 30319, + "hypDomainId": 480 + }, + "324": { + "name": "zkSync", + "family": 0, + "nativeToken": "ETH", + "publicRPC": "https://mainnet.era.zksync.io", + "blockExplorer": "https://era.zksync.network", + "cctpDomain": -1, + "oftEid": -1, + "hypDomainId": 324 + }, + "7777777": { + "name": "Zora", + "family": 1, + "nativeToken": "ETH", + "publicRPC": "https://rpc.zora.energy", + "blockExplorer": "https://zorascan.xyz", + "cctpDomain": -1, + "oftEid": -1, + "hypDomainId": -1 + } + }, + "testnet": { + "421614": { + "name": "Arbitrum Sepolia", + "family": 0, + "nativeToken": "ETH", + "publicRPC": "https://sepolia-rollup.arbitrum.io/rpc", + "blockExplorer": "https://sepolia.arbiscan.io", + "cctpDomain": 3, + "oftEid": 40231, + "hypDomainId": 421614 + }, + "84532": { + "name": "Base Sepolia", + "family": 1, + "nativeToken": "ETH", + "publicRPC": "https://sepolia.base.org", + "blockExplorer": "https://sepolia.basescan.org", + "cctpDomain": 6, + "oftEid": 40245, + "hypDomainId": 84532 + }, + "168587773": { + "name": "Blast Sepolia", + "family": 1, + "nativeToken": "ETH", + "publicRPC": "https://sepolia.blast.io", + "blockExplorer": "https://sepolia.blastscan.io", + "cctpDomain": -1, + "oftEid": -1, + "hypDomainId": 168587773 + }, + "808813": { + "name": "BOB Sepolia", + "family": 1, + "nativeToken": "ETH", + "publicRPC": "https://bob-sepolia.rpc.gobob.xyz", + "blockExplorer": "https://bob-sepolia.explorer.gobob.xyz", + "cctpDomain": -1, + "oftEid": -1, + "hypDomainId": -1 + }, + "998": { + "name": "HyperEVM Testnet", + "family": 0, + "nativeToken": "HYPE", + "publicRPC": "https://rpc.hyperliquid-testnet.xyz/evm", + "blockExplorer": "https://testnet.purrsec.com/", + "cctpDomain": 19, + "oftEid": 40362, + "hypDomainId": 998 + }, + "37111": { + "name": "Lens Sepolia", + "family": 3, + "nativeToken": "GRASS", + "publicRPC": "https://rpc.testnet.lens.dev", + "blockExplorer": "https://block-explorer.testnet.lens.dev", + "cctpDomain": -1, + "oftEid": -1, + "hypDomainId": -1 + }, + "4202": { + "name": "Lisk Sepolia", + "family": 1, + "nativeToken": "ETH", + "publicRPC": "https://rpc.sepolia-api.lisk.com", + "blockExplorer": "https://sepolia-blockscout.lisk.com", + "cctpDomain": -1, + "oftEid": -1, + "hypDomainId": -1 + }, + "919": { + "name": "Mode Sepolia", + "family": 1, + "nativeToken": "ETH", + "publicRPC": "https://sepolia.mode.network", + "blockExplorer": "https://sepolia.explorer.mode.network", + "cctpDomain": -1, + "oftEid": -1, + "hypDomainId": 919 + }, + "11155420": { + "name": "Optimism Sepolia", + "family": 1, + "nativeToken": "ETH", + "publicRPC": "https://sepolia.optimism.io", + "blockExplorer": "https://sepolia-optimism.etherscan.io", + "cctpDomain": 2, + "oftEid": 40232, + "hypDomainId": 11155420 + }, + "80002": { + "name": "Polygon Amoy", + "family": 0, + "nativeToken": "MATIC", + "publicRPC": "https://rpc-amoy.polygon.technology", + "blockExplorer": "https://amoy.polygonscan.com", + "cctpDomain": 7, + "oftEid": 40267, + "hypDomainId": 80002 + }, + "534351": { + "name": "Scroll Sepolia", + "family": 0, + "nativeToken": "ETH", + "publicRPC": "https://sepolia-rpc.scroll.io", + "blockExplorer": "https://sepolia.scrollscan.com", + "cctpDomain": -1, + "oftEid": -1, + "hypDomainId": -1 + }, + "11155111": { + "name": "Sepolia", + "family": 0, + "nativeToken": "ETH", + "publicRPC": "https://sepolia.drpc.org", + "blockExplorer": "https://sepolia.etherscan.io", + "cctpDomain": 0, + "oftEid": 40161, + "hypDomainId": 11155111 + }, + "133268194659241": { + "name": "Solana Devnet", + "family": 4, + "nativeToken": "SOL", + "publicRPC": "https://api.devnet.solana.com", + "blockExplorer": "https://explorer.solana.com/?cluster=devnet", + "cctpDomain": 5, + "oftEid": 40168, + "hypDomainId": 1399811151 + }, + "1301": { + "name": "Unichain Sepolia", + "family": 1, + "nativeToken": "ETH", + "publicRPC": "https://sepolia.unichain.org", + "blockExplorer": "https://sepolia.uniscan.xyz", + "cctpDomain": 10, + "oftEid": 40333, + "hypDomainId": 1301 + }, + "300": { + "name": "zkSync Sepolia", + "family": 0, + "nativeToken": "ETH", + "publicRPC": "https://sepolia.era.zksync.dev", + "blockExplorer": "https://sepolia-era.zksync.network", + "cctpDomain": -1, + "oftEid": -1, + "hypDomainId": 300 + } + } + } +} \ No newline at end of file diff --git a/data/schemas/chains-schema.json b/data/schemas/chains-schema.json new file mode 100644 index 0000000..e982b4c --- /dev/null +++ b/data/schemas/chains-schema.json @@ -0,0 +1,158 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Chain Information Schema", + "description": "Schema for blockchain network configuration data", + "type": "object", + "properties": { + "chainFamilies": { + "type": "object", + "patternProperties": { + "^[A-Z_]+$": { + "type": "integer", + "minimum": 0 + } + } + }, + "testnetSepoliaChainIds": { + "type": "object", + "patternProperties": { + "^[A-Z_]+$": { + "type": "integer", + "minimum": 0 + } + } + }, + "testnetChainIds": { + "type": "object", + "patternProperties": { + "^[A-Z_]+$": { + "type": "integer", + "minimum": 0 + } + } + }, + "mainnetChainIds": { + "type": "object", + "patternProperties": { + "^[A-Z_]+$": { + "type": "integer", + "minimum": 0 + } + } + }, + "productionOftEids": { + "type": "object", + "patternProperties": { + "^[A-Z_]+$": { + "type": "integer", + "minimum": 0 + } + } + }, + "testnetOftEids": { + "type": "object", + "patternProperties": { + "^[A-Z_]+$": { + "type": "integer", + "minimum": 0 + } + } + }, + "hyperlaneDomainIdOverrides": { + "type": "object", + "patternProperties": { + "^[A-Z_]+$": { + "type": "integer" + } + } + }, + "constants": { + "type": "object", + "properties": { + "CCTP_NO_DOMAIN": { + "type": "integer" + }, + "OFT_NO_EID": { + "type": "integer" + }, + "HYPERLANE_NO_DOMAIN_ID": { + "type": "integer" + } + }, + "required": ["CCTP_NO_DOMAIN", "OFT_NO_EID", "HYPERLANE_NO_DOMAIN_ID"] + }, + "networks": { + "type": "object", + "properties": { + "production": { + "$ref": "#/definitions/networkMap" + }, + "testnet": { + "$ref": "#/definitions/networkMap" + } + }, + "required": ["production", "testnet"] + } + }, + "required": [ + "chainFamilies", + "testnetSepoliaChainIds", + "testnetChainIds", + "mainnetChainIds", + "productionOftEids", + "testnetOftEids", + "hyperlaneDomainIdOverrides", + "constants", + "networks" + ], + "definitions": { + "networkMap": { + "type": "object", + "patternProperties": { + "^[0-9]+$": { + "$ref": "#/definitions/networkConfig" + } + } + }, + "networkConfig": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "family": { + "type": "integer", + "minimum": 0 + }, + "nativeToken": { + "type": "string" + }, + "publicRPC": { + "type": "string" + }, + "blockExplorer": { + "type": "string" + }, + "cctpDomain": { + "type": "integer" + }, + "oftEid": { + "type": "integer" + }, + "hypDomainId": { + "type": "integer" + } + }, + "required": [ + "name", + "family", + "nativeToken", + "publicRPC", + "blockExplorer", + "cctpDomain", + "oftEid", + "hypDomainId" + ] + } + } +} \ No newline at end of file diff --git a/data/schemas/tokens-schema.json b/data/schemas/tokens-schema.json new file mode 100644 index 0000000..e11601b --- /dev/null +++ b/data/schemas/tokens-schema.json @@ -0,0 +1,60 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Token Information Schema", + "description": "Schema for cryptocurrency token configuration data", + "type": "object", + "properties": { + "tokens": { + "type": "object", + "patternProperties": { + "^[A-Z0-9._-]+$": { + "$ref": "#/definitions/tokenConfig" + } + } + }, + "tokenEquivalenceRemapping": { + "type": "object", + "patternProperties": { + "^[A-Z0-9._-]+$": { + "type": "string" + } + } + } + }, + "required": ["tokens", "tokenEquivalenceRemapping"], + "definitions": { + "tokenConfig": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "symbol": { + "type": "string" + }, + "decimals": { + "type": "integer", + "minimum": 0, + "maximum": 255 + }, + "addresses": { + "type": "object", + "patternProperties": { + "^[0-9]+$": { + "type": "string" + } + } + }, + "coingeckoId": { + "type": "string" + }, + "l1TokenDecimals": { + "type": "integer", + "minimum": 0, + "maximum": 255 + } + }, + "required": ["name", "symbol", "decimals", "addresses", "coingeckoId"] + } + } +} \ No newline at end of file diff --git a/data/tokens.json b/data/tokens.json new file mode 100644 index 0000000..1097c7d --- /dev/null +++ b/data/tokens.json @@ -0,0 +1,631 @@ +{ + "$schema": "./schemas/tokens-schema.json", + "tokens": { + "ACX": { + "name": "Across Protocol Token", + "symbol": "ACX", + "decimals": 18, + "addresses": { + "42161": "0x53691596d1BCe8CEa565b84d4915e69e03d9C99d", + "288": "0x96821b258955587069F680729cD77369C0892B40", + "1": "0x44108f0223A3C3028F5Fe7AEC7f9bb2E66beF82F", + "10": "0xFf733b2A3557a7ed6697007ab5D11B79FdD1b76B", + "137": "0xF328b73B6c685831F238c30a23Fc19140CB4D8FC", + "11155111": "0x49fCaC04AE71dbD074304Fb12071bD771e0E927A" + }, + "coingeckoId": "across-protocol" + }, + "ARB": { + "name": "Arbitrum", + "symbol": "ARB", + "decimals": 18, + "addresses": { + "42161": "0x912CE59144191C1204E64559FE8253a0e49E6548", + "1": "0xB50721BCf8d664c30412Cfbc6cf7a15145234ad1" + }, + "coingeckoId": "arbitrum" + }, + "AZERO": { + "name": "Aleph Zero", + "symbol": "AZERO", + "decimals": 18, + "addresses": { + "41455": "0xb7Da55D7040ef9C887e20374D76A88F93A59119E", + "1": "0xdD0ae774F7E300CdAA4EA371cD55169665Ee6AFe" + }, + "coingeckoId": "aleph-zero" + }, + "BADGER": { + "name": "Badger", + "symbol": "BADGER", + "decimals": 18, + "addresses": { + "42161": "0xBfa641051Ba0a0Ad1b0AcF549a89536A0D76472E", + "1": "0x3472A5A71965499acd81997a54BBA8D852C6E53d", + "137": "0x1FcbE5937B0cc2adf69772D228fA4205aCF4D9b2" + }, + "coingeckoId": "badger-dao" + }, + "BAL": { + "name": "Balancer", + "symbol": "BAL", + "decimals": 18, + "addresses": { + "42161": "0x040d1EdC9569d4Bab2D15287Dc5A4F10F56a56B8", + "8453": "0x4158734D47Fc9692176B5085E0F52ee0Da5d47F1", + "59144": "0x660edb0A46c3f69be9eFF5446318593b9469F9e2", + "1": "0xba100000625a3754423978a60c9317c58a424e3D", + "10": "0xFE8B128bA8C78aabC59d4c64cEE7fF28e9379921", + "137": "0x9a71012B13CA4d3D0Cdc72A177DF3ef03b0E76A3" + }, + "coingeckoId": "balancer" + }, + "BNB": { + "name": "BNB", + "symbol": "BNB", + "decimals": 18, + "addresses": { + "56": "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c", + "1": "0xB8c77482e45F1F44dE1745F52C74426C631bDD52" + }, + "coingeckoId": "binancecoin" + }, + "BOBA": { + "name": "Boba", + "symbol": "BOBA", + "decimals": 18, + "addresses": { + "288": "0xa18bF3994C0Cc6E3b63ac420308E5383f53120D7", + "1": "0x42bBFa2e77757C645eeaAd1655E0911a7553Efbc" + }, + "coingeckoId": "boba-network" + }, + "CAKE": { + "name": "PancakeSwap Token", + "symbol": "CAKE", + "decimals": 18, + "addresses": { + "56": "0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82", + "1": "0x152649eA73beAb28c5b49B26eb48f7EAD6d4c898" + }, + "coingeckoId": "pancakeswap-token" + }, + "DAI": { + "name": "Dai Stablecoin", + "symbol": "DAI", + "decimals": 18, + "addresses": { + "42161": "0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1", + "8453": "0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb", + "288": "0xf74195Bb8a5cf652411867c5C2C5b8C2a402be35", + "59144": "0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d5", + "1": "0x6B175474E89094C44Da98b954EedeAC495271d0F", + "10": "0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1", + "137": "0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063", + "324": "0x4B9eb6c0b6ea15176BBF62841C6B2A8a398cb656" + }, + "coingeckoId": "dai" + }, + "ETH": { + "name": "Ether", + "symbol": "ETH", + "decimals": 18, + "addresses": { + "41455": "0xB3f0eE446723f4258862D949B4c9688e7e7d35d3", + "42161": "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1", + "421614": "0x980B62Da83eFf3D4576C647993b0c1D7faf17c73", + "8453": "0x4200000000000000000000000000000000000006", + "84532": "0x4200000000000000000000000000000000000006", + "56": "0x2170Ed0880ac9A755fd29B2688956BD959F933F8", + "60808": "0x4200000000000000000000000000000000000006", + "808813": "0x4200000000000000000000000000000000000006", + "288": "0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000", + "81457": "0x4300000000000000000000000000000000000004", + "168587773": "0x4200000000000000000000000000000000000023", + "57073": "0x4200000000000000000000000000000000000006", + "763373": "0x4200000000000000000000000000000000000006", + "232": "0xE5ecd226b3032910CEaa43ba92EE8232f8237553", + "37111": "0xaA91D645D7a6C1aeaa5988e0547267B77d33fe16", + "59144": "0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f", + "1135": "0x4200000000000000000000000000000000000006", + "4202": "0x4200000000000000000000000000000000000006", + "1": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", + "34443": "0x4200000000000000000000000000000000000006", + "919": "0x4200000000000000000000000000000000000006", + "10": "0x4200000000000000000000000000000000000006", + "11155420": "0x4200000000000000000000000000000000000006", + "137": "0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619", + "80002": "0x52eF3d68BaB452a294342DC3e5f464d7f610f72E", + "690": "0x4200000000000000000000000000000000000006", + "534352": "0x5300000000000000000000000000000000000004", + "534351": "0x5300000000000000000000000000000000000004", + "11155111": "0xfFf9976782d46CC05630D1f6eBAb18b2324d6B14", + "1868": "0x4200000000000000000000000000000000000006", + "129399": "0x17B8Ee96E3bcB3b04b3e8334de4524520C51caB4", + "130": "0x4200000000000000000000000000000000000006", + "1301": "0x4200000000000000000000000000000000000006", + "480": "0x4200000000000000000000000000000000000006", + "324": "0x5AEa5775959fBC2557Cc8789bC1bf90A239D9a91", + "300": "0x2D6Db36B3117802E996f13073A08A685D3FeF7eD", + "7777777": "0x4200000000000000000000000000000000000006" + }, + "coingeckoId": "ethereum" + }, + "ezETH": { + "name": "Renzo Restaked ETH", + "symbol": "ezETH", + "decimals": 18, + "addresses": { + "42161": "0x2416092f143378750bb29b79eD961ab195CcEea5", + "8453": "0x2416092f143378750bb29b79eD961ab195CcEea5", + "81457": "0x2416092f143378750bb29b79eD961ab195CcEea5", + "56": "0x2416092f143378750bb29b79eD961ab195CcEea5", + "59144": "0x2416092f143378750bb29b79eD961ab195CcEea5", + "1": "0xbf5495Efe5DB9ce00f80364C8B423567e58d2110", + "34443": "0x2416092f143378750bb29b79eD961ab195CcEea5", + "10": "0x2416092f143378750bb29b79eD961ab195CcEea5", + "130": "0x2416092f143378750bb29b79eD961ab195CcEea5", + "480": "0x2416092f143378750bb29b79eD961ab195CcEea5" + }, + "coingeckoId": "renzo-restaked-eth" + }, + "GHO": { + "name": "Gho Token", + "symbol": "GHO", + "decimals": 18, + "addresses": { + "421614": "0xb13Cfa6f8B2Eed2C37fB00fF0c1A59807C585810", + "84532": "0x7CFa3f3d1cded0Da930881c609D4Dbf0012c14Bb", + "232": "0x000000000000000000000000000000000000800A", + "1": "0x40D16FC0246aD3160Ccc09B8D0D3A2cD28aE6C2f", + "11155420": "0xb13Cfa6f8B2Eed2C37fB00fF0c1A59807C585810", + "11155111": "0xc4bF5CbDaBE595361438F8c6a187bDc330539c60" + }, + "coingeckoId": "gho" + }, + "GRASS": { + "name": "Grass", + "symbol": "GRASS", + "decimals": 18, + "addresses": { + "37111": "0xeee5a340Cdc9c179Db25dea45AcfD5FE8d4d3eB8", + "11155111": "0x2Be68B15c693D3b5747F9F0D49D30A2E81BAA2Df" + }, + "coingeckoId": "gho" + }, + "HYPE": { + "name": "Hyperliquid", + "symbol": "HYPE", + "decimals": 18, + "addresses": { + "999": "0x5555555555555555555555555555555555555555", + "998": "0x5555555555555555555555555555555555555555" + }, + "coingeckoId": "hyperliquid" + }, + "WHYPE": { + "name": "Wrapped Hyperliquid", + "symbol": "WHYPE", + "decimals": 18, + "addresses": { + "999": "0x5555555555555555555555555555555555555555", + "998": "0x5555555555555555555555555555555555555555" + }, + "coingeckoId": "hyperliquid" + }, + "LSK": { + "name": "Lisk", + "symbol": "LSK", + "decimals": 18, + "addresses": { + "1135": "0xac485391EB2d7D88253a7F1eF18C37f4242D1A24", + "1": "0x6033F7f88332B8db6ad452B7C6D5bB643990aE3f" + }, + "coingeckoId": "lisk" + }, + "MATIC": { + "name": "Matic", + "symbol": "MATIC", + "decimals": 18, + "addresses": { + "1": "0x7D1AfA7B718fb893dB30A3aBc0Cfc608AaCfeBB0", + "80002": "0x360ad4f9a9A8EFe9A8DCB5f461c4Cc1047E1Dcf9", + "11155111": "0x3fd0A53F4Bf853985a95F4Eb3F9C9FDE1F8e2b53" + }, + "coingeckoId": "matic-network" + }, + "OP": { + "name": "Optimism", + "symbol": "OP", + "decimals": 18, + "addresses": { + "10": "0x4200000000000000000000000000000000000042" + }, + "coingeckoId": "optimism" + }, + "POOL": { + "name": "PoolTogether", + "symbol": "POOL", + "decimals": 18, + "addresses": { + "42161": "0xCF934E2402A5e072928a39a956964eb8F2B5B79C", + "8453": "0xd652C5425aea2Afd5fb142e120FeCf79e18fafc3", + "1": "0x0cEC1A9154Ff802e7934Fc916Ed7Ca50bDE6844e", + "10": "0x395Ae52bB17aef68C2888d941736A71dC6d4e125", + "137": "0x25788a1a171ec66Da6502f9975a15B609fF54CF6", + "534352": "0xF9Af83FC41e0cc2af2fba93644D542Df6eA0F2b7", + "480": "0x7077C71B4AF70737a08287E279B717Dcf64fdC57" + }, + "coingeckoId": "pooltogether" + }, + "SNX": { + "name": "Synthetix", + "symbol": "SNX", + "decimals": 18, + "addresses": { + "1": "0xC011a73ee8576Fb46F5E1c5751cA3B9Fe0af2a6F", + "10": "0x8700dAec35aF8Ff88c16BdF0418774CB3D7599B4" + }, + "coingeckoId": "havven" + }, + "SOL": { + "name": "Solana", + "symbol": "SOL", + "decimals": 9, + "addresses": { + "34268394551451": "So11111111111111111111111111111111111111112", + "133268194659241": "So11111111111111111111111111111111111111112" + }, + "coingeckoId": "solana" + }, + "TATARA-USDC": { + "name": "Tatara USDC", + "symbol": "TATARA-USDC", + "decimals": 6, + "addresses": { + "84532": "0x3c95BB5f49F3643558aa8F699403564A652FBeB0", + "80002": "0x8B0180f2101c8260d49339abfEe87927412494B4", + "11155111": "0x2b9Ca0A8C773bb1B92A3dDAE9F882Fd14457DACc", + "129399": "0x102E14ffF48170F2e5b6d0e30259fCD4eE5E28aE" + }, + "coingeckoId": "usd-coin" + }, + "TATARA-USDS": { + "name": "Tatara USDS", + "symbol": "TATARA-USDS", + "decimals": 18, + "addresses": { + "11155111": "0xfC7b006bDEd8e5D4A55FbaC7A91dAf3753f085CD" + }, + "coingeckoId": "usd-coin" + }, + "TATARA-USDT": { + "name": "Tatara USDT", + "symbol": "TATARA-USDT", + "decimals": 6, + "addresses": { + "11155111": "0x18fDA3c97Ea92A04D1636D84948624b414D0058E" + }, + "coingeckoId": "usd-coin" + }, + "TATARA-WBTC": { + "name": "Tatara WBTC", + "symbol": "TATARA-WBTC", + "decimals": 18, + "addresses": { + "11155111": "0xd67A804510739C33c578162A26324C83DCFC0a0A" + }, + "coingeckoId": "wrapped-bitcoin" + }, + "UMA": { + "name": "UMA Voting Token", + "symbol": "UMA", + "decimals": 18, + "addresses": { + "42161": "0xd693Ec944A85eeca4247eC1c3b130DCa9B0C3b22", + "288": "0x780f33Ad21314d9A1Ffb6867Fe53d48a76Ec0D16", + "1": "0x04Fa0d235C4abf4BcF4787aF4CF447DE572eF828", + "10": "0xE7798f023fC62146e8Aa1b36Da45fb70855a77Ea", + "137": "0x3066818837c5e6eD6601bd5a91B0762877A6B731" + }, + "coingeckoId": "uma" + }, + "USDB": { + "name": "USDB", + "symbol": "USDB", + "decimals": 18, + "addresses": { + "81457": "0x4300000000000000000000000000000000000003", + "1": "0x6B175474E89094C44Da98b954EedeAC495271d0F" + }, + "coingeckoId": "usdb" + }, + "USDC": { + "name": "USD Coin", + "symbol": "USDC", + "decimals": 6, + "addresses": { + "42161": "0xaf88d065e77c8cC2239327C5EDb3A432268e5831", + "421614": "0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d", + "8453": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", + "84532": "0x036CbD53842c5426634e7929541eC2318f3dCF7e", + "999": "0xb88339CB7199b77E23DB6E890353E22632Ba630f", + "998": "0x2B3370eE501B4a559b57D449569354196457D8Ab", + "59144": "0x176211869cA2b568f2A7D4EE941E073a821EE1ff", + "232": "0x88F08E304EC4f90D644Cec3Fb69b8aD414acf884", + "1": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", + "10": "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85", + "11155420": "0x5fd84259d66Cd46123540766Be93DFE6D43130D7", + "137": "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359", + "80002": "0x41E94Eb019C0762f9Bfcf9Fb1E58725BfB0e7582", + "534352": "0x06eFdBFf2a14a7c8E15944D1F4A48F9F95F663A4", + "11155111": "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238", + "130": "0x078D782b760474a361dDA0AF3839290b0EF57AD6", + "1301": "0x31d0220469e10c4E71834a79b1f276d740d3768F", + "480": "0x79A02482A880bCE3F13e09Da970dC34db4CD24d1", + "34268394551451": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", + "133268194659241": "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU" + }, + "coingeckoId": "usd-coin" + }, + "USDC.e": { + "name": "USD Coin (bridged)", + "symbol": "USDC.e", + "decimals": 6, + "addresses": { + "41455": "0x18d25B4e18165c97e1285212e5d1f80eDD6d3Aa7", + "42161": "0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8", + "288": "0x66a2A913e447d6b4BF33EFbec43aAeF87890FBbc", + "1135": "0xF242275d3a6527d877f2c927a82D9b057609cc71", + "1": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", + "34443": "0xd988097fb8612cc24eeC14542bC03424c656005f", + "10": "0x7F5c764cBc14f9669B88837ca1490cCa17c31607", + "11155420": "0x9552a0a6624A23B848060AE5901659CDDa1f83f8", + "137": "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174", + "1868": "0xbA9986D2381edf1DA03B0B9c1f8b00dc4AacC369", + "324": "0x3355df6D4c9C3035724Fd0e3914dE96A5a83aaf4" + }, + "coingeckoId": "usd-coin-ethereum-bridged" + }, + "USDbC": { + "name": "USD Coin (bridged)", + "symbol": "USDbC", + "decimals": 6, + "addresses": { + "8453": "0xd9aAEc86B65D86f6A7B5B1b0c42FFA531710b6CA", + "84532": "0xE634Ec56B73779eCFfa78109a653FA0aE33D243f", + "1": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" + }, + "coingeckoId": "bridged-usd-coin-base" + }, + "USDzC": { + "name": "USD Coin (bridged)", + "symbol": "USDzC", + "decimals": 6, + "addresses": { + "1": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", + "7777777": "0xCccCCccc7021b32EBb4e8C08314bD62F7c653EC4" + }, + "coingeckoId": "usd-coin-ethereum-bridged" + }, + "USDC-BNB": { + "name": "USD Coin", + "symbol": "USDC-BNB", + "decimals": 18, + "addresses": { + "56": "0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d", + "1": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" + }, + "l1TokenDecimals": 6, + "coingeckoId": "usd-coin" + }, + "USDT": { + "name": "Tether USD", + "symbol": "USDT", + "decimals": 6, + "addresses": { + "41455": "0xD648529D4803d3467bA8850577BEd4e4b8Ae583C", + "42161": "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9", + "8453": "0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2", + "288": "0x5DE1677344D3Cb0D7D465c10b72A8f60699C062d", + "999": "0xB8CE59FC3717ada4C02eaDF9682A9e934F625ebb", + "59144": "0xA219439258ca9da29E9Cc4cE5596924745e12B93", + "1135": "0x05D032ac25d322df992303dCa074EE7392C117b9", + "1": "0xdAC17F958D2ee523a2206206994597C13D831ec7", + "34443": "0xf0F161fDA2712DB8b566946122a5af183995e2eD", + "10": "0x94b008aA00579c1307B0EF2c499aD98a8ce58e58", + "137": "0xc2132D05D31c914a87C6611C10748AEb04B58e8F", + "534352": "0xf55BEC9cafDbE8730f096Aa55dad6D22d44099Df", + "11155111": "0x7169D38820dfd117C3FA1f22a697dBA58d90BA06", + "324": "0x493257fD37EDB34451f62EDf8D2a0C418852bA4C" + }, + "coingeckoId": "tether" + }, + "USDT-BNB": { + "name": "Tether USD", + "symbol": "USDT-BNB", + "decimals": 18, + "addresses": { + "56": "0x55d398326f99059fF775485246999027B3197955", + "1": "0xdAC17F958D2ee523a2206206994597C13D831ec7" + }, + "l1TokenDecimals": 6, + "coingeckoId": "tether" + }, + "VLR": { + "name": "Velora", + "symbol": "VLR", + "decimals": 18, + "addresses": { + "8453": "0x4e107a0000DB66f0E9Fd2039288Bf811dD1f9c74", + "1": "0x4e107a0000DB66f0E9Fd2039288Bf811dD1f9c74", + "10": "0x4e107a0000DB66f0E9Fd2039288Bf811dD1f9c74" + }, + "coingeckoId": "velora" + }, + "WAZERO": { + "name": "Wrapped AZERO", + "symbol": "WAZERO", + "decimals": 18, + "addresses": { + "41455": "0xb7Da55D7040ef9C887e20374D76A88F93A59119E", + "1": "0xdD0ae774F7E300CdAA4EA371cD55169665Ee6AFe" + }, + "coingeckoId": "aleph-zero" + }, + "WBNB": { + "name": "Wrapped BNB", + "symbol": "WBNB", + "decimals": 18, + "addresses": { + "56": "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c", + "1": "0xB8c77482e45F1F44dE1745F52C74426C631bDD52" + }, + "coingeckoId": "wbnb" + }, + "WBTC": { + "name": "Wrapped Bitcoin", + "symbol": "WBTC", + "decimals": 8, + "addresses": { + "42161": "0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f", + "81457": "0xF7bc58b8D8f97ADC129cfC4c9f45Ce3C0E1D2692", + "56": "0x7130d2A12B9BCbFAe4f2634d864A1Ee1Ce3Ead9c", + "288": "0xdc0486f8bf31DF57a952bcd3c1d3e166e3d9eC8b", + "59144": "0x3aAB2285ddcDdaD8edf438C1bAB47e1a9D05a9b4", + "1135": "0x03C7054BCB39f7b2e5B2c7AcB37583e32D70Cfa3", + "1": "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599", + "34443": "0xcDd475325D6F564d27247D1DddBb0DAc6fA0a5CF", + "10": "0x68f180fcCe6836688e9084f035309E29Bf0A2095", + "137": "0x1BFD67037B42Cf73acF2047067bd4F2C47D9BfD6", + "480": "0x03C7054BCB39f7b2e5B2c7AcB37583e32D70Cfa3", + "534352": "0x3C1BCa5a656e69edCD0D4E36BEbb3FcDAcA60Cf1", + "324": "0xBBeB516fb02a01611cBBE0453Fe3c580D7281011", + "808813": "0xAdCE1AB74C8e64c155953A8BdE37cBB06Cf7086D", + "11155111": "0x9D15Db83680572C9a48826d51b733ea3B0957De3" + }, + "coingeckoId": "wrapped-bitcoin" + }, + "WETH": { + "name": "Wrapped Ether", + "symbol": "WETH", + "decimals": 18, + "addresses": { + "41455": "0xB3f0eE446723f4258862D949B4c9688e7e7d35d3", + "42161": "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1", + "421614": "0x980B62Da83eFf3D4576C647993b0c1D7faf17c73", + "8453": "0x4200000000000000000000000000000000000006", + "84532": "0x4200000000000000000000000000000000000006", + "288": "0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000", + "81457": "0x4300000000000000000000000000000000000004", + "168587773": "0x4200000000000000000000000000000000000023", + "56": "0x2170Ed0880ac9A755fd29B2688956BD959F933F8", + "57073": "0x4200000000000000000000000000000000000006", + "763373": "0x4200000000000000000000000000000000000006", + "232": "0xE5ecd226b3032910CEaa43ba92EE8232f8237553", + "37111": "0xaA91D645D7a6C1aeaa5988e0547267B77d33fe16", + "59144": "0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f", + "1135": "0x4200000000000000000000000000000000000006", + "4202": "0x4200000000000000000000000000000000000006", + "1": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", + "34443": "0x4200000000000000000000000000000000000006", + "919": "0x4200000000000000000000000000000000000006", + "10": "0x4200000000000000000000000000000000000006", + "11155420": "0x4200000000000000000000000000000000000006", + "137": "0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619", + "80002": "0x52eF3d68BaB452a294342DC3e5f464d7f610f72E", + "690": "0x4200000000000000000000000000000000000006", + "534352": "0x5300000000000000000000000000000000000004", + "534351": "0x5300000000000000000000000000000000000004", + "11155111": "0xfFf9976782d46CC05630D1f6eBAb18b2324d6B14", + "1868": "0x4200000000000000000000000000000000000006", + "129399": "0x17B8Ee96E3bcB3b04b3e8334de4524520C51caB4", + "130": "0x4200000000000000000000000000000000000006", + "1301": "0x4200000000000000000000000000000000000006", + "480": "0x4200000000000000000000000000000000000006", + "324": "0x5AEa5775959fBC2557Cc8789bC1bf90A239D9a91", + "300": "0x2D6Db36B3117802E996f13073A08A685D3FeF7eD", + "7777777": "0x4200000000000000000000000000000000000006", + "808813": "0x4200000000000000000000000000000000000006" + }, + "coingeckoId": "weth" + }, + "WGHO": { + "name": "Wrapped GHO Token", + "symbol": "WGHO", + "decimals": 18, + "addresses": { + "232": "0x6bDc36E20D267Ff0dd6097799f82e78907105e2F", + "1": "0x1ff1dC3cB9eeDbC6Eb2d99C03b30A05cA625fB5a" + }, + "coingeckoId": "gho" + }, + "WGRASS": { + "name": "Wrapped Grass", + "symbol": "WGRASS", + "decimals": 18, + "addresses": { + "37111": "0xeee5a340Cdc9c179Db25dea45AcfD5FE8d4d3eB8", + "11155111": "0x2Be68B15c693D3b5747F9F0D49D30A2E81BAA2Df" + }, + "coingeckoId": "gho" + }, + "WLD": { + "name": "Worldcoin", + "symbol": "WLD", + "decimals": 18, + "addresses": { + "1": "0x163f8C2467924be0ae7B5347228CABF260318753", + "10": "0xdC6fF44d5d932Cbd77B52E5612Ba0529DC6226F1", + "480": "0x2cFc85d8E48F8EAB294be644d9E25C3030863003" + }, + "coingeckoId": "worldcoin-wld" + }, + "WMATIC": { + "name": "Matic", + "symbol": "WMATIC", + "decimals": 18, + "addresses": { + "1": "0x7D1AfA7B718fb893dB30A3aBc0Cfc608AaCfeBB0", + "137": "0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270", + "80002": "0x360ad4f9a9A8EFe9A8DCB5f461c4Cc1047E1Dcf9", + "11155111": "0x3fd0A53F4Bf853985a95F4Eb3F9C9FDE1F8e2b53" + }, + "coingeckoId": "wmatic" + }, + "WSOL": { + "name": "Wrapped SOL", + "symbol": "WSOL", + "decimals": 9, + "addresses": { + "34268394551451": "So11111111111111111111111111111111111111112", + "133268194659241": "So11111111111111111111111111111111111111112" + }, + "coingeckoId": "wrapped-solana" + }, + "XYZ": { + "name": "XYZ Token", + "symbol": "XYZ", + "decimals": 18, + "addresses": { + "84532": "0x180D555759e4d1d5Cf70C3BaBbAE4B8F410BDAD9", + "11155420": "0x180D555759e4d1d5Cf70C3BaBbAE4B8F410BDAD9", + "11155111": "0x180D555759e4d1d5Cf70C3BaBbAE4B8F410BDAD9" + }, + "coingeckoId": "xyz" + } + }, + "tokenEquivalenceRemapping": { + "USDC.e": "USDC", + "USDbC": "USDC", + "USDzC": "USDC", + "USDB": "DAI", + "USDC-BNB": "USDC", + "USDT-BNB": "USDT", + "LGHO": "WGHO", + "ETH": "WETH", + "BNB": "WBNB", + "HYPE": "WHYPE", + "TATARA-USDC": "USDC" + } +} \ No newline at end of file diff --git a/package.json b/package.json index 947cac1..81c8a95 100644 --- a/package.json +++ b/package.json @@ -19,16 +19,23 @@ "lint-fix": "yarn eslint --fix && yarn prettier --write", "prettier": "prettier .", "eslint": "eslint .", - "prepare": "yarn build", + "prepare": "yarn generate && yarn build", "build": "yarn run clean && yarn run build:cjs && yarn run build:esm && yarn run build:types", "build:cjs": "tsc --project tsconfig.json --module commonjs --outDir ./dist/cjs --removeComments --verbatimModuleSyntax false && echo > ./dist/cjs/package.json '{\"type\":\"commonjs\"}'", "build:esm": "tsc --project tsconfig.json --module es2015 --outDir ./dist/esm && echo > ./dist/esm/package.json '{\"type\":\"module\",\"sideEffects\":false}'", "build:types": "tsc --project tsconfig.json --module esnext --declarationDir ./dist/types --emitDeclarationOnly --declaration --declarationMap", - "clean": "rm -rf ./dist" + "clean": "rm -rf ./dist ./src-generated", + "generate": "node scripts/generate-all.cjs && cp -r src-generated/typescript/* src/", + "generate:typescript": "node scripts/generate-typescript.cjs", + "generate:python": "node scripts/generate-python.cjs", + "generate:rust": "node scripts/generate-rust.cjs", + "validate": "node scripts/validate-data.cjs", + "watch": "node scripts/watch-data.cjs" }, "devDependencies": { "@typescript-eslint/eslint-plugin": "^6.7.3", "@typescript-eslint/parser": "^6.7.3", + "ajv": "^8.12.0", "eslint": "^8.50.0", "eslint-config-prettier": "^9.0.0", "eslint-config-standard": "^17.1.0", diff --git a/scripts/generate-all.cjs b/scripts/generate-all.cjs new file mode 100755 index 0000000..8015b46 --- /dev/null +++ b/scripts/generate-all.cjs @@ -0,0 +1,28 @@ +#!/usr/bin/env node + +const { execSync } = require('child_process'); +const path = require('path'); + +function runScript(scriptPath, description) { + console.log(`\nšŸ”„ ${description}...`); + try { + execSync(`node "${scriptPath}"`, { stdio: 'inherit' }); + } catch (error) { + console.error(`āŒ Failed to ${description.toLowerCase()}: ${error.message}`); + process.exit(1); + } +} + +console.log('šŸš€ Generating all packages from JSON data...\n'); + +const scriptsDir = __dirname; + +runScript(path.join(scriptsDir, 'generate-typescript.cjs'), 'Generate TypeScript package'); +runScript(path.join(scriptsDir, 'generate-python.cjs'), 'Generate Python package'); +runScript(path.join(scriptsDir, 'generate-rust.cjs'), 'Generate Rust package'); + +console.log('\nāœ… All packages generated successfully!'); +console.log('\nGenerated packages:'); +console.log('šŸ“ TypeScript: src-generated/typescript/'); +console.log('šŸ“ Python: src-generated/python/'); +console.log('šŸ“ Rust: src-generated/rust/'); \ No newline at end of file diff --git a/scripts/generate-python.cjs b/scripts/generate-python.cjs new file mode 100755 index 0000000..9e8a512 --- /dev/null +++ b/scripts/generate-python.cjs @@ -0,0 +1,339 @@ +#!/usr/bin/env node + +const fs = require('fs'); +const path = require('path'); + +const CHAINS_DATA = require('../data/chains.json'); +const TOKENS_DATA = require('../data/tokens.json'); + +function toPythonConstant(name) { + return name.toUpperCase(); +} + +function generatePythonNetworks() { + const { chainFamilies, testnetSepoliaChainIds, testnetChainIds, mainnetChainIds, productionOftEids, testnetOftEids, hyperlaneDomainIdOverrides, constants, networks } = CHAINS_DATA; + + let code = `"""Chain names and IDs.""" + +from enum import IntEnum +from typing import Dict, Any, Final + + +# Chain IDs +TESTNET_SEPOLIA_CHAIN_IDS: Final[Dict[str, int]] = { +${Object.entries(testnetSepoliaChainIds).map(([key, value]) => ` "${key}": ${value},`).join('\n')} +} + +TESTNET_CHAIN_IDS: Final[Dict[str, int]] = { + **TESTNET_SEPOLIA_CHAIN_IDS, +${Object.entries(testnetChainIds).filter(([key]) => !testnetSepoliaChainIds[key]).map(([key, value]) => ` "${key}": ${value},`).join('\n')} +} + +MAINNET_CHAIN_IDS: Final[Dict[str, int]] = { +${Object.entries(mainnetChainIds).map(([key, value]) => ` "${key}": ${value},`).join('\n')} +} + +CHAIN_IDS: Final[Dict[str, int]] = { + **MAINNET_CHAIN_IDS, + **TESTNET_CHAIN_IDS, +} + + +class ChainFamily(IntEnum): + """Blockchain family types.""" +${Object.entries(chainFamilies).map(([key, value]) => ` ${key} = ${value}`).join('\n')} + + +# LayerZero Endpoint IDs +# Source: https://docs.layerzero.network/v2/developers/evm/technical-reference/deployed-contracts +PRODUCTION_OFT_EIDS: Final[Dict[str, int]] = { +${Object.entries(productionOftEids).map(([key, value]) => ` "${key}": ${value},`).join('\n')} +} + +TESTNET_OFT_EIDS: Final[Dict[str, int]] = { +${Object.entries(testnetOftEids).map(([key, value]) => ` "${key}": ${value},`).join('\n')} +} + +# Hyperlane domain ID overrides +# Source: https://github.com/hyperlane-xyz/hyperlane-registry +HYPERLANE_DOMAIN_ID_OVERRIDES: Final[Dict[str, int]] = { +${Object.entries(hyperlaneDomainIdOverrides).map(([key, value]) => ` "${key}": ${value},`).join('\n')} +} + +# Constants +CCTP_NO_DOMAIN: Final[int] = ${constants.CCTP_NO_DOMAIN} +OFT_NO_EID: Final[int] = ${constants.OFT_NO_EID} +HYPERLANE_NO_DOMAIN_ID: Final[int] = ${constants.HYPERLANE_NO_DOMAIN_ID} + + +class PublicNetwork: + """Network configuration.""" + + def __init__( + self, + name: str, + family: ChainFamily, + native_token: str, + public_rpc: str, + block_explorer: str, + cctp_domain: int, + oft_eid: int, + hyp_domain_id: int, + ): + self.name = name + self.family = family + self.native_token = native_token + self.public_rpc = public_rpc + self.block_explorer = block_explorer + self.cctp_domain = cctp_domain + self.oft_eid = oft_eid + self.hyp_domain_id = hyp_domain_id + + def to_dict(self) -> Dict[str, Any]: + """Convert to dictionary.""" + return { + "name": self.name, + "family": self.family, + "native_token": self.native_token, + "public_rpc": self.public_rpc, + "block_explorer": self.block_explorer, + "cctp_domain": self.cctp_domain, + "oft_eid": self.oft_eid, + "hyp_domain_id": self.hyp_domain_id, + } + + +PRODUCTION_NETWORKS: Final[Dict[int, PublicNetwork]] = { +${Object.entries(networks.production).map(([chainId, config]) => { + const chainName = Object.entries(mainnetChainIds).find(([, id]) => id.toString() === chainId)?.[0]; + const familyName = Object.entries(chainFamilies).find(([, value]) => value === config.family)?.[0]; + return ` CHAIN_IDS["${chainName}"]: PublicNetwork( + name="${config.name}", + family=ChainFamily.${familyName}, + native_token="${config.nativeToken}", + public_rpc="${config.publicRPC}", + block_explorer="${config.blockExplorer}", + cctp_domain=${config.cctpDomain}, + oft_eid=${config.oftEid}, + hyp_domain_id=${config.hypDomainId}, + ),`; +}).join('\n')} +} + +TEST_NETWORKS: Final[Dict[int, PublicNetwork]] = { +${Object.entries(networks.testnet).map(([chainId, config]) => { + const chainName = Object.entries(testnetChainIds).find(([, id]) => id.toString() === chainId)?.[0]; + const familyName = Object.entries(chainFamilies).find(([, value]) => value === config.family)?.[0]; + return ` CHAIN_IDS["${chainName}"]: PublicNetwork( + name="${config.name}", + family=ChainFamily.${familyName}, + native_token="${config.nativeToken}", + public_rpc="${config.publicRPC}", + block_explorer="${config.blockExplorer}", + cctp_domain=${config.cctpDomain}, + oft_eid=${config.oftEid}, + hyp_domain_id=${config.hypDomainId}, + ),`; +}).join('\n')} +} + +PUBLIC_NETWORKS: Final[Dict[int, PublicNetwork]] = { + **PRODUCTION_NETWORKS, + **TEST_NETWORKS, +} +`; + + return code; +} + +function generatePythonTokens() { + const { tokens, tokenEquivalenceRemapping } = TOKENS_DATA; + const { mainnetChainIds, testnetChainIds } = CHAINS_DATA; + const allChainIds = { ...mainnetChainIds, ...testnetChainIds }; + + let code = `"""Token information and addresses.""" + +from typing import Dict, Any, Optional, Final +from .networks import CHAIN_IDS + + +class TokenConfig: + """Token configuration.""" + + def __init__( + self, + name: str, + symbol: str, + decimals: int, + addresses: Dict[int, str], + coingecko_id: str, + l1_token_decimals: Optional[int] = None, + ): + self.name = name + self.symbol = symbol + self.decimals = decimals + self.addresses = addresses + self.coingecko_id = coingecko_id + self.l1_token_decimals = l1_token_decimals + + def to_dict(self) -> Dict[str, Any]: + """Convert to dictionary.""" + result = { + "name": self.name, + "symbol": self.symbol, + "decimals": self.decimals, + "addresses": self.addresses, + "coingecko_id": self.coingecko_id, + } + if self.l1_token_decimals is not None: + result["l1_token_decimals"] = self.l1_token_decimals + return result + + +# Information for the supported tokens on each chain. +# NOTE: All addresses should be checksummed +TOKEN_SYMBOLS_MAP: Final[Dict[str, TokenConfig]] = { +${Object.entries(tokens).map(([symbol, config]) => { + const addressEntries = Object.entries(config.addresses).map(([chainId, address]) => { + const chainName = Object.entries(allChainIds).find(([, id]) => id.toString() === chainId)?.[0]; + return ` CHAIN_IDS["${chainName}"]: "${address}",`; + }).join('\n'); + + const l1Decimals = config.l1TokenDecimals ? `,\n l1_token_decimals=${config.l1TokenDecimals}` : ''; + + return ` "${symbol}": TokenConfig( + name="${config.name}", + symbol="${config.symbol}", + decimals=${config.decimals}, + addresses={ +${addressEntries} + }, + coingecko_id="${config.coingeckoId}"${l1Decimals}, + ),`; +}).join('\n')} +} + +# Hard-coded mapping of token symbols that should be treated as having equivalent +# prices. The right-hand side should map to a token symbol in TOKEN_SYMBOLS_MAP. +TOKEN_EQUIVALENCE_REMAPPING: Final[Dict[str, str]] = { +${Object.entries(tokenEquivalenceRemapping).map(([from, to]) => ` "${from}": "${to}",`).join('\n')} +} +`; + + return code; +} + +function generatePythonInit() { + return `"""Across Protocol constants for Python.""" + +from .networks import * +from .tokens import * + +__version__ = "3.1.76" +__all__ = [ + # Networks + "TESTNET_SEPOLIA_CHAIN_IDS", + "TESTNET_CHAIN_IDS", + "MAINNET_CHAIN_IDS", + "CHAIN_IDS", + "ChainFamily", + "PRODUCTION_OFT_EIDS", + "TESTNET_OFT_EIDS", + "HYPERLANE_DOMAIN_ID_OVERRIDES", + "CCTP_NO_DOMAIN", + "OFT_NO_EID", + "HYPERLANE_NO_DOMAIN_ID", + "PublicNetwork", + "PRODUCTION_NETWORKS", + "TEST_NETWORKS", + "PUBLIC_NETWORKS", + # Tokens + "TokenConfig", + "TOKEN_SYMBOLS_MAP", + "TOKEN_EQUIVALENCE_REMAPPING", +] +`; +} + +function generatePythonSetup() { + return `"""Setup script for across-constants Python package.""" + +from setuptools import setup, find_packages + +with open("README.md", "r", encoding="utf-8") as fh: + long_description = fh.read() + +setup( + name="across-constants", + version="3.1.76", + author="Across Protocol", + author_email="hello@umaproject.org", + description="Export commonly re-used values for Across repositories", + long_description=long_description, + long_description_content_type="text/markdown", + url="https://github.com/across-protocol/constants", + packages=find_packages(), + classifiers=[ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "License :: OSI Approved :: GNU Affero General Public License v3", + "Operating System :: OS Independent", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + ], + python_requires=">=3.8", + license="AGPL-3.0-only", +) +`; +} + +function generatePythonReadme() { + return `# Across Constants (Python) + +Python package containing chain and token constants for the Across Protocol. + +## Installation + +\`\`\`bash +pip install across-constants +\`\`\` + +## Usage + +\`\`\`python +from across_constants import CHAIN_IDS, TOKEN_SYMBOLS_MAP, ChainFamily + +# Get chain ID for Arbitrum +arbitrum_chain_id = CHAIN_IDS["ARBITRUM"] + +# Get USDC token config +usdc_config = TOKEN_SYMBOLS_MAP["USDC"] +print(f"USDC decimals: {usdc_config.decimals}") + +# Get USDC address on Arbitrum +usdc_arbitrum_address = usdc_config.addresses[arbitrum_chain_id] +\`\`\` + +## Generated Code + +This package is automatically generated from JSON data sources. Do not edit the generated files directly. +`; +} + +// Create output directory +const outputDir = path.join(__dirname, '../src-generated/python'); +const packageDir = path.join(outputDir, 'across_constants'); +fs.mkdirSync(packageDir, { recursive: true }); + +// Generate files +fs.writeFileSync(path.join(packageDir, 'networks.py'), generatePythonNetworks()); +fs.writeFileSync(path.join(packageDir, 'tokens.py'), generatePythonTokens()); +fs.writeFileSync(path.join(packageDir, '__init__.py'), generatePythonInit()); +fs.writeFileSync(path.join(outputDir, 'setup.py'), generatePythonSetup()); +fs.writeFileSync(path.join(outputDir, 'README.md'), generatePythonReadme()); + +console.log('āœ… Python files generated successfully'); \ No newline at end of file diff --git a/scripts/generate-rust.cjs b/scripts/generate-rust.cjs new file mode 100755 index 0000000..75d815d --- /dev/null +++ b/scripts/generate-rust.cjs @@ -0,0 +1,319 @@ +#!/usr/bin/env node + +const fs = require('fs'); +const path = require('path'); + +const CHAINS_DATA = require('../data/chains.json'); +const TOKENS_DATA = require('../data/tokens.json'); + +function toRustConstant(name) { + return name.toUpperCase(); +} + +function generateRustNetworks() { + const { chainFamilies, testnetSepoliaChainIds, testnetChainIds, mainnetChainIds, productionOftEids, testnetOftEids, hyperlaneDomainIdOverrides, constants, networks } = CHAINS_DATA; + + let code = `//! Chain names and IDs. + +use std::collections::HashMap; +use once_cell::sync::Lazy; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[repr(u8)] +pub enum ChainFamily { +${Object.entries(chainFamilies).map(([key, value]) => ` ${key.charAt(0) + key.slice(1).toLowerCase().replace(/_([a-z])/g, (_, letter) => letter.toUpperCase())} = ${value},`).join('\n')} +} + +// Chain ID constants +${Object.entries(testnetSepoliaChainIds).map(([key, value]) => `pub const TESTNET_SEPOLIA_${key}: u64 = ${value};`).join('\n')} + +${Object.entries(testnetChainIds).filter(([key]) => !testnetSepoliaChainIds[key]).map(([key, value]) => `pub const TESTNET_${key}: u64 = ${value};`).join('\n')} + +${Object.entries(mainnetChainIds).map(([key, value]) => `pub const MAINNET_${key}: u64 = ${value};`).join('\n')} + +// LayerZero Endpoint IDs +${Object.entries(productionOftEids).map(([key, value]) => `pub const PRODUCTION_OFT_EID_${key}: u32 = ${value};`).join('\n')} + +${Object.entries(testnetOftEids).map(([key, value]) => `pub const TESTNET_OFT_EID_${key}: u32 = ${value};`).join('\n')} + +// Hyperlane domain ID overrides +${Object.entries(hyperlaneDomainIdOverrides).map(([key, value]) => `pub const HYPERLANE_DOMAIN_${key}: u32 = ${value};`).join('\n')} + +// Constants +pub const CCTP_NO_DOMAIN: i32 = ${constants.CCTP_NO_DOMAIN}; +pub const OFT_NO_EID: i32 = ${constants.OFT_NO_EID}; +pub const HYPERLANE_NO_DOMAIN_ID: i32 = ${constants.HYPERLANE_NO_DOMAIN_ID}; + +#[derive(Debug, Clone)] +pub struct PublicNetwork { + pub name: &'static str, + pub family: ChainFamily, + pub native_token: &'static str, + pub public_rpc: &'static str, + pub block_explorer: &'static str, + pub cctp_domain: i32, + pub oft_eid: i32, + pub hyp_domain_id: i32, +} + +impl PublicNetwork { + pub const fn new( + name: &'static str, + family: ChainFamily, + native_token: &'static str, + public_rpc: &'static str, + block_explorer: &'static str, + cctp_domain: i32, + oft_eid: i32, + hyp_domain_id: i32, + ) -> Self { + Self { + name, + family, + native_token, + public_rpc, + block_explorer, + cctp_domain, + oft_eid, + hyp_domain_id, + } + } +} + +pub static TESTNET_SEPOLIA_CHAIN_IDS: Lazy> = Lazy::new(|| { + let mut m = HashMap::new(); +${Object.entries(testnetSepoliaChainIds).map(([key, value]) => ` m.insert("${key}", ${value});`).join('\n')} + m +}); + +pub static TESTNET_CHAIN_IDS: Lazy> = Lazy::new(|| { + let mut m = HashMap::new(); +${Object.entries(testnetChainIds).map(([key, value]) => ` m.insert("${key}", ${value});`).join('\n')} + m +}); + +pub static MAINNET_CHAIN_IDS: Lazy> = Lazy::new(|| { + let mut m = HashMap::new(); +${Object.entries(mainnetChainIds).map(([key, value]) => ` m.insert("${key}", ${value});`).join('\n')} + m +}); + +pub static PRODUCTION_NETWORKS: Lazy> = Lazy::new(|| { + let mut m = HashMap::new(); +${Object.entries(networks.production).map(([chainId, config]) => { + const chainName = Object.entries(mainnetChainIds).find(([, id]) => id.toString() === chainId)?.[0]; + const familyName = Object.entries(chainFamilies).find(([, value]) => value === config.family)?.[0]; + const rustFamilyName = familyName.charAt(0) + familyName.slice(1).toLowerCase().replace(/_([a-z])/g, (_, letter) => letter.toUpperCase()); + return ` m.insert(${chainId}, PublicNetwork::new( + "${config.name}", + ChainFamily::${rustFamilyName}, + "${config.nativeToken}", + "${config.publicRPC}", + "${config.blockExplorer}", + ${config.cctpDomain}, + ${config.oftEid}, + ${config.hypDomainId}, + ));`; +}).join('\n')} + m +}); + +pub static TEST_NETWORKS: Lazy> = Lazy::new(|| { + let mut m = HashMap::new(); +${Object.entries(networks.testnet).map(([chainId, config]) => { + const chainName = Object.entries(testnetChainIds).find(([, id]) => id.toString() === chainId)?.[0]; + const familyName = Object.entries(chainFamilies).find(([, value]) => value === config.family)?.[0]; + const rustFamilyName = familyName.charAt(0) + familyName.slice(1).toLowerCase().replace(/_([a-z])/g, (_, letter) => letter.toUpperCase()); + return ` m.insert(${chainId}, PublicNetwork::new( + "${config.name}", + ChainFamily::${rustFamilyName}, + "${config.nativeToken}", + "${config.publicRPC}", + "${config.blockExplorer}", + ${config.cctpDomain}, + ${config.oftEid}, + ${config.hypDomainId}, + ));`; +}).join('\n')} + m +}); + +pub static PUBLIC_NETWORKS: Lazy> = Lazy::new(|| { + let mut m = HashMap::new(); + m.extend(PRODUCTION_NETWORKS.iter().map(|(&k, v)| (k, v.clone()))); + m.extend(TEST_NETWORKS.iter().map(|(&k, v)| (k, v.clone()))); + m +}); +`; + + return code; +} + +function generateRustTokens() { + const { tokens, tokenEquivalenceRemapping } = TOKENS_DATA; + const { mainnetChainIds, testnetChainIds } = CHAINS_DATA; + const allChainIds = { ...mainnetChainIds, ...testnetChainIds }; + + let code = `//! Token information and addresses. + +use std::collections::HashMap; +use once_cell::sync::Lazy; + +#[derive(Debug, Clone)] +pub struct TokenConfig { + pub name: &'static str, + pub symbol: &'static str, + pub decimals: u8, + pub addresses: HashMap, + pub coingecko_id: &'static str, + pub l1_token_decimals: Option, +} + +impl TokenConfig { + pub const fn new( + name: &'static str, + symbol: &'static str, + decimals: u8, + coingecko_id: &'static str, + l1_token_decimals: Option, + ) -> Self { + Self { + name, + symbol, + decimals, + addresses: HashMap::new(), + coingecko_id, + l1_token_decimals, + } + } +} + +// Information for the supported tokens on each chain. +// NOTE: All addresses should be checksummed +pub static TOKEN_SYMBOLS_MAP: Lazy> = Lazy::new(|| { + let mut m = HashMap::new(); +${Object.entries(tokens).map(([symbol, config]) => { + const addressLines = Object.entries(config.addresses).map(([chainId, address]) => { + return ` addresses.insert(${chainId}, "${address}");`; + }).join('\n'); + + return ` + { + let mut addresses = HashMap::new(); +${addressLines} + let mut token = TokenConfig::new( + "${config.name}", + "${config.symbol}", + ${config.decimals}, + "${config.coingeckoId}", + ${config.l1TokenDecimals ? `Some(${config.l1TokenDecimals})` : 'None'}, + ); + token.addresses = addresses; + m.insert("${symbol}", token); + }`; +}).join('\n')} + m +}); + +// Hard-coded mapping of token symbols that should be treated as having equivalent +// prices. The right-hand side should map to a token symbol in TOKEN_SYMBOLS_MAP. +pub static TOKEN_EQUIVALENCE_REMAPPING: Lazy> = Lazy::new(|| { + let mut m = HashMap::new(); +${Object.entries(tokenEquivalenceRemapping).map(([from, to]) => ` m.insert("${from}", "${to}");`).join('\n')} + m +}); +`; + + return code; +} + +function generateRustLib() { + return `//! Across Protocol constants for Rust. +//! +//! This crate provides chain and token constants used by the Across Protocol. + +pub mod networks; +pub mod tokens; + +pub use networks::*; +pub use tokens::*; + +/// Version of the constants package +pub const VERSION: &str = "3.1.76"; +`; +} + +function generateRustCargo() { + return `[package] +name = "across-constants" +version = "3.1.76" +edition = "2021" +authors = ["Across Protocol "] +description = "Export commonly re-used values for Across repositories" +repository = "https://github.com/across-protocol/constants" +license = "AGPL-3.0-only" +readme = "README.md" +keywords = ["across", "blockchain", "constants"] +categories = ["api-bindings", "config"] + +[dependencies] +once_cell = "1.19" + +[dev-dependencies] +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +`; +} + +function generateRustReadme() { + return `# Across Constants (Rust) + +Rust crate containing chain and token constants for the Across Protocol. + +## Installation + +Add this to your \`Cargo.toml\`: + +\`\`\`toml +[dependencies] +across-constants = "3.1.76" +\`\`\` + +## Usage + +\`\`\`rust +use across_constants::{MAINNET_CHAIN_IDS, TOKEN_SYMBOLS_MAP, ChainFamily}; + +fn main() { + // Get chain ID for Arbitrum + let arbitrum_chain_id = MAINNET_CHAIN_IDS.get("ARBITRUM").unwrap(); + + // Get USDC token config + let usdc_config = TOKEN_SYMBOLS_MAP.get("USDC").unwrap(); + println!("USDC decimals: {}", usdc_config.decimals); + + // Get USDC address on Arbitrum + let usdc_arbitrum_address = usdc_config.addresses.get(arbitrum_chain_id).unwrap(); + println!("USDC on Arbitrum: {}", usdc_arbitrum_address); +} +\`\`\` + +## Generated Code + +This crate is automatically generated from JSON data sources. Do not edit the generated files directly. +`; +} + +// Create output directory +const outputDir = path.join(__dirname, '../src-generated/rust'); +const srcDir = path.join(outputDir, 'src'); +fs.mkdirSync(srcDir, { recursive: true }); + +// Generate files +fs.writeFileSync(path.join(srcDir, 'networks.rs'), generateRustNetworks()); +fs.writeFileSync(path.join(srcDir, 'tokens.rs'), generateRustTokens()); +fs.writeFileSync(path.join(srcDir, 'lib.rs'), generateRustLib()); +fs.writeFileSync(path.join(outputDir, 'Cargo.toml'), generateRustCargo()); +fs.writeFileSync(path.join(outputDir, 'README.md'), generateRustReadme()); + +console.log('āœ… Rust files generated successfully'); \ No newline at end of file diff --git a/scripts/generate-typescript.cjs b/scripts/generate-typescript.cjs new file mode 100755 index 0000000..4f593eb --- /dev/null +++ b/scripts/generate-typescript.cjs @@ -0,0 +1,183 @@ +#!/usr/bin/env node + +const fs = require('fs'); +const path = require('path'); + +const CHAINS_DATA = require('../data/chains.json'); +const TOKENS_DATA = require('../data/tokens.json'); + +function generateTypeScriptNetworks() { + const { chainFamilies, testnetSepoliaChainIds, testnetChainIds, mainnetChainIds, productionOftEids, testnetOftEids, hyperlaneDomainIdOverrides, constants, networks } = CHAINS_DATA; + + let code = `// Chain names and IDs. +export const TESTNET_SEPOLIA_CHAIN_IDs = { +${Object.entries(testnetSepoliaChainIds).map(([key, value]) => ` ${key}: ${value},`).join('\n')} +}; + +export const TESTNET_CHAIN_IDs = { + ...TESTNET_SEPOLIA_CHAIN_IDs, +${Object.entries(testnetChainIds).filter(([key]) => !testnetSepoliaChainIds[key]).map(([key, value]) => ` ${key}: ${value},`).join('\n')} +} as const; + +export const MAINNET_CHAIN_IDs = { +${Object.entries(mainnetChainIds).map(([key, value]) => ` ${key}: ${value},`).join('\n')} +}; + +export const CHAIN_IDs = { + ...MAINNET_CHAIN_IDs, + ...TESTNET_CHAIN_IDs, +}; + +export enum ChainFamily { +${Object.entries(chainFamilies).map(([key, value]) => ` ${key} = ${value},`).join('\n')} +} + +// Source https://docs.layerzero.network/v2/developers/evm/technical-reference/deployed-contracts +export const PRODUCTION_OFT_EIDs = { +${Object.entries(productionOftEids).map(([key, value]) => ` ${key}: ${value},`).join('\n')} +}; + +// Source https://docs.layerzero.network/v2/developers/evm/technical-reference/deployed-contracts +export const TESTNET_OFT_EIDs = { +${Object.entries(testnetOftEids).map(([key, value]) => ` ${key}: ${value},`).join('\n')} +}; + +// Collection of Hyperlane domain ids that are different from CHAIN_IDs. +// Source https://github.com/hyperlane-xyz/hyperlane-registry +export const HYPERLANE_DOMAIN_ID_OVERRIDES = { +${Object.entries(hyperlaneDomainIdOverrides).map(([key, value]) => ` ${key}: ${value},`).join('\n')} +}; + +interface PublicNetwork { + name: string; + family: ChainFamily; + nativeToken: string; + publicRPC: string; // RPC provider of last resort. + blockExplorer: string; + cctpDomain: number; + oftEid: number; + hypDomainId: number; // Hyperlane domain id +} + +export const CCTP_NO_DOMAIN = ${constants.CCTP_NO_DOMAIN}; +export const OFT_NO_EID = ${constants.OFT_NO_EID}; +export const HYPERLANE_NO_DOMAIN_ID = ${constants.HYPERLANE_NO_DOMAIN_ID}; + +const { ${Object.keys(chainFamilies).join(', ')} } = ChainFamily; +export const PRODUCTION_NETWORKS: { [chainId: number]: PublicNetwork } = { +${Object.entries(networks.production).map(([chainId, config]) => { + // Check both mainnet and testnet chain IDs for the chain name + const allChainIds = { ...mainnetChainIds, ...testnetChainIds }; + const chainName = Object.entries(allChainIds).find(([, id]) => id.toString() === chainId)?.[0]; + if (!chainName) { + console.warn(`Warning: No chain name found for production chain ID ${chainId}`); + return ` // Skipping chain ID ${chainId} - no matching chain name found`; + } + return ` [CHAIN_IDs.${chainName}]: { + name: "${config.name}", + family: ${config.family === 0 ? 'NONE' : config.family === 1 ? 'OP_STACK' : config.family === 2 ? 'ORBIT' : config.family === 3 ? 'ZK_STACK' : 'SVM'}, + nativeToken: "${config.nativeToken}", + publicRPC: "${config.publicRPC}", + blockExplorer: "${config.blockExplorer}", + cctpDomain: ${config.cctpDomain}, + oftEid: ${config.oftEid === -1 ? 'OFT_NO_EID' : config.oftEid}, + hypDomainId: ${config.hypDomainId === -1 ? 'HYPERLANE_NO_DOMAIN_ID' : config.hypDomainId}, + },`; +}).filter(line => !line.includes('Skipping')).join('\n')} +}; + +export const TEST_NETWORKS: { [chainId: number]: PublicNetwork } = { +${Object.entries(networks.testnet).map(([chainId, config]) => { + const chainName = Object.entries(testnetChainIds).find(([, id]) => id.toString() === chainId)?.[0]; + if (!chainName) { + console.warn(`Warning: No chain name found for testnet chain ID ${chainId}`); + return ` // Skipping chain ID ${chainId} - no matching chain name found`; + } + return ` [CHAIN_IDs.${chainName}]: { + name: "${config.name}", + family: ${config.family === 0 ? 'NONE' : config.family === 1 ? 'OP_STACK' : config.family === 2 ? 'ORBIT' : config.family === 3 ? 'ZK_STACK' : 'SVM'}, + nativeToken: "${config.nativeToken}", + publicRPC: "${config.publicRPC}", + blockExplorer: "${config.blockExplorer}", + cctpDomain: ${config.cctpDomain}, + oftEid: ${config.oftEid === -1 ? 'OFT_NO_EID' : config.oftEid}, + hypDomainId: ${config.hypDomainId === -1 ? 'HYPERLANE_NO_DOMAIN_ID' : config.hypDomainId}, + },`; +}).filter(line => !line.includes('Skipping')).join('\n')} +}; + +export const PUBLIC_NETWORKS = { + ...PRODUCTION_NETWORKS, + ...TEST_NETWORKS, +}; +`; + + return code; +} + +function generateTypeScriptTokens() { + const { tokens, tokenEquivalenceRemapping } = TOKENS_DATA; + const { mainnetChainIds, testnetChainIds } = CHAINS_DATA; + const allChainIds = { ...mainnetChainIds, ...testnetChainIds }; + + let code = `import { CHAIN_IDs } from "./networks"; + +// Information for the supported tokens on each chain. +// NOTE: All addresses should be checksummed +export const TOKEN_SYMBOLS_MAP = { +${Object.entries(tokens).map(([symbol, config]) => { + const addressEntries = Object.entries(config.addresses).map(([chainId, address]) => { + const chainName = Object.entries(allChainIds).find(([, id]) => id.toString() === chainId)?.[0]; + if (!chainName) { + console.warn(`Warning: No chain name found for token ${symbol} address on chain ID ${chainId}`); + return null; + } + return ` [CHAIN_IDs.${chainName}]: "${address}",`; + }).filter(line => line !== null).join('\n'); + + // Quote symbol if it contains special characters + const quotedSymbol = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(symbol) ? symbol : `"${symbol}"`; + + return ` ${quotedSymbol}: { + name: "${config.name}", + symbol: "${config.symbol}", + decimals: ${config.decimals}, + addresses: { +${addressEntries} + }, + coingeckoId: "${config.coingeckoId}",${config.l1TokenDecimals ? `\n l1TokenDecimals: ${config.l1TokenDecimals},` : ''} + },`; +}).join('\n')} +}; + +// Hard-coded mapping of token symbols that should be treated as having equivalent +// prices. The right-hand side should map to a token symbol in TOKEN_SYMBOLS_MAP. +export const TOKEN_EQUIVALENCE_REMAPPING: { [symbol: string]: string } = { +${Object.entries(tokenEquivalenceRemapping).map(([from, to]) => { + // Use string key for the from value, and check if to needs quotes + const fromKey = `"${from}"`; + const toKey = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(to) ? `TOKEN_SYMBOLS_MAP.${to}.symbol` : `TOKEN_SYMBOLS_MAP["${to}"].symbol`; + return ` ${fromKey}: ${toKey},`; +}).join('\n')} +}; +`; + + return code; +} + +function generateTypeScriptIndex() { + return `export * from "./networks"; +export * from "./tokens"; +`; +} + +// Create output directory +const outputDir = path.join(__dirname, '../src-generated/typescript'); +fs.mkdirSync(outputDir, { recursive: true }); + +// Generate files +fs.writeFileSync(path.join(outputDir, 'networks.ts'), generateTypeScriptNetworks()); +fs.writeFileSync(path.join(outputDir, 'tokens.ts'), generateTypeScriptTokens()); +fs.writeFileSync(path.join(outputDir, 'index.ts'), generateTypeScriptIndex()); + +console.log('āœ… TypeScript files generated successfully'); \ No newline at end of file diff --git a/scripts/validate-data.cjs b/scripts/validate-data.cjs new file mode 100755 index 0000000..c51c43c --- /dev/null +++ b/scripts/validate-data.cjs @@ -0,0 +1,59 @@ +#!/usr/bin/env node + +const fs = require('fs'); +const path = require('path'); +const Ajv = require('ajv'); + +function validateFile(dataPath, schemaPath, description) { + console.log(`\nšŸ” Validating ${description}...`); + + try { + const data = JSON.parse(fs.readFileSync(dataPath, 'utf8')); + const schema = JSON.parse(fs.readFileSync(schemaPath, 'utf8')); + + const ajv = new Ajv(); + const validate = ajv.compile(schema); + const valid = validate(data); + + if (valid) { + console.log(`āœ… ${description} is valid`); + return true; + } else { + console.error(`āŒ ${description} validation failed:`); + console.error(validate.errors); + return false; + } + } catch (error) { + console.error(`āŒ Error validating ${description}: ${error.message}`); + return false; + } +} + +console.log('šŸ” Validating JSON data against schemas...'); + +const dataDir = path.join(__dirname, '../data'); +const schemasDir = path.join(dataDir, 'schemas'); + +let allValid = true; + +// Validate chains data +allValid &= validateFile( + path.join(dataDir, 'chains.json'), + path.join(schemasDir, 'chains-schema.json'), + 'Chains data' +); + +// Validate tokens data +allValid &= validateFile( + path.join(dataDir, 'tokens.json'), + path.join(schemasDir, 'tokens-schema.json'), + 'Tokens data' +); + +if (allValid) { + console.log('\nāœ… All data files are valid!'); + process.exit(0); +} else { + console.log('\nāŒ Some data files have validation errors'); + process.exit(1); +} \ No newline at end of file diff --git a/scripts/watch-data.cjs b/scripts/watch-data.cjs new file mode 100755 index 0000000..f202969 --- /dev/null +++ b/scripts/watch-data.cjs @@ -0,0 +1,41 @@ +#!/usr/bin/env node + +const fs = require('fs'); +const path = require('path'); +const { execSync } = require('child_process'); + +const dataDir = path.join(__dirname, '../data'); +const generateScript = path.join(__dirname, 'generate-all.cjs'); + +console.log('šŸ‘€ Watching JSON data files for changes...'); +console.log(`Watching: ${dataDir}`); +console.log('Press Ctrl+C to stop\n'); + +function regenerateAll() { + console.log('\nšŸ”„ Data files changed, regenerating packages...'); + try { + execSync(`node "${generateScript}"`, { stdio: 'inherit' }); + console.log('\nāœ… Regeneration complete!\n'); + } catch (error) { + console.error(`āŒ Regeneration failed: ${error.message}`); + } +} + +// Initial generation +regenerateAll(); + +// Watch for changes +fs.watch(dataDir, { recursive: true }, (eventType, filename) => { + if (filename && filename.endsWith('.json') && !filename.includes('schema')) { + console.log(`šŸ“ File changed: ${filename}`); + // Debounce multiple rapid changes + clearTimeout(regenerateAll.timeout); + regenerateAll.timeout = setTimeout(regenerateAll, 500); + } +}); + +// Keep process alive +process.on('SIGINT', () => { + console.log('\nšŸ‘‹ Stopping file watcher...'); + process.exit(0); +}); \ No newline at end of file diff --git a/src/index.ts b/src/index.ts deleted file mode 100644 index 69ee52a..0000000 --- a/src/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./networks"; -export * from "./tokens"; diff --git a/src/networks.ts b/src/networks.ts deleted file mode 100644 index 8cf3c41..0000000 --- a/src/networks.ts +++ /dev/null @@ -1,527 +0,0 @@ -// Chain names and IDs. -export const TESTNET_SEPOLIA_CHAIN_IDs = { - ARBITRUM_SEPOLIA: 421614, - BASE_SEPOLIA: 84532, - BLAST_SEPOLIA: 168587773, - BOB_SEPOLIA: 808813, - HYPEREVM_TESTNET: 998, - INK_SEPOLIA: 763373, - TATARA: 129399, - LENS_SEPOLIA: 37111, - LISK_SEPOLIA: 4202, - MODE_SEPOLIA: 919, - OPTIMISM_SEPOLIA: 11155420, - POLYGON_AMOY: 80002, - SCROLL_SEPOLIA: 534351, - SEPOLIA: 11155111, - UNICHAIN_SEPOLIA: 1301, - ZK_SYNC_SEPOLIA: 300, -}; - -export const TESTNET_CHAIN_IDs = { - ...TESTNET_SEPOLIA_CHAIN_IDs, - SOLANA_DEVNET: 133268194659241, -} as const; - -export const MAINNET_CHAIN_IDs = { - ALEPH_ZERO: 41455, - ARBITRUM: 42161, - BASE: 8453, - BLAST: 81457, - BOB: 60808, - BSC: 56, - BOBA: 288, - HYPEREVM: 999, - INK: 57073, - LENS: 232, - LINEA: 59144, - LISK: 1135, - MAINNET: 1, - MODE: 34443, - OPTIMISM: 10, - POLYGON: 137, - REDSTONE: 690, - SCROLL: 534352, - SONEIUM: 1868, - SUPERSEED: 5330, - UNICHAIN: 130, - WORLD_CHAIN: 480, - ZK_SYNC: 324, - ZORA: 7777777, - SOLANA: 34268394551451, -}; - -export const CHAIN_IDs = { - ...MAINNET_CHAIN_IDs, - ...TESTNET_CHAIN_IDs, -}; - -export enum ChainFamily { - NONE, - OP_STACK, - ORBIT, // Future: Might need to distinguish between ORBIT_L2 and ORBIT_L3... - ZK_STACK, - SVM, -} - -// Source https://docs.layerzero.network/v2/developers/evm/technical-reference/deployed-contracts -export const PRODUCTION_OFT_EIDs = { - ARBITRUM: 30110, - BASE: 30184, - BLAST: 30243, - BSC: 30102, - HYPEREVM: 30367, - MAINNET: 30101, - OPTIMISM: 30111, - POLYGON: 30109, - SONEIUM: 30340, - UNICHAIN: 30320, - WORLD_CHAIN: 30319, - SOLANA: 30168, -}; - -// Source https://docs.layerzero.network/v2/developers/evm/technical-reference/deployed-contracts -export const TESTNET_OFT_EIDs = { - ARBITRUM_SEPOLIA: 40231, - BASE_SEPOLIA: 40245, - OPTIMISM_SEPOLIA: 40232, - HYPEREVM_TESTNET: 40362, - POLYGON_AMOY: 40267, - SEPOLIA: 40161, - UNICHAIN_SEPOLIA: 40333, - SOLANA_DEVNET: 40168, -}; - -// Collection of Hyperlane domain ids that are different from CHAIN_IDs. -// Source https://github.com/hyperlane-xyz/hyperlane-registry -export const HYPERLANE_DOMAIN_ID_OVERRIDES = { - SOLANA: 1399811149, - SOLANA_DEVNET: 1399811151, -}; - -interface PublicNetwork { - name: string; - family: ChainFamily; - nativeToken: string; - publicRPC: string; // RPC provider of last resort. - blockExplorer: string; - cctpDomain: number; - oftEid: number; - hypDomainId: number; // Hyperlane domain id -} - -export const CCTP_NO_DOMAIN = -1; -export const OFT_NO_EID = -1; -export const HYPERLANE_NO_DOMAIN_ID = -1; - -const { NONE, OP_STACK, ORBIT, SVM, ZK_STACK } = ChainFamily; -export const PRODUCTION_NETWORKS: { [chainId: number]: PublicNetwork } = { - [CHAIN_IDs.ALEPH_ZERO]: { - name: "Aleph Zero", - family: ORBIT, - nativeToken: "AZERO", - publicRPC: "https://rpc.alephzero.raas.gelato.cloud", - blockExplorer: "https://evm-explorer.alephzero.org", - cctpDomain: CCTP_NO_DOMAIN, - oftEid: OFT_NO_EID, - hypDomainId: HYPERLANE_NO_DOMAIN_ID, - }, - [CHAIN_IDs.ARBITRUM]: { - name: "Arbitrum One", - family: NONE, - nativeToken: "ETH", - publicRPC: "https://arb1.arbitrum.io/rpc", - blockExplorer: "https://arbiscan.io", - cctpDomain: 3, - oftEid: PRODUCTION_OFT_EIDs.ARBITRUM, - hypDomainId: MAINNET_CHAIN_IDs.ARBITRUM, - }, - [CHAIN_IDs.BASE]: { - name: "Base", - family: OP_STACK, - nativeToken: "ETH", - publicRPC: "https://mainnet.base.org", - blockExplorer: "https://basescan.org", - cctpDomain: 6, - oftEid: PRODUCTION_OFT_EIDs.BASE, - hypDomainId: MAINNET_CHAIN_IDs.BASE, - }, - [CHAIN_IDs.BLAST]: { - name: "Blast", - family: OP_STACK, - nativeToken: "ETH", - publicRPC: "https://rpc.blast.io", - blockExplorer: "https://blastscan.io", - cctpDomain: CCTP_NO_DOMAIN, - oftEid: PRODUCTION_OFT_EIDs.BLAST, - hypDomainId: MAINNET_CHAIN_IDs.BLAST, - }, - [CHAIN_IDs.BSC]: { - name: "BNB Smart Chain", - family: NONE, - nativeToken: "BNB", - publicRPC: "https://bsc-dataseed1.binance.org", - blockExplorer: "https://bscscan.com", - cctpDomain: CCTP_NO_DOMAIN, - oftEid: PRODUCTION_OFT_EIDs.BSC, - hypDomainId: MAINNET_CHAIN_IDs.BSC, - }, - [CHAIN_IDs.BOBA]: { - name: "Boba", - family: OP_STACK, - nativeToken: "ETH", - publicRPC: "https://mainnet.boba.network", - blockExplorer: "https://blockexplorer.boba.network", - cctpDomain: CCTP_NO_DOMAIN, - oftEid: OFT_NO_EID, - hypDomainId: HYPERLANE_NO_DOMAIN_ID, - }, - [CHAIN_IDs.HYPEREVM]: { - name: "HyperEVM", - family: NONE, - nativeToken: "HYPE", - publicRPC: "https://rpc.hyperliquid.xyz/evm", - blockExplorer: "https://hyperevmscan.io/", - cctpDomain: 19, - oftEid: PRODUCTION_OFT_EIDs.HYPEREVM, - hypDomainId: CHAIN_IDs.HYPEREVM, - }, - [CHAIN_IDs.UNICHAIN]: { - name: "Unichain", - family: OP_STACK, - nativeToken: "ETH", - publicRPC: "https://mainnet.unichain.org/", - blockExplorer: "https://uniscan.xyz", - cctpDomain: 10, - oftEid: PRODUCTION_OFT_EIDs.UNICHAIN, - hypDomainId: MAINNET_CHAIN_IDs.UNICHAIN, - }, - [CHAIN_IDs.INK]: { - name: "Ink", - family: OP_STACK, - nativeToken: "ETH", - publicRPC: "https://rpc-gel.inkonchain.com", - blockExplorer: "https://explorer.inkonchain.com", - cctpDomain: CCTP_NO_DOMAIN, - oftEid: OFT_NO_EID, - hypDomainId: MAINNET_CHAIN_IDs.INK, - }, - [CHAIN_IDs.TATARA]: { - name: "Tatara", - family: NONE, // Snowflake family - tbd - nativeToken: "ETH", - publicRPC: "https://rpc.tatara.katanarpc.com/", - blockExplorer: "https://explorer.tatara.katana.network", - cctpDomain: CCTP_NO_DOMAIN, - oftEid: OFT_NO_EID, - hypDomainId: HYPERLANE_NO_DOMAIN_ID, - }, - [CHAIN_IDs.LENS]: { - name: "Lens", - family: ZK_STACK, - nativeToken: "WGHO", - publicRPC: "https://api.lens.matterhosted.dev", - blockExplorer: "https://explorer.lens.xyz", - cctpDomain: CCTP_NO_DOMAIN, - oftEid: OFT_NO_EID, - hypDomainId: HYPERLANE_NO_DOMAIN_ID, - }, - [CHAIN_IDs.LINEA]: { - name: "Linea", - family: NONE, - nativeToken: "ETH", - publicRPC: "https://rpc.linea.build", - blockExplorer: "https://lineascan.build", - cctpDomain: 11, - oftEid: OFT_NO_EID, - hypDomainId: MAINNET_CHAIN_IDs.LINEA, - }, - [CHAIN_IDs.LISK]: { - name: "Lisk", - family: OP_STACK, - nativeToken: "ETH", - publicRPC: "https://rpc.api.lisk.com", - blockExplorer: "https://blockscout.lisk.com", - cctpDomain: CCTP_NO_DOMAIN, - oftEid: OFT_NO_EID, - hypDomainId: HYPERLANE_NO_DOMAIN_ID, - }, - [CHAIN_IDs.MAINNET]: { - name: "Mainnet", - family: NONE, - nativeToken: "ETH", - publicRPC: "https://eth.llamarpc.com", - blockExplorer: "https://etherscan.io", - cctpDomain: 0, - oftEid: PRODUCTION_OFT_EIDs.MAINNET, - hypDomainId: MAINNET_CHAIN_IDs.MAINNET, - }, - [CHAIN_IDs.MODE]: { - name: "Mode", - family: OP_STACK, - nativeToken: "ETH", - publicRPC: "https://mainnet.mode.network", - blockExplorer: "https://explorer.mode.network", - cctpDomain: CCTP_NO_DOMAIN, - oftEid: OFT_NO_EID, - hypDomainId: MAINNET_CHAIN_IDs.MODE, - }, - [CHAIN_IDs.OPTIMISM]: { - name: "Optimism", - family: OP_STACK, - nativeToken: "ETH", - publicRPC: "https://mainnet.optimism.io", - blockExplorer: "https://optimistic.etherscan.io", - cctpDomain: 2, - oftEid: PRODUCTION_OFT_EIDs.OPTIMISM, - hypDomainId: MAINNET_CHAIN_IDs.OPTIMISM, - }, - [CHAIN_IDs.POLYGON]: { - name: "Polygon", - family: NONE, - nativeToken: "MATIC", - publicRPC: "https://polygon-rpc.com", - blockExplorer: "https://polygonscan.com", - cctpDomain: 7, - oftEid: PRODUCTION_OFT_EIDs.POLYGON, - hypDomainId: MAINNET_CHAIN_IDs.POLYGON, - }, - [CHAIN_IDs.REDSTONE]: { - name: "Redstone", - family: OP_STACK, - nativeToken: "ETH", - publicRPC: "https://rpc.redstonechain.com", - blockExplorer: "https://explorer.redstone.xyz", - cctpDomain: CCTP_NO_DOMAIN, - oftEid: OFT_NO_EID, - hypDomainId: MAINNET_CHAIN_IDs.REDSTONE, - }, - [CHAIN_IDs.SCROLL]: { - name: "Scroll", - family: NONE, - nativeToken: "ETH", - publicRPC: "https://rpc.scroll.io", - blockExplorer: "https://scrollscan.com", - cctpDomain: CCTP_NO_DOMAIN, - oftEid: OFT_NO_EID, - hypDomainId: HYPERLANE_NO_DOMAIN_ID, - }, - [CHAIN_IDs.SOLANA]: { - name: "Solana", - family: SVM, - nativeToken: "SOL", - publicRPC: "https://api.mainnet-beta.solana.com", - blockExplorer: "https://solscan.io", - cctpDomain: 5, - oftEid: PRODUCTION_OFT_EIDs.SOLANA, - hypDomainId: HYPERLANE_DOMAIN_ID_OVERRIDES.SOLANA, - }, - [CHAIN_IDs.SONEIUM]: { - name: "Soneium", - family: OP_STACK, - nativeToken: "ETH", - publicRPC: "https://rpc.soneium.org", - blockExplorer: "https://soneium.blockscout.com", - cctpDomain: CCTP_NO_DOMAIN, - oftEid: PRODUCTION_OFT_EIDs.SONEIUM, - hypDomainId: HYPERLANE_NO_DOMAIN_ID, - }, - [CHAIN_IDs.SUPERSEED]: { - name: "Superseed", - family: OP_STACK, - nativeToken: "ETH", - publicRPC: "https://mainnet.superseed.xyz", - blockExplorer: "", // @todo: To be added later - cctpDomain: CCTP_NO_DOMAIN, - oftEid: OFT_NO_EID, - hypDomainId: HYPERLANE_NO_DOMAIN_ID, - }, - [CHAIN_IDs.WORLD_CHAIN]: { - name: "World Chain", - family: OP_STACK, - nativeToken: "ETH", - publicRPC: "https://worldchain-mainnet.g.alchemy.com/public", - blockExplorer: "https://worldchain-mainnet-explorer.alchemy.com", - cctpDomain: 14, - oftEid: PRODUCTION_OFT_EIDs.WORLD_CHAIN, - hypDomainId: MAINNET_CHAIN_IDs.WORLD_CHAIN, - }, - [CHAIN_IDs.ZK_SYNC]: { - name: "zkSync", - family: NONE, - nativeToken: "ETH", - publicRPC: "https://mainnet.era.zksync.io", - blockExplorer: "https://era.zksync.network", - cctpDomain: CCTP_NO_DOMAIN, - oftEid: OFT_NO_EID, - hypDomainId: MAINNET_CHAIN_IDs.ZK_SYNC, - }, - [CHAIN_IDs.ZORA]: { - name: "Zora", - family: OP_STACK, - nativeToken: "ETH", - publicRPC: "https://rpc.zora.energy", - blockExplorer: "https://zorascan.xyz", - cctpDomain: CCTP_NO_DOMAIN, - oftEid: OFT_NO_EID, - hypDomainId: HYPERLANE_NO_DOMAIN_ID, - }, -}; - -export const TEST_NETWORKS: { [chainId: number]: PublicNetwork } = { - [CHAIN_IDs.ARBITRUM_SEPOLIA]: { - name: "Arbitrum Sepolia", - family: NONE, - nativeToken: "ETH", - publicRPC: "https://sepolia-rollup.arbitrum.io/rpc", - blockExplorer: "https://sepolia.arbiscan.io", - cctpDomain: 3, - oftEid: TESTNET_OFT_EIDs.ARBITRUM_SEPOLIA, - hypDomainId: TESTNET_CHAIN_IDs.ARBITRUM_SEPOLIA, - }, - [CHAIN_IDs.BASE_SEPOLIA]: { - name: "Base Sepolia", - family: OP_STACK, - nativeToken: "ETH", - publicRPC: "https://sepolia.base.org", - blockExplorer: "https://sepolia.basescan.org", - cctpDomain: 6, - oftEid: TESTNET_OFT_EIDs.BASE_SEPOLIA, - hypDomainId: TESTNET_CHAIN_IDs.BASE_SEPOLIA, - }, - [CHAIN_IDs.BLAST_SEPOLIA]: { - name: "Blast Sepolia", - family: OP_STACK, - nativeToken: "ETH", - publicRPC: "https://sepolia.blast.io", - blockExplorer: "https://sepolia.blastscan.io", - cctpDomain: CCTP_NO_DOMAIN, - oftEid: OFT_NO_EID, - hypDomainId: TESTNET_CHAIN_IDs.BLAST_SEPOLIA, - }, - [CHAIN_IDs.BOB_SEPOLIA]: { - name: "BOB Sepolia", - family: OP_STACK, - nativeToken: "ETH", - publicRPC: "https://bob-sepolia.rpc.gobob.xyz", - blockExplorer: "https://bob-sepolia.explorer.gobob.xyz", - cctpDomain: CCTP_NO_DOMAIN, - oftEid: OFT_NO_EID, - hypDomainId: HYPERLANE_NO_DOMAIN_ID, - }, - [CHAIN_IDs.HYPEREVM_TESTNET]: { - name: "HyperEVM Testnet", - family: NONE, - nativeToken: "HYPE", - publicRPC: "https://rpc.hyperliquid-testnet.xyz/evm", - blockExplorer: "https://testnet.purrsec.com/", - cctpDomain: 19, - oftEid: TESTNET_OFT_EIDs.HYPEREVM_TESTNET, - hypDomainId: TESTNET_CHAIN_IDs.HYPEREVM_TESTNET, - }, - [CHAIN_IDs.LENS_SEPOLIA]: { - name: "Lens Sepolia", - family: ZK_STACK, - nativeToken: "GRASS", - publicRPC: "https://rpc.testnet.lens.dev", - blockExplorer: "https://block-explorer.testnet.lens.dev", - cctpDomain: CCTP_NO_DOMAIN, - oftEid: OFT_NO_EID, - hypDomainId: HYPERLANE_NO_DOMAIN_ID, - }, - [CHAIN_IDs.LISK_SEPOLIA]: { - name: "Lisk Sepolia", - family: OP_STACK, - nativeToken: "ETH", - publicRPC: "https://rpc.sepolia-api.lisk.com", - blockExplorer: "https://sepolia-blockscout.lisk.com", - cctpDomain: CCTP_NO_DOMAIN, - oftEid: OFT_NO_EID, - hypDomainId: HYPERLANE_NO_DOMAIN_ID, - }, - [CHAIN_IDs.MODE_SEPOLIA]: { - name: "Mode Sepolia", - family: OP_STACK, - nativeToken: "ETH", - publicRPC: "https://sepolia.mode.network", - blockExplorer: "https://sepolia.explorer.mode.network", - cctpDomain: CCTP_NO_DOMAIN, - oftEid: OFT_NO_EID, - hypDomainId: TESTNET_CHAIN_IDs.MODE_SEPOLIA, - }, - [CHAIN_IDs.OPTIMISM_SEPOLIA]: { - name: "Optimism Sepolia", - family: OP_STACK, - nativeToken: "ETH", - publicRPC: "https://sepolia.optimism.io", - blockExplorer: "https://sepolia-optimism.etherscan.io", - cctpDomain: 2, - oftEid: TESTNET_OFT_EIDs.OPTIMISM_SEPOLIA, - hypDomainId: TESTNET_CHAIN_IDs.OPTIMISM_SEPOLIA, - }, - [CHAIN_IDs.POLYGON_AMOY]: { - name: "Polygon Amoy", - family: NONE, - nativeToken: "MATIC", - publicRPC: "https://rpc-amoy.polygon.technology", - blockExplorer: "https://amoy.polygonscan.com", - cctpDomain: 7, - oftEid: TESTNET_OFT_EIDs.POLYGON_AMOY, - hypDomainId: TESTNET_CHAIN_IDs.POLYGON_AMOY, - }, - [CHAIN_IDs.SCROLL_SEPOLIA]: { - name: "Scroll Sepolia", - family: NONE, - nativeToken: "ETH", - publicRPC: "https://sepolia-rpc.scroll.io", - blockExplorer: "https://sepolia.scrollscan.com", - cctpDomain: CCTP_NO_DOMAIN, - oftEid: OFT_NO_EID, - hypDomainId: HYPERLANE_NO_DOMAIN_ID, - }, - [CHAIN_IDs.SEPOLIA]: { - name: "Sepolia", - family: NONE, - nativeToken: "ETH", - publicRPC: "https://sepolia.drpc.org", - blockExplorer: "https://sepolia.etherscan.io", - cctpDomain: 0, - oftEid: TESTNET_OFT_EIDs.SEPOLIA, - hypDomainId: TESTNET_CHAIN_IDs.SEPOLIA, - }, - [CHAIN_IDs.SOLANA_DEVNET]: { - name: "Solana Devnet", - family: SVM, - nativeToken: "SOL", - publicRPC: "https://api.devnet.solana.com", - blockExplorer: "https://explorer.solana.com/?cluster=devnet", - cctpDomain: 5, - oftEid: TESTNET_OFT_EIDs.SOLANA_DEVNET, - hypDomainId: HYPERLANE_DOMAIN_ID_OVERRIDES.SOLANA_DEVNET, - }, - [CHAIN_IDs.UNICHAIN_SEPOLIA]: { - name: "Unichain Sepolia", - family: OP_STACK, - nativeToken: "ETH", - publicRPC: "https://sepolia.unichain.org", - blockExplorer: "https://sepolia.uniscan.xyz", - cctpDomain: 10, - oftEid: TESTNET_OFT_EIDs.UNICHAIN_SEPOLIA, - hypDomainId: TESTNET_CHAIN_IDs.UNICHAIN_SEPOLIA, - }, - [CHAIN_IDs.ZK_SYNC_SEPOLIA]: { - name: "zkSync Sepolia", - family: NONE, - nativeToken: "ETH", - publicRPC: "https://sepolia.era.zksync.dev", - blockExplorer: "https://sepolia-era.zksync.network", - cctpDomain: CCTP_NO_DOMAIN, - oftEid: OFT_NO_EID, - hypDomainId: TESTNET_CHAIN_IDs.ZK_SYNC_SEPOLIA, - }, -}; - -export const PUBLIC_NETWORKS = { - ...PRODUCTION_NETWORKS, - ...TEST_NETWORKS, -}; diff --git a/src/tokens.ts b/src/tokens.ts deleted file mode 100644 index d6387a0..0000000 --- a/src/tokens.ts +++ /dev/null @@ -1,642 +0,0 @@ -import { CHAIN_IDs } from "./networks"; - -// Information for the supported tokens on each chain. -// NOTE: All addresses should be checksummed -export const TOKEN_SYMBOLS_MAP = { - ACX: { - name: "Across Protocol Token", - symbol: "ACX", - decimals: 18, - addresses: { - [CHAIN_IDs.ARBITRUM]: "0x53691596d1BCe8CEa565b84d4915e69e03d9C99d", - [CHAIN_IDs.BOBA]: "0x96821b258955587069F680729cD77369C0892B40", - [CHAIN_IDs.MAINNET]: "0x44108f0223A3C3028F5Fe7AEC7f9bb2E66beF82F", - [CHAIN_IDs.OPTIMISM]: "0xFf733b2A3557a7ed6697007ab5D11B79FdD1b76B", - [CHAIN_IDs.POLYGON]: "0xF328b73B6c685831F238c30a23Fc19140CB4D8FC", - [CHAIN_IDs.SEPOLIA]: "0x49fCaC04AE71dbD074304Fb12071bD771e0E927A", - }, - coingeckoId: "across-protocol", - }, - ARB: { - name: "Arbitrum", - symbol: "ARB", - decimals: 18, - addresses: { - [CHAIN_IDs.ARBITRUM]: "0x912CE59144191C1204E64559FE8253a0e49E6548", - [CHAIN_IDs.MAINNET]: "0xB50721BCf8d664c30412Cfbc6cf7a15145234ad1", - }, - coingeckoId: "arbitrum", - }, - AZERO: { - name: "Aleph Zero", - symbol: "AZERO", - decimals: 18, - addresses: { - [CHAIN_IDs.ALEPH_ZERO]: "0xb7Da55D7040ef9C887e20374D76A88F93A59119E", - [CHAIN_IDs.MAINNET]: "0xdD0ae774F7E300CdAA4EA371cD55169665Ee6AFe", - }, - coingeckoId: "aleph-zero", - }, - BADGER: { - name: "Badger", - symbol: "BADGER", - decimals: 18, - addresses: { - [CHAIN_IDs.ARBITRUM]: "0xBfa641051Ba0a0Ad1b0AcF549a89536A0D76472E", - [CHAIN_IDs.MAINNET]: "0x3472A5A71965499acd81997a54BBA8D852C6E53d", - [CHAIN_IDs.POLYGON]: "0x1FcbE5937B0cc2adf69772D228fA4205aCF4D9b2", - }, - coingeckoId: "badger-dao", - }, - BAL: { - name: "Balancer", - symbol: "BAL", - decimals: 18, - addresses: { - [CHAIN_IDs.ARBITRUM]: "0x040d1EdC9569d4Bab2D15287Dc5A4F10F56a56B8", - [CHAIN_IDs.BASE]: "0x4158734D47Fc9692176B5085E0F52ee0Da5d47F1", - [CHAIN_IDs.LINEA]: "0x660edb0A46c3f69be9eFF5446318593b9469F9e2", - [CHAIN_IDs.MAINNET]: "0xba100000625a3754423978a60c9317c58a424e3D", - [CHAIN_IDs.OPTIMISM]: "0xFE8B128bA8C78aabC59d4c64cEE7fF28e9379921", - [CHAIN_IDs.POLYGON]: "0x9a71012B13CA4d3D0Cdc72A177DF3ef03b0E76A3", - }, - coingeckoId: "balancer", - }, - BNB: { - name: "BNB", - symbol: "BNB", - decimals: 18, - addresses: { - [CHAIN_IDs.BSC]: "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c", - [CHAIN_IDs.MAINNET]: "0xB8c77482e45F1F44dE1745F52C74426C631bDD52", - }, - coingeckoId: "binancecoin", - }, - BOBA: { - name: "Boba", - symbol: "BOBA", - decimals: 18, - addresses: { - [CHAIN_IDs.BOBA]: "0xa18bF3994C0Cc6E3b63ac420308E5383f53120D7", - [CHAIN_IDs.MAINNET]: "0x42bBFa2e77757C645eeaAd1655E0911a7553Efbc", - }, - coingeckoId: "boba-network", - }, - CAKE: { - name: "PancakeSwap Token", - symbol: "CAKE", - decimals: 18, - addresses: { - [CHAIN_IDs.BSC]: "0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82", - [CHAIN_IDs.MAINNET]: "0x152649eA73beAb28c5b49B26eb48f7EAD6d4c898", - }, - coingeckoId: "pancakeswap-token", - }, - DAI: { - name: "Dai Stablecoin", - symbol: "DAI", - decimals: 18, - addresses: { - [CHAIN_IDs.ARBITRUM]: "0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1", - [CHAIN_IDs.BASE]: "0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb", - [CHAIN_IDs.BOBA]: "0xf74195Bb8a5cf652411867c5C2C5b8C2a402be35", - [CHAIN_IDs.LINEA]: "0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d5", - [CHAIN_IDs.MAINNET]: "0x6B175474E89094C44Da98b954EedeAC495271d0F", - [CHAIN_IDs.OPTIMISM]: "0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1", - [CHAIN_IDs.POLYGON]: "0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063", - [CHAIN_IDs.ZK_SYNC]: "0x4B9eb6c0b6ea15176BBF62841C6B2A8a398cb656", - }, - coingeckoId: "dai", - }, - ETH: { - name: "Ether", - symbol: "ETH", - decimals: 18, - addresses: { - [CHAIN_IDs.ALEPH_ZERO]: "0xB3f0eE446723f4258862D949B4c9688e7e7d35d3", - [CHAIN_IDs.ARBITRUM]: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1", - [CHAIN_IDs.ARBITRUM_SEPOLIA]: "0x980B62Da83eFf3D4576C647993b0c1D7faf17c73", - [CHAIN_IDs.BASE]: "0x4200000000000000000000000000000000000006", - [CHAIN_IDs.BASE_SEPOLIA]: "0x4200000000000000000000000000000000000006", - [CHAIN_IDs.BSC]: "0x2170Ed0880ac9A755fd29B2688956BD959F933F8", - [CHAIN_IDs.BOB]: "0x4200000000000000000000000000000000000006", - [CHAIN_IDs.BOB_SEPOLIA]: "0x4200000000000000000000000000000000000006", - [CHAIN_IDs.BOBA]: "0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000", - [CHAIN_IDs.BLAST]: "0x4300000000000000000000000000000000000004", - [CHAIN_IDs.BLAST_SEPOLIA]: "0x4200000000000000000000000000000000000023", - [CHAIN_IDs.INK]: "0x4200000000000000000000000000000000000006", - [CHAIN_IDs.INK_SEPOLIA]: "0x4200000000000000000000000000000000000006", - [CHAIN_IDs.LENS]: "0xE5ecd226b3032910CEaa43ba92EE8232f8237553", - [CHAIN_IDs.LENS_SEPOLIA]: "0xaA91D645D7a6C1aeaa5988e0547267B77d33fe16", - [CHAIN_IDs.LINEA]: "0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f", - [CHAIN_IDs.LISK]: "0x4200000000000000000000000000000000000006", - [CHAIN_IDs.LISK_SEPOLIA]: "0x4200000000000000000000000000000000000006", - [CHAIN_IDs.MAINNET]: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", - [CHAIN_IDs.MODE]: "0x4200000000000000000000000000000000000006", - [CHAIN_IDs.MODE_SEPOLIA]: "0x4200000000000000000000000000000000000006", - [CHAIN_IDs.OPTIMISM]: "0x4200000000000000000000000000000000000006", - [CHAIN_IDs.OPTIMISM_SEPOLIA]: "0x4200000000000000000000000000000000000006", - [CHAIN_IDs.POLYGON]: "0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619", - [CHAIN_IDs.POLYGON_AMOY]: "0x52eF3d68BaB452a294342DC3e5f464d7f610f72E", - [CHAIN_IDs.REDSTONE]: "0x4200000000000000000000000000000000000006", - [CHAIN_IDs.SCROLL]: "0x5300000000000000000000000000000000000004", - [CHAIN_IDs.SCROLL_SEPOLIA]: "0x5300000000000000000000000000000000000004", - [CHAIN_IDs.SEPOLIA]: "0xfFf9976782d46CC05630D1f6eBAb18b2324d6B14", - [CHAIN_IDs.SONEIUM]: "0x4200000000000000000000000000000000000006", - [CHAIN_IDs.TATARA]: "0x17B8Ee96E3bcB3b04b3e8334de4524520C51caB4", - [CHAIN_IDs.UNICHAIN]: "0x4200000000000000000000000000000000000006", - [CHAIN_IDs.UNICHAIN_SEPOLIA]: "0x4200000000000000000000000000000000000006", - [CHAIN_IDs.WORLD_CHAIN]: "0x4200000000000000000000000000000000000006", - [CHAIN_IDs.ZK_SYNC]: "0x5AEa5775959fBC2557Cc8789bC1bf90A239D9a91", - [CHAIN_IDs.ZK_SYNC_SEPOLIA]: "0x2D6Db36B3117802E996f13073A08A685D3FeF7eD", - [CHAIN_IDs.ZORA]: "0x4200000000000000000000000000000000000006", - }, - coingeckoId: "ethereum", - }, - ezETH: { - name: "Renzo Restaked ETH", - symbol: "ezETH", - decimals: 18, - addresses: { - [CHAIN_IDs.ARBITRUM]: "0x2416092f143378750bb29b79eD961ab195CcEea5", - [CHAIN_IDs.BASE]: "0x2416092f143378750bb29b79eD961ab195CcEea5", - [CHAIN_IDs.BLAST]: "0x2416092f143378750bb29b79eD961ab195CcEea5", - [CHAIN_IDs.BSC]: "0x2416092f143378750bb29b79eD961ab195CcEea5", - [CHAIN_IDs.LINEA]: "0x2416092f143378750bb29b79eD961ab195CcEea5", - [CHAIN_IDs.MAINNET]: "0xbf5495Efe5DB9ce00f80364C8B423567e58d2110", - [CHAIN_IDs.MODE]: "0x2416092f143378750bb29b79eD961ab195CcEea5", - [CHAIN_IDs.OPTIMISM]: "0x2416092f143378750bb29b79eD961ab195CcEea5", - [CHAIN_IDs.UNICHAIN]: "0x2416092f143378750bb29b79eD961ab195CcEea5", - [CHAIN_IDs.WORLD_CHAIN]: "0x2416092f143378750bb29b79eD961ab195CcEea5", - }, - coingeckoId: "renzo-restaked-eth", - }, - GHO: { - name: "Gho Token", - symbol: "GHO", - decimals: 18, - addresses: { - [CHAIN_IDs.ARBITRUM_SEPOLIA]: "0xb13Cfa6f8B2Eed2C37fB00fF0c1A59807C585810", - [CHAIN_IDs.BASE_SEPOLIA]: "0x7CFa3f3d1cded0Da930881c609D4Dbf0012c14Bb", - [CHAIN_IDs.LENS]: "0x000000000000000000000000000000000000800A", - [CHAIN_IDs.MAINNET]: "0x40D16FC0246aD3160Ccc09B8D0D3A2cD28aE6C2f", - [CHAIN_IDs.OPTIMISM_SEPOLIA]: "0xb13Cfa6f8B2Eed2C37fB00fF0c1A59807C585810", - [CHAIN_IDs.SEPOLIA]: "0xc4bF5CbDaBE595361438F8c6a187bDc330539c60", - }, - coingeckoId: "gho", - }, - GRASS: { - name: "Grass", - symbol: "GRASS", - decimals: 18, - addresses: { - [CHAIN_IDs.LENS_SEPOLIA]: "0xeee5a340Cdc9c179Db25dea45AcfD5FE8d4d3eB8", - [CHAIN_IDs.SEPOLIA]: "0x2Be68B15c693D3b5747F9F0D49D30A2E81BAA2Df", - }, - coingeckoId: "gho", // GRASS is Sepolia GHO. - }, - HYPE: { - name: "Hyperliquid", - symbol: "HYPE", - decimals: 18, - addresses: { - [CHAIN_IDs.HYPEREVM]: "0x5555555555555555555555555555555555555555", - [CHAIN_IDs.HYPEREVM_TESTNET]: "0x5555555555555555555555555555555555555555", - }, - coingeckoId: "hyperliquid", - }, - WHYPE: { - name: "Wrapped Hyperliquid", - symbol: "WHYPE", - decimals: 18, - addresses: { - [CHAIN_IDs.HYPEREVM]: "0x5555555555555555555555555555555555555555", - [CHAIN_IDs.HYPEREVM_TESTNET]: "0x5555555555555555555555555555555555555555", - }, - coingeckoId: "hyperliquid", - }, - LSK: { - name: "Lisk", - symbol: "LSK", - decimals: 18, - addresses: { - [CHAIN_IDs.LISK]: "0xac485391EB2d7D88253a7F1eF18C37f4242D1A24", - [CHAIN_IDs.MAINNET]: "0x6033F7f88332B8db6ad452B7C6D5bB643990aE3f", - }, - coingeckoId: "lisk", - }, - MATIC: { - name: "Matic", - symbol: "MATIC", - decimals: 18, - addresses: { - [CHAIN_IDs.MAINNET]: "0x7D1AfA7B718fb893dB30A3aBc0Cfc608AaCfeBB0", - [CHAIN_IDs.POLYGON_AMOY]: "0x360ad4f9a9A8EFe9A8DCB5f461c4Cc1047E1Dcf9", - [CHAIN_IDs.SEPOLIA]: "0x3fd0A53F4Bf853985a95F4Eb3F9C9FDE1F8e2b53", - }, - coingeckoId: "matic-network", - }, - OP: { - name: "Optimism", - symbol: "OP", - decimals: 18, - addresses: { - [CHAIN_IDs.OPTIMISM]: "0x4200000000000000000000000000000000000042", - }, - coingeckoId: "optimism", - }, - POOL: { - name: "PoolTogether", - symbol: "POOL", - decimals: 18, - addresses: { - [CHAIN_IDs.ARBITRUM]: "0xCF934E2402A5e072928a39a956964eb8F2B5B79C", - [CHAIN_IDs.BASE]: "0xd652C5425aea2Afd5fb142e120FeCf79e18fafc3", - [CHAIN_IDs.MAINNET]: "0x0cEC1A9154Ff802e7934Fc916Ed7Ca50bDE6844e", - [CHAIN_IDs.OPTIMISM]: "0x395Ae52bB17aef68C2888d941736A71dC6d4e125", - [CHAIN_IDs.POLYGON]: "0x25788a1a171ec66Da6502f9975a15B609fF54CF6", - [CHAIN_IDs.SCROLL]: "0xF9Af83FC41e0cc2af2fba93644D542Df6eA0F2b7", - [CHAIN_IDs.WORLD_CHAIN]: "0x7077C71B4AF70737a08287E279B717Dcf64fdC57", - }, - coingeckoId: "pooltogether", - }, - SNX: { - name: "Synthetix", - symbol: "SNX", - decimals: 18, - // Based on https://github.com/Synthetixio/synthetix-docs/blob/fe83d0757977b1cb7f69796126e71a66295bf264/content/addresses.md - addresses: { - [CHAIN_IDs.MAINNET]: "0xC011a73ee8576Fb46F5E1c5751cA3B9Fe0af2a6F", - [CHAIN_IDs.OPTIMISM]: "0x8700dAec35aF8Ff88c16BdF0418774CB3D7599B4", - }, - coingeckoId: "havven", - }, - SOL: { - name: "Solana", - symbol: "SOL", - decimals: 9, - addresses: { - [CHAIN_IDs.SOLANA]: "So11111111111111111111111111111111111111112", - [CHAIN_IDs.SOLANA_DEVNET]: "So11111111111111111111111111111111111111112", - }, - coingeckoId: "solana", - }, - "TATARA-USDC": { - name: "Tatara USDC", - symbol: "TATARA-USDC", - decimals: 6, - addresses: { - [CHAIN_IDs.BASE_SEPOLIA]: "0x3c95BB5f49F3643558aa8F699403564A652FBeB0", - [CHAIN_IDs.POLYGON_AMOY]: "0x8B0180f2101c8260d49339abfEe87927412494B4", - [CHAIN_IDs.SEPOLIA]: "0x2b9Ca0A8C773bb1B92A3dDAE9F882Fd14457DACc", - [CHAIN_IDs.TATARA]: "0x102E14ffF48170F2e5b6d0e30259fCD4eE5E28aE", - }, - coingeckoId: "usd-coin", - }, - "TATARA-USDS": { - name: "Tatara USDS", - symbol: "TATARA-USDS", - decimals: 18, - addresses: { - [CHAIN_IDs.SEPOLIA]: "0xfC7b006bDEd8e5D4A55FbaC7A91dAf3753f085CD", - }, - coingeckoId: "usd-coin", - }, - "TATARA-USDT": { - name: "Tatara USDT", - symbol: "TATARA-USDT", - decimals: 6, - addresses: { - [CHAIN_IDs.SEPOLIA]: "0x18fDA3c97Ea92A04D1636D84948624b414D0058E", - }, - coingeckoId: "usd-coin", - }, - "TATARA-WBTC": { - name: "Tatara WBTC", - symbol: "TATARA-WBTC", - decimals: 18, - addresses: { - [CHAIN_IDs.SEPOLIA]: "0xd67A804510739C33c578162A26324C83DCFC0a0A", - }, - coingeckoId: "wrapped-bitcoin", - }, - UMA: { - name: "UMA Voting Token", - symbol: "UMA", - decimals: 18, - addresses: { - [CHAIN_IDs.ARBITRUM]: "0xd693Ec944A85eeca4247eC1c3b130DCa9B0C3b22", - [CHAIN_IDs.BOBA]: "0x780f33Ad21314d9A1Ffb6867Fe53d48a76Ec0D16", - [CHAIN_IDs.MAINNET]: "0x04Fa0d235C4abf4BcF4787aF4CF447DE572eF828", - [CHAIN_IDs.OPTIMISM]: "0xE7798f023fC62146e8Aa1b36Da45fb70855a77Ea", - [CHAIN_IDs.POLYGON]: "0x3066818837c5e6eD6601bd5a91B0762877A6B731", - }, - coingeckoId: "uma", - }, - USDB: { - name: "USDB", - symbol: "USDB", - decimals: 18, - addresses: { - [CHAIN_IDs.BLAST]: "0x4300000000000000000000000000000000000003", - [CHAIN_IDs.MAINNET]: "0x6B175474E89094C44Da98b954EedeAC495271d0F", - }, - coingeckoId: "usdb", - }, - USDC: { - name: "USD Coin", - symbol: "USDC", - decimals: 6, - addresses: { - [CHAIN_IDs.ARBITRUM]: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831", - [CHAIN_IDs.ARBITRUM_SEPOLIA]: "0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d", - [CHAIN_IDs.BASE]: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", - [CHAIN_IDs.BASE_SEPOLIA]: "0x036CbD53842c5426634e7929541eC2318f3dCF7e", - [CHAIN_IDs.HYPEREVM]: "0xb88339CB7199b77E23DB6E890353E22632Ba630f", - [CHAIN_IDs.HYPEREVM_TESTNET]: "0x2B3370eE501B4a559b57D449569354196457D8Ab", - [CHAIN_IDs.LINEA]: "0x176211869cA2b568f2A7D4EE941E073a821EE1ff", - [CHAIN_IDs.LENS]: "0x88F08E304EC4f90D644Cec3Fb69b8aD414acf884", - [CHAIN_IDs.MAINNET]: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", - [CHAIN_IDs.OPTIMISM]: "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85", - [CHAIN_IDs.OPTIMISM_SEPOLIA]: "0x5fd84259d66Cd46123540766Be93DFE6D43130D7", - [CHAIN_IDs.POLYGON]: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359", - [CHAIN_IDs.POLYGON_AMOY]: "0x41E94Eb019C0762f9Bfcf9Fb1E58725BfB0e7582", - [CHAIN_IDs.SCROLL]: "0x06eFdBFf2a14a7c8E15944D1F4A48F9F95F663A4", - [CHAIN_IDs.SEPOLIA]: "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238", - [CHAIN_IDs.UNICHAIN]: "0x078D782b760474a361dDA0AF3839290b0EF57AD6", - [CHAIN_IDs.UNICHAIN_SEPOLIA]: "0x31d0220469e10c4E71834a79b1f276d740d3768F", - [CHAIN_IDs.WORLD_CHAIN]: "0x79A02482A880bCE3F13e09Da970dC34db4CD24d1", - [CHAIN_IDs.SOLANA]: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", - [CHAIN_IDs.SOLANA_DEVNET]: "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU", - }, - coingeckoId: "usd-coin", - }, - "USDC.e": { - name: "USD Coin (bridged)", - symbol: "USDC.e", - decimals: 6, - addresses: { - [CHAIN_IDs.ALEPH_ZERO]: "0x18d25B4e18165c97e1285212e5d1f80eDD6d3Aa7", - [CHAIN_IDs.ARBITRUM]: "0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8", - [CHAIN_IDs.BOBA]: "0x66a2A913e447d6b4BF33EFbec43aAeF87890FBbc", - [CHAIN_IDs.LISK]: "0xF242275d3a6527d877f2c927a82D9b057609cc71", - [CHAIN_IDs.MAINNET]: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", - [CHAIN_IDs.MODE]: "0xd988097fb8612cc24eeC14542bC03424c656005f", - [CHAIN_IDs.OPTIMISM]: "0x7F5c764cBc14f9669B88837ca1490cCa17c31607", - [CHAIN_IDs.OPTIMISM_SEPOLIA]: "0x9552a0a6624A23B848060AE5901659CDDa1f83f8", - [CHAIN_IDs.POLYGON]: "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174", - [CHAIN_IDs.SONEIUM]: "0xbA9986D2381edf1DA03B0B9c1f8b00dc4AacC369", - [CHAIN_IDs.ZK_SYNC]: "0x3355df6D4c9C3035724Fd0e3914dE96A5a83aaf4", - }, - coingeckoId: "usd-coin-ethereum-bridged", - }, - USDbC: { - name: "USD Coin (bridged)", - symbol: "USDbC", - decimals: 6, - addresses: { - [CHAIN_IDs.BASE]: "0xd9aAEc86B65D86f6A7B5B1b0c42FFA531710b6CA", - [CHAIN_IDs.BASE_SEPOLIA]: "0xE634Ec56B73779eCFfa78109a653FA0aE33D243f", - [CHAIN_IDs.MAINNET]: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", - }, - coingeckoId: "bridged-usd-coin-base", - }, - USDzC: { - name: "USD Coin (bridged)", - symbol: "USDzC", - decimals: 6, - addresses: { - [CHAIN_IDs.MAINNET]: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", - [CHAIN_IDs.ZORA]: "0xCccCCccc7021b32EBb4e8C08314bD62F7c653EC4", - }, - coingeckoId: "usd-coin-ethereum-bridged", - }, - "USDC-BNB": { - name: "USD Coin", - symbol: "USDC-BNB", - decimals: 18, - addresses: { - [CHAIN_IDs.BSC]: "0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d", - [CHAIN_IDs.MAINNET]: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", - }, - l1TokenDecimals: 6, - coingeckoId: "usd-coin", - }, - USDT: { - name: "Tether USD", - symbol: "USDT", - decimals: 6, - addresses: { - [CHAIN_IDs.ALEPH_ZERO]: "0xD648529D4803d3467bA8850577BEd4e4b8Ae583C", - [CHAIN_IDs.ARBITRUM]: "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9", - [CHAIN_IDs.BASE]: "0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2", - [CHAIN_IDs.BOBA]: "0x5DE1677344D3Cb0D7D465c10b72A8f60699C062d", - [CHAIN_IDs.HYPEREVM]: "0xB8CE59FC3717ada4C02eaDF9682A9e934F625ebb", - [CHAIN_IDs.LINEA]: "0xA219439258ca9da29E9Cc4cE5596924745e12B93", - [CHAIN_IDs.LISK]: "0x05D032ac25d322df992303dCa074EE7392C117b9", - [CHAIN_IDs.MAINNET]: "0xdAC17F958D2ee523a2206206994597C13D831ec7", - [CHAIN_IDs.MODE]: "0xf0F161fDA2712DB8b566946122a5af183995e2eD", - [CHAIN_IDs.OPTIMISM]: "0x94b008aA00579c1307B0EF2c499aD98a8ce58e58", - [CHAIN_IDs.POLYGON]: "0xc2132D05D31c914a87C6611C10748AEb04B58e8F", - [CHAIN_IDs.SCROLL]: "0xf55BEC9cafDbE8730f096Aa55dad6D22d44099Df", - [CHAIN_IDs.SEPOLIA]: "0x7169D38820dfd117C3FA1f22a697dBA58d90BA06", - [CHAIN_IDs.ZK_SYNC]: "0x493257fD37EDB34451f62EDf8D2a0C418852bA4C", - }, - coingeckoId: "tether", - }, - "USDT-BNB": { - name: "Tether USD", - symbol: "USDT-BNB", - decimals: 18, - addresses: { - [CHAIN_IDs.BSC]: "0x55d398326f99059fF775485246999027B3197955", - [CHAIN_IDs.MAINNET]: "0xdAC17F958D2ee523a2206206994597C13D831ec7", - }, - l1TokenDecimals: 6, - coingeckoId: "tether", - }, - VLR: { - name: "Velora", - symbol: "VLR", - decimals: 18, - addresses: { - [CHAIN_IDs.BASE]: "0x4e107a0000DB66f0E9Fd2039288Bf811dD1f9c74", - [CHAIN_IDs.MAINNET]: "0x4e107a0000DB66f0E9Fd2039288Bf811dD1f9c74", - [CHAIN_IDs.OPTIMISM]: "0x4e107a0000DB66f0E9Fd2039288Bf811dD1f9c74", - }, - coingeckoId: "velora", - }, - WAZERO: { - name: "Wrapped AZERO", - symbol: "WAZERO", - decimals: 18, - addresses: { - [CHAIN_IDs.ALEPH_ZERO]: "0xb7Da55D7040ef9C887e20374D76A88F93A59119E", - [CHAIN_IDs.MAINNET]: "0xdD0ae774F7E300CdAA4EA371cD55169665Ee6AFe", - }, - coingeckoId: "aleph-zero", - }, - WBNB: { - name: "Wrapped BNB", - symbol: "WBNB", - decimals: 18, - addresses: { - [CHAIN_IDs.BSC]: "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c", - [CHAIN_IDs.MAINNET]: "0xB8c77482e45F1F44dE1745F52C74426C631bDD52", - }, - coingeckoId: "wbnb", - }, - WBTC: { - name: "Wrapped Bitcoin", - symbol: "WBTC", - decimals: 8, - addresses: { - [CHAIN_IDs.ARBITRUM]: "0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f", - [CHAIN_IDs.BLAST]: "0xF7bc58b8D8f97ADC129cfC4c9f45Ce3C0E1D2692", - [CHAIN_IDs.BSC]: "0x7130d2A12B9BCbFAe4f2634d864A1Ee1Ce3Ead9c", - [CHAIN_IDs.BOBA]: "0xdc0486f8bf31DF57a952bcd3c1d3e166e3d9eC8b", - [CHAIN_IDs.LINEA]: "0x3aAB2285ddcDdaD8edf438C1bAB47e1a9D05a9b4", - [CHAIN_IDs.LISK]: "0x03C7054BCB39f7b2e5B2c7AcB37583e32D70Cfa3", - [CHAIN_IDs.MAINNET]: "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599", - [CHAIN_IDs.MODE]: "0xcDd475325D6F564d27247D1DddBb0DAc6fA0a5CF", - [CHAIN_IDs.OPTIMISM]: "0x68f180fcCe6836688e9084f035309E29Bf0A2095", - [CHAIN_IDs.POLYGON]: "0x1BFD67037B42Cf73acF2047067bd4F2C47D9BfD6", - [CHAIN_IDs.WORLD_CHAIN]: "0x03C7054BCB39f7b2e5B2c7AcB37583e32D70Cfa3", - [CHAIN_IDs.SCROLL]: "0x3C1BCa5a656e69edCD0D4E36BEbb3FcDAcA60Cf1", - [CHAIN_IDs.ZK_SYNC]: "0xBBeB516fb02a01611cBBE0453Fe3c580D7281011", - [CHAIN_IDs.BOB_SEPOLIA]: "0xAdCE1AB74C8e64c155953A8BdE37cBB06Cf7086D", - [CHAIN_IDs.SEPOLIA]: "0x9D15Db83680572C9a48826d51b733ea3B0957De3", - }, - coingeckoId: "wrapped-bitcoin", - }, - WETH: { - name: "Wrapped Ether", - symbol: "WETH", - decimals: 18, - addresses: { - [CHAIN_IDs.ALEPH_ZERO]: "0xB3f0eE446723f4258862D949B4c9688e7e7d35d3", - [CHAIN_IDs.ARBITRUM]: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1", - [CHAIN_IDs.ARBITRUM_SEPOLIA]: "0x980B62Da83eFf3D4576C647993b0c1D7faf17c73", - [CHAIN_IDs.BASE]: "0x4200000000000000000000000000000000000006", - [CHAIN_IDs.BASE_SEPOLIA]: "0x4200000000000000000000000000000000000006", - [CHAIN_IDs.BOBA]: "0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000", - [CHAIN_IDs.BLAST]: "0x4300000000000000000000000000000000000004", - [CHAIN_IDs.BLAST_SEPOLIA]: "0x4200000000000000000000000000000000000023", - [CHAIN_IDs.BSC]: "0x2170Ed0880ac9A755fd29B2688956BD959F933F8", - [CHAIN_IDs.INK]: "0x4200000000000000000000000000000000000006", - [CHAIN_IDs.INK_SEPOLIA]: "0x4200000000000000000000000000000000000006", - [CHAIN_IDs.LENS]: "0xE5ecd226b3032910CEaa43ba92EE8232f8237553", - [CHAIN_IDs.LENS_SEPOLIA]: "0xaA91D645D7a6C1aeaa5988e0547267B77d33fe16", - [CHAIN_IDs.LINEA]: "0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f", - [CHAIN_IDs.LISK]: "0x4200000000000000000000000000000000000006", - [CHAIN_IDs.LISK_SEPOLIA]: "0x4200000000000000000000000000000000000006", - [CHAIN_IDs.MAINNET]: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", - [CHAIN_IDs.MODE]: "0x4200000000000000000000000000000000000006", - [CHAIN_IDs.MODE_SEPOLIA]: "0x4200000000000000000000000000000000000006", - [CHAIN_IDs.OPTIMISM]: "0x4200000000000000000000000000000000000006", - [CHAIN_IDs.OPTIMISM_SEPOLIA]: "0x4200000000000000000000000000000000000006", - [CHAIN_IDs.POLYGON]: "0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619", - [CHAIN_IDs.POLYGON_AMOY]: "0x52eF3d68BaB452a294342DC3e5f464d7f610f72E", - [CHAIN_IDs.REDSTONE]: "0x4200000000000000000000000000000000000006", - [CHAIN_IDs.SCROLL]: "0x5300000000000000000000000000000000000004", - [CHAIN_IDs.SCROLL_SEPOLIA]: "0x5300000000000000000000000000000000000004", - [CHAIN_IDs.SEPOLIA]: "0xfFf9976782d46CC05630D1f6eBAb18b2324d6B14", - [CHAIN_IDs.SONEIUM]: "0x4200000000000000000000000000000000000006", - [CHAIN_IDs.TATARA]: "0x17B8Ee96E3bcB3b04b3e8334de4524520C51caB4", - [CHAIN_IDs.UNICHAIN]: "0x4200000000000000000000000000000000000006", - [CHAIN_IDs.UNICHAIN_SEPOLIA]: "0x4200000000000000000000000000000000000006", - [CHAIN_IDs.WORLD_CHAIN]: "0x4200000000000000000000000000000000000006", - [CHAIN_IDs.ZK_SYNC]: "0x5AEa5775959fBC2557Cc8789bC1bf90A239D9a91", - [CHAIN_IDs.ZK_SYNC_SEPOLIA]: "0x2D6Db36B3117802E996f13073A08A685D3FeF7eD", - [CHAIN_IDs.ZORA]: "0x4200000000000000000000000000000000000006", - [CHAIN_IDs.BOB_SEPOLIA]: "0x4200000000000000000000000000000000000006", - }, - coingeckoId: "weth", - }, - WGHO: { - name: "Wrapped GHO Token", - symbol: "WGHO", - decimals: 18, - addresses: { - [CHAIN_IDs.LENS]: "0x6bDc36E20D267Ff0dd6097799f82e78907105e2F", - [CHAIN_IDs.MAINNET]: "0x1ff1dC3cB9eeDbC6Eb2d99C03b30A05cA625fB5a", // Lens Wrapped GHO - }, - coingeckoId: "gho", - }, - WGRASS: { - name: "Wrapped Grass", - symbol: "WGRASS", - decimals: 18, - addresses: { - [CHAIN_IDs.LENS_SEPOLIA]: "0xeee5a340Cdc9c179Db25dea45AcfD5FE8d4d3eB8", - [CHAIN_IDs.SEPOLIA]: "0x2Be68B15c693D3b5747F9F0D49D30A2E81BAA2Df", - }, - coingeckoId: "gho", // GRASS is Sepolia GHO. - }, - WLD: { - name: "Worldcoin", - symbol: "WLD", - decimals: 18, - addresses: { - [CHAIN_IDs.MAINNET]: "0x163f8C2467924be0ae7B5347228CABF260318753", - [CHAIN_IDs.OPTIMISM]: "0xdC6fF44d5d932Cbd77B52E5612Ba0529DC6226F1", - [CHAIN_IDs.WORLD_CHAIN]: "0x2cFc85d8E48F8EAB294be644d9E25C3030863003", - }, - coingeckoId: "worldcoin-wld", - }, - WMATIC: { - name: "Matic", - symbol: "WMATIC", - decimals: 18, - addresses: { - [CHAIN_IDs.MAINNET]: "0x7D1AfA7B718fb893dB30A3aBc0Cfc608AaCfeBB0", - [CHAIN_IDs.POLYGON]: "0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270", - [CHAIN_IDs.POLYGON_AMOY]: "0x360ad4f9a9A8EFe9A8DCB5f461c4Cc1047E1Dcf9", - [CHAIN_IDs.SEPOLIA]: "0x3fd0A53F4Bf853985a95F4Eb3F9C9FDE1F8e2b53", - }, - coingeckoId: "wmatic", - }, - WSOL: { - name: "Wrapped SOL", - symbol: "WSOL", - decimals: 9, - addresses: { - [CHAIN_IDs.SOLANA]: "So11111111111111111111111111111111111111112", - [CHAIN_IDs.SOLANA_DEVNET]: "So11111111111111111111111111111111111111112", - }, - coingeckoId: "wrapped-solana", - }, - XYZ: { - name: "XYZ Token", - symbol: "XYZ", - decimals: 18, - addresses: { - [CHAIN_IDs.BASE_SEPOLIA]: "0x180D555759e4d1d5Cf70C3BaBbAE4B8F410BDAD9", - [CHAIN_IDs.OPTIMISM_SEPOLIA]: "0x180D555759e4d1d5Cf70C3BaBbAE4B8F410BDAD9", - [CHAIN_IDs.SEPOLIA]: "0x180D555759e4d1d5Cf70C3BaBbAE4B8F410BDAD9", - }, - coingeckoId: "xyz", // This is a testnet token only. - }, -}; - -// Hard-coded mapping of token symbols that should be treated as having equivalent -// prices. The right-hand side should map to a token symbol in TOKEN_SYMBOLS_MAP. -export const TOKEN_EQUIVALENCE_REMAPPING: { [symbol: string]: string } = { - [TOKEN_SYMBOLS_MAP["USDC.e"].symbol]: TOKEN_SYMBOLS_MAP.USDC.symbol, - [TOKEN_SYMBOLS_MAP.USDbC.symbol]: TOKEN_SYMBOLS_MAP.USDC.symbol, - [TOKEN_SYMBOLS_MAP.USDzC.symbol]: TOKEN_SYMBOLS_MAP.USDC.symbol, - [TOKEN_SYMBOLS_MAP.USDB.symbol]: TOKEN_SYMBOLS_MAP.DAI.symbol, - [TOKEN_SYMBOLS_MAP["USDC-BNB"].symbol]: TOKEN_SYMBOLS_MAP.USDC.symbol, - [TOKEN_SYMBOLS_MAP["USDT-BNB"].symbol]: TOKEN_SYMBOLS_MAP.USDT.symbol, - LGHO: TOKEN_SYMBOLS_MAP.WGHO.symbol, // LGHO is the symbol for WGHO on L1. - // The TOKEN_SYMBOLS_MAP structure assumes that each L2 token address is unique but several mappings - // can share the same L1 token mapping. Therefore this structure lends itself to querying symbols/decimals/name - // for an L1 token directly on-chain and then looking up the L2 data from this mapping. Therefore, its likely to get - // an "ETH" from this mapping but its mapped to a "WETH" on-chain, therefore map the ETH back to the WETH. Same - // with other native / wrapped token pairings like BNB/WBNB, MATIC/WMATIC, LGHO/WGHO, etc. - ETH: TOKEN_SYMBOLS_MAP.WETH.symbol, - BNB: TOKEN_SYMBOLS_MAP.WBNB.symbol, - HYPE: TOKEN_SYMBOLS_MAP.WHYPE.symbol, - // Testnet remappings. - [TOKEN_SYMBOLS_MAP["TATARA-USDC"].symbol]: TOKEN_SYMBOLS_MAP.USDC.symbol, -}; From 0714d05bca8d11c95e14278d7220559e2c6ce717 Mon Sep 17 00:00:00 2001 From: Chase Coleman Date: Fri, 19 Sep 2025 15:08:08 +0000 Subject: [PATCH 2/2] Bug in Python generation --- scripts/generate-python.cjs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/scripts/generate-python.cjs b/scripts/generate-python.cjs index 9e8a512..171ffec 100755 --- a/scripts/generate-python.cjs +++ b/scripts/generate-python.cjs @@ -105,8 +105,10 @@ class PublicNetwork: PRODUCTION_NETWORKS: Final[Dict[int, PublicNetwork]] = { ${Object.entries(networks.production).map(([chainId, config]) => { - const chainName = Object.entries(mainnetChainIds).find(([, id]) => id.toString() === chainId)?.[0]; + const allChainIds = { ...mainnetChainIds, ...testnetChainIds }; + const chainName = Object.entries(allChainIds).find(([, id]) => id.toString() === chainId)?.[0]; const familyName = Object.entries(chainFamilies).find(([, value]) => value === config.family)?.[0]; + if (!chainName) return null; return ` CHAIN_IDS["${chainName}"]: PublicNetwork( name="${config.name}", family=ChainFamily.${familyName}, @@ -117,13 +119,15 @@ ${Object.entries(networks.production).map(([chainId, config]) => { oft_eid=${config.oftEid}, hyp_domain_id=${config.hypDomainId}, ),`; -}).join('\n')} +}).filter(Boolean).join('\n')} } TEST_NETWORKS: Final[Dict[int, PublicNetwork]] = { ${Object.entries(networks.testnet).map(([chainId, config]) => { - const chainName = Object.entries(testnetChainIds).find(([, id]) => id.toString() === chainId)?.[0]; + const allChainIds = { ...mainnetChainIds, ...testnetChainIds }; + const chainName = Object.entries(allChainIds).find(([, id]) => id.toString() === chainId)?.[0]; const familyName = Object.entries(chainFamilies).find(([, value]) => value === config.family)?.[0]; + if (!chainName) return null; return ` CHAIN_IDS["${chainName}"]: PublicNetwork( name="${config.name}", family=ChainFamily.${familyName}, @@ -134,7 +138,7 @@ ${Object.entries(networks.testnet).map(([chainId, config]) => { oft_eid=${config.oftEid}, hyp_domain_id=${config.hypDomainId}, ),`; -}).join('\n')} +}).filter(Boolean).join('\n')} } PUBLIC_NETWORKS: Final[Dict[int, PublicNetwork]] = { @@ -196,8 +200,9 @@ TOKEN_SYMBOLS_MAP: Final[Dict[str, TokenConfig]] = { ${Object.entries(tokens).map(([symbol, config]) => { const addressEntries = Object.entries(config.addresses).map(([chainId, address]) => { const chainName = Object.entries(allChainIds).find(([, id]) => id.toString() === chainId)?.[0]; + if (!chainName) return null; return ` CHAIN_IDS["${chainName}"]: "${address}",`; - }).join('\n'); + }).filter(Boolean).join('\n'); const l1Decimals = config.l1TokenDecimals ? `,\n l1_token_decimals=${config.l1TokenDecimals}` : '';