diff --git a/.gitignore b/.gitignore index e965055..21cbe8a 100644 --- a/.gitignore +++ b/.gitignore @@ -21,8 +21,10 @@ build/ .env.local .env.*.local -# IDE -.vscode/ +# IDE (team settings may be committed) +.vscode/* +!.vscode/settings.json +!.vscode/extensions.json .idea/ *.swp *.swo diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..88fa3bf --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "go.useLanguageServer": true, + "go.toolsEnvVars": { + "GO111MODULE": "on" + }, + "gopls": { + "build.env": { + "GO111MODULE": "on" + } + } +} diff --git a/backend/.vscode/settings.json b/backend/.vscode/settings.json new file mode 100644 index 0000000..1f1bbba --- /dev/null +++ b/backend/.vscode/settings.json @@ -0,0 +1,23 @@ +{ + "go.useLanguageServer": true, + "go.alternateTools": { + "go": "/home/intlc/sdk/go1.23.4/bin/go", + "gopls": "/home/intlc/go/bin/gopls" + }, + "go.toolsEnvVars": { + "GO111MODULE": "on", + "GOWORK": "off", + "GOROOT": "/home/intlc/sdk/go1.23.4", + "GOPATH": "/home/intlc/go", + "GOMODCACHE": "/home/intlc/go/pkg/mod" + }, + "gopls": { + "build.env": { + "GO111MODULE": "on", + "GOWORK": "off", + "GOROOT": "/home/intlc/sdk/go1.23.4", + "GOPATH": "/home/intlc/go", + "GOMODCACHE": "/home/intlc/go/pkg/mod" + } + } +} diff --git a/backend/api/rest/config/metamask/DUAL_CHAIN_NETWORKS.json b/backend/api/rest/config/metamask/DUAL_CHAIN_NETWORKS.json index ffa6b0e..a06a425 100644 --- a/backend/api/rest/config/metamask/DUAL_CHAIN_NETWORKS.json +++ b/backend/api/rest/config/metamask/DUAL_CHAIN_NETWORKS.json @@ -1,23 +1,52 @@ { "name": "MetaMask Multi-Chain Networks (13 chains)", - "version": {"major": 1, "minor": 2, "patch": 0}, + "version": {"major": 1, "minor": 2, "patch": 1}, "defaultChainId": 138, "explorerUrl": "https://explorer.d-bis.org", - "tokenListUrl": "https://explorer.d-bis.org/api/v1/report/token-list?chainId=138", + "tokenListUrl": "https://explorer.d-bis.org/api/config/token-list", "generatedBy": "DBIS Explorer", "chains": [ - {"chainId":"0x8a","chainIdDecimal":138,"chainName":"DeFi Oracle Meta Mainnet","shortName":"dbis","rpcUrls":["https://rpc-http-pub.d-bis.org","https://rpc.d-bis.org","https://rpc2.d-bis.org","https://rpc.defi-oracle.io"],"nativeCurrency":{"name":"Ether","symbol":"ETH","decimals":18},"blockExplorerUrls":["https://explorer.d-bis.org","https://blockscout.defi-oracle.io"],"iconUrls":["https://explorer.d-bis.org/token-icons/chain-138.png","https://explorer.d-bis.org/api/v1/report/logo/chain-138","https://explorer.d-bis.org/favicon.ico"],"infoURL":"https://explorer.d-bis.org","explorerApiUrl":"https://explorer.d-bis.org/api/v2","testnet":false}, - {"chainId":"0x1","chainIdDecimal":1,"chainName":"Ethereum Mainnet","shortName":"eth","rpcUrls":["https://eth.llamarpc.com","https://rpc.ankr.com/eth","https://ethereum.publicnode.com","https://1rpc.io/eth"],"nativeCurrency":{"name":"Ether","symbol":"ETH","decimals":18},"blockExplorerUrls":["https://etherscan.io"],"iconUrls":["https://raw.githubusercontent.com/ethereum/ethereum.org/main/static/images/eth-diamond-black.png"],"infoURL":"https://ethereum.org","testnet":false}, - {"chainId":"0x9f2c4","chainIdDecimal":651940,"chainName":"ALL Mainnet","shortName":"all","rpcUrls":["https://mainnet-rpc.alltra.global"],"nativeCurrency":{"name":"Ether","symbol":"ETH","decimals":18},"blockExplorerUrls":["https://alltra.global"],"iconUrls":["https://raw.githubusercontent.com/ethereum/ethereum.org/main/static/images/eth-diamond-black.png"],"infoURL":"https://alltra.global","testnet":false}, - {"chainId":"0x19","chainIdDecimal":25,"chainName":"Cronos Mainnet","rpcUrls":["https://evm.cronos.org","https://cronos-rpc.publicnode.com"],"nativeCurrency":{"name":"CRO","symbol":"CRO","decimals":18},"blockExplorerUrls":["https://cronos.org/explorer"],"iconUrls":["https://ipfs.io/ipfs/Qma3FKtLce9MjgJgWbtyCxBiPjJ6xi8jGWUSKNS5Jc2ong"]}, - {"chainId":"0x38","chainIdDecimal":56,"chainName":"BNB Smart Chain","rpcUrls":["https://bsc-dataseed.binance.org","https://bsc-dataseed1.defibit.io","https://bsc-dataseed1.ninicoin.io"],"nativeCurrency":{"name":"BNB","symbol":"BNB","decimals":18},"blockExplorerUrls":["https://bscscan.com"],"iconUrls":["https://raw.githubusercontent.com/ethereum/ethereum.org/main/static/images/eth-diamond-black.png"]}, - {"chainId":"0x64","chainIdDecimal":100,"chainName":"Gnosis Chain","rpcUrls":["https://rpc.gnosischain.com","https://gnosis-rpc.publicnode.com","https://1rpc.io/gnosis"],"nativeCurrency":{"name":"xDAI","symbol":"xDAI","decimals":18},"blockExplorerUrls":["https://gnosisscan.io"],"iconUrls":["https://raw.githubusercontent.com/ethereum/ethereum.org/main/static/images/eth-diamond-black.png"]}, - {"chainId":"0x89","chainIdDecimal":137,"chainName":"Polygon","rpcUrls":["https://polygon-rpc.com","https://polygon.llamarpc.com","https://polygon-bor-rpc.publicnode.com"],"nativeCurrency":{"name":"MATIC","symbol":"MATIC","decimals":18},"blockExplorerUrls":["https://polygonscan.com"],"iconUrls":["https://raw.githubusercontent.com/ethereum/ethereum.org/main/static/images/eth-diamond-black.png"]}, - {"chainId":"0xa","chainIdDecimal":10,"chainName":"Optimism","rpcUrls":["https://mainnet.optimism.io","https://optimism.llamarpc.com","https://optimism-rpc.publicnode.com"],"nativeCurrency":{"name":"Ether","symbol":"ETH","decimals":18},"blockExplorerUrls":["https://optimistic.etherscan.io"],"iconUrls":["https://raw.githubusercontent.com/ethereum/ethereum.org/main/static/images/eth-diamond-black.png"]}, - {"chainId":"0xa4b1","chainIdDecimal":42161,"chainName":"Arbitrum One","rpcUrls":["https://arb1.arbitrum.io/rpc","https://arbitrum.llamarpc.com","https://arbitrum-one-rpc.publicnode.com"],"nativeCurrency":{"name":"Ether","symbol":"ETH","decimals":18},"blockExplorerUrls":["https://arbiscan.io"],"iconUrls":["https://raw.githubusercontent.com/ethereum/ethereum.org/main/static/images/eth-diamond-black.png"]}, - {"chainId":"0x2105","chainIdDecimal":8453,"chainName":"Base","rpcUrls":["https://mainnet.base.org","https://base.llamarpc.com","https://base-rpc.publicnode.com"],"nativeCurrency":{"name":"Ether","symbol":"ETH","decimals":18},"blockExplorerUrls":["https://basescan.org"],"iconUrls":["https://raw.githubusercontent.com/ethereum/ethereum.org/main/static/images/eth-diamond-black.png"]}, - {"chainId":"0xa86a","chainIdDecimal":43114,"chainName":"Avalanche C-Chain","rpcUrls":["https://api.avax.network/ext/bc/C/rpc","https://avalanche-c-chain-rpc.publicnode.com","https://1rpc.io/avax/c"],"nativeCurrency":{"name":"AVAX","symbol":"AVAX","decimals":18},"blockExplorerUrls":["https://snowtrace.io"],"iconUrls":["https://raw.githubusercontent.com/ethereum/ethereum.org/main/static/images/eth-diamond-black.png"]}, - {"chainId":"0xa4ec","chainIdDecimal":42220,"chainName":"Celo","rpcUrls":["https://forno.celo.org","https://celo-mainnet-rpc.publicnode.com","https://1rpc.io/celo"],"nativeCurrency":{"name":"CELO","symbol":"CELO","decimals":18},"blockExplorerUrls":["https://celoscan.io"],"iconUrls":["https://raw.githubusercontent.com/ethereum/ethereum.org/main/static/images/eth-diamond-black.png"]}, - {"chainId":"0x457","chainIdDecimal":1111,"chainName":"Wemix","rpcUrls":["https://api.wemix.com","https://wemix-mainnet-rpc.publicnode.com"],"nativeCurrency":{"name":"WEMIX","symbol":"WEMIX","decimals":18},"blockExplorerUrls":["https://scan.wemix.com"],"iconUrls":["https://raw.githubusercontent.com/ethereum/ethereum.org/main/static/images/eth-diamond-black.png"]} + { + "chainId": "0x8a", + "chainIdDecimal": 138, + "chainName": "DeFi Oracle Meta Mainnet", + "shortName": "dbis", + "rpcUrls": ["https://rpc-http-pub.d-bis.org"], + "nativeCurrency": {"name": "Ether", "symbol": "ETH", "decimals": 18}, + "blockExplorerUrls": ["https://explorer.d-bis.org"], + "infoURL": "https://d-bis.org", + "explorerApiUrl": "https://explorer.d-bis.org/api/v2", + "testnet": false, + "iconUrls": [ + "https://explorer.d-bis.org/api/v1/report/logo/chain-138", + "https://explorer.d-bis.org/token-icons/chain-138.png", + "https://explorer.d-bis.org/favicon.ico" + ], + "oracles": [ + {"name": "ETH/USD (proxy)", "address": "0x3304b747e565a97ec8ac220b0b6a1f6ffdb837e6", "decimals": 8}, + {"name": "ETH/USD (aggregator)", "address": "0x99b3511a2d315a497c8112c1fdd8d508d4b1e506", "decimals": 8} + ] + }, + { + "chainId": "0x1", + "chainIdDecimal": 1, + "chainName": "Ethereum Mainnet", + "rpcUrls": ["https://eth.llamarpc.com", "https://rpc.ankr.com/eth", "https://ethereum.publicnode.com", "https://1rpc.io/eth"], + "nativeCurrency": {"name": "Ether", "symbol": "ETH", "decimals": 18}, + "blockExplorerUrls": ["https://etherscan.io"], + "iconUrls": ["https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2/logo.png"], + "oracles": [{"name": "ETH/USD", "address": "0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419", "decimals": 8}] + }, + {"chainId": "0x9f2c4", "chainIdDecimal": 651940, "chainName": "ALL Mainnet", "rpcUrls": ["https://mainnet-rpc.alltra.global"], "nativeCurrency": {"name": "Ether", "symbol": "ETH", "decimals": 18}, "blockExplorerUrls": ["https://alltra.global"], "iconUrls": ["https://alltra.global/favicon.ico"], "oracles": []}, + {"chainId": "0x19", "chainIdDecimal": 25, "chainName": "Cronos Mainnet", "rpcUrls": ["https://evm.cronos.org", "https://cronos-rpc.publicnode.com"], "nativeCurrency": {"name": "CRO", "symbol": "CRO", "decimals": 18}, "blockExplorerUrls": ["https://cronos.org/explorer"], "iconUrls": ["https://ipfs.io/ipfs/Qma3FKtLce9MjgJgWbtyCxBiPjJ6xi8jGWUSKNS5Jc2ong"], "oracles": []}, + {"chainId": "0x38", "chainIdDecimal": 56, "chainName": "BNB Smart Chain", "rpcUrls": ["https://bsc-dataseed.binance.org", "https://bsc-dataseed1.defibit.io", "https://bsc-dataseed1.ninicoin.io"], "nativeCurrency": {"name": "BNB", "symbol": "BNB", "decimals": 18}, "blockExplorerUrls": ["https://bscscan.com"], "iconUrls": ["https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/smartchain/info/logo.png"], "oracles": []}, + {"chainId": "0x64", "chainIdDecimal": 100, "chainName": "Gnosis Chain", "rpcUrls": ["https://rpc.gnosischain.com", "https://gnosis-rpc.publicnode.com", "https://1rpc.io/gnosis"], "nativeCurrency": {"name": "xDAI", "symbol": "xDAI", "decimals": 18}, "blockExplorerUrls": ["https://gnosisscan.io"], "iconUrls": ["https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/xdai/info/logo.png"], "oracles": []}, + {"chainId": "0x89", "chainIdDecimal": 137, "chainName": "Polygon", "rpcUrls": ["https://polygon-rpc.com", "https://polygon.llamarpc.com", "https://polygon-bor-rpc.publicnode.com"], "nativeCurrency": {"name": "MATIC", "symbol": "MATIC", "decimals": 18}, "blockExplorerUrls": ["https://polygonscan.com"], "iconUrls": ["https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/polygon/info/logo.png"], "oracles": []}, + {"chainId": "0xa", "chainIdDecimal": 10, "chainName": "Optimism", "rpcUrls": ["https://mainnet.optimism.io", "https://optimism.llamarpc.com", "https://optimism-rpc.publicnode.com"], "nativeCurrency": {"name": "Ether", "symbol": "ETH", "decimals": 18}, "blockExplorerUrls": ["https://optimistic.etherscan.io"], "iconUrls": ["https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/optimism/info/logo.png"], "oracles": []}, + {"chainId": "0xa4b1", "chainIdDecimal": 42161, "chainName": "Arbitrum One", "rpcUrls": ["https://arb1.arbitrum.io/rpc", "https://arbitrum.llamarpc.com", "https://arbitrum-one-rpc.publicnode.com"], "nativeCurrency": {"name": "Ether", "symbol": "ETH", "decimals": 18}, "blockExplorerUrls": ["https://arbiscan.io"], "iconUrls": ["https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/arbitrum/info/logo.png"], "oracles": []}, + {"chainId": "0x2105", "chainIdDecimal": 8453, "chainName": "Base", "rpcUrls": ["https://mainnet.base.org", "https://base.llamarpc.com", "https://base-rpc.publicnode.com"], "nativeCurrency": {"name": "Ether", "symbol": "ETH", "decimals": 18}, "blockExplorerUrls": ["https://basescan.org"], "iconUrls": ["https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/base/info/logo.png"], "oracles": []}, + {"chainId": "0xa86a", "chainIdDecimal": 43114, "chainName": "Avalanche C-Chain", "rpcUrls": ["https://api.avax.network/ext/bc/C/rpc", "https://avalanche-c-chain-rpc.publicnode.com", "https://1rpc.io/avax/c"], "nativeCurrency": {"name": "AVAX", "symbol": "AVAX", "decimals": 18}, "blockExplorerUrls": ["https://snowtrace.io"], "iconUrls": ["https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/avalanchec/info/logo.png"], "oracles": []}, + {"chainId": "0xa4ec", "chainIdDecimal": 42220, "chainName": "Celo", "rpcUrls": ["https://forno.celo.org", "https://celo-mainnet-rpc.publicnode.com", "https://1rpc.io/celo"], "nativeCurrency": {"name": "CELO", "symbol": "CELO", "decimals": 18}, "blockExplorerUrls": ["https://celoscan.io"], "iconUrls": ["https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/celo/info/logo.png"], "oracles": []}, + {"chainId": "0x457", "chainIdDecimal": 1111, "chainName": "Wemix", "rpcUrls": ["https://api.wemix.com", "https://wemix-mainnet-rpc.publicnode.com"], "nativeCurrency": {"name": "WEMIX", "symbol": "WEMIX", "decimals": 18}, "blockExplorerUrls": ["https://scan.wemix.com"], "iconUrls": ["https://scan.wemix.com/favicon.ico"], "oracles": []} ] } diff --git a/backend/api/rest/stats.go b/backend/api/rest/stats.go index c26b787..69a20dc 100644 --- a/backend/api/rest/stats.go +++ b/backend/api/rest/stats.go @@ -23,6 +23,8 @@ type explorerStats struct { GasPrices *explorerGasPrices `json:"gas_prices,omitempty"` NetworkUtilizationPercentage *float64 `json:"network_utilization_percentage,omitempty"` TransactionsToday *int64 `json:"transactions_today,omitempty"` + CoinPrice *string `json:"coin_price,omitempty"` + CoinImage *string `json:"coin_image,omitempty"` Freshness freshness.Snapshot `json:"freshness"` Completeness freshness.SummaryCompleteness `json:"completeness"` Sampling freshness.Sampling `json:"sampling"` @@ -268,6 +270,8 @@ func (s *Server) handleStats(w http.ResponseWriter, r *http.Request) { } } + enrichNativeCoinMarket(ctx, &stats) + w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(stats) } diff --git a/backend/api/rest/stats_coin_price.go b/backend/api/rest/stats_coin_price.go new file mode 100644 index 0000000..e50e3fa --- /dev/null +++ b/backend/api/rest/stats_coin_price.go @@ -0,0 +1,150 @@ +package rest + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "os" + "strings" + "time" +) + +const ( + chain138WETHAddress = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" +) + +type blockscoutCoinStats struct { + CoinPrice *string `json:"coin_price"` + CoinImage *string `json:"coin_image"` +} + +type tokenAggregationTokenResponse struct { + Token struct { + Market struct { + PriceUsd *float64 `json:"priceUsd"` + } `json:"market"` + } `json:"token"` +} + +func enrichNativeCoinMarket(ctx context.Context, stats *explorerStats) { + if stats.CoinPrice != nil && strings.TrimSpace(*stats.CoinPrice) != "" { + return + } + + // Prefer on-chain token-aggregation WETH/ETH oracle over Blockscout CoinGecko on Chain 138. + if price := fetchTokenAggregationEthUsd(ctx); price != "" { + stats.CoinPrice = &price + if image := fetchBlockscoutCoinImage(ctx); image != "" { + stats.CoinImage = &image + } + return + } + + bsURL := strings.TrimSpace(os.Getenv("BLOCKSCOUT_STATS_URL")) + if bsURL == "" { + bsURL = "http://127.0.0.1:4000/api/v2/stats" + } + if price, image := fetchBlockscoutCoinMarket(ctx, bsURL); price != "" { + stats.CoinPrice = &price + if image != "" { + stats.CoinImage = &image + } + } +} + +func fetchBlockscoutCoinImage(ctx context.Context) string { + bsURL := strings.TrimSpace(os.Getenv("BLOCKSCOUT_STATS_URL")) + if bsURL == "" { + bsURL = "http://127.0.0.1:4000/api/v2/stats" + } + _, image := fetchBlockscoutCoinMarket(ctx, bsURL) + return image +} + +func fetchBlockscoutCoinMarket(ctx context.Context, url string) (price string, image string) { + req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) + if err != nil { + return "", "" + } + + client := &http.Client{Timeout: 4 * time.Second} + resp, err := client.Do(req) + if err != nil { + return "", "" + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + return "", "" + } + + body, err := io.ReadAll(io.LimitReader(resp.Body, 1<<20)) + if err != nil { + return "", "" + } + + var payload blockscoutCoinStats + if err := json.Unmarshal(body, &payload); err != nil { + return "", "" + } + if payload.CoinPrice != nil { + price = strings.TrimSpace(*payload.CoinPrice) + } + if payload.CoinImage != nil { + image = strings.TrimSpace(*payload.CoinImage) + } + return price, image +} + +func tokenAggregationAPIV1Base() string { + base := strings.TrimRight(strings.TrimSpace(firstNonEmptyEnv( + "TOKEN_AGGREGATION_API_BASE", + "TOKEN_AGGREGATION_URL", + "TOKEN_AGGREGATION_BASE_URL", + )), "/") + if base == "" { + return "http://127.0.0.1:3001/api/v1" + } + if strings.HasSuffix(base, "/api/v1") { + return base + } + return base + "/api/v1" +} + +func fetchTokenAggregationEthUsd(ctx context.Context) string { + url := fmt.Sprintf("%s/tokens/%s?chainId=138", tokenAggregationAPIV1Base(), chain138WETHAddress) + + req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) + if err != nil { + return "" + } + + client := &http.Client{Timeout: 5 * time.Second} + resp, err := client.Do(req) + if err != nil { + return "" + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + return "" + } + + body, err := io.ReadAll(io.LimitReader(resp.Body, 1<<20)) + if err != nil { + return "" + } + + var payload tokenAggregationTokenResponse + if err := json.Unmarshal(body, &payload); err != nil { + return "" + } + if payload.Token.Market.PriceUsd == nil || *payload.Token.Market.PriceUsd <= 0 { + return "" + } + return formatUsdPrice(*payload.Token.Market.PriceUsd) +} + +func formatUsdPrice(value float64) string { + return fmt.Sprintf("%.2f", value) +} diff --git a/backend/api/rest/stats_coin_price_test.go b/backend/api/rest/stats_coin_price_test.go new file mode 100644 index 0000000..86ba553 --- /dev/null +++ b/backend/api/rest/stats_coin_price_test.go @@ -0,0 +1,133 @@ +package rest + +import ( + "context" + "encoding/json" + "net/http" + "net/http/httptest" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestEnrichNativeCoinMarketFromBlockscout(t *testing.T) { + tokenAgg := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusNotFound) + })) + defer tokenAgg.Close() + t.Setenv("TOKEN_AGGREGATION_BASE_URL", tokenAgg.URL) + + blockscout := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + require.NoError(t, json.NewEncoder(w).Encode(map[string]any{ + "coin_price": "1701.77", + "coin_image": "https://example.com/eth.png", + })) + })) + defer blockscout.Close() + + t.Setenv("BLOCKSCOUT_STATS_URL", blockscout.URL) + stats := explorerStats{} + enrichNativeCoinMarket(context.Background(), &stats) + + require.NotNil(t, stats.CoinPrice) + require.Equal(t, "1701.77", *stats.CoinPrice) + require.NotNil(t, stats.CoinImage) + require.Equal(t, "https://example.com/eth.png", *stats.CoinImage) +} + +func TestEnrichNativeCoinMarketFallsBackToTokenAggregation(t *testing.T) { + blockscout := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + require.NoError(t, json.NewEncoder(w).Encode(map[string]any{ + "coin_price": nil, + })) + })) + defer blockscout.Close() + + tokenAgg := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + require.Contains(t, r.URL.Path, chain138WETHAddress) + w.Header().Set("Content-Type", "application/json") + require.NoError(t, json.NewEncoder(w).Encode(map[string]any{ + "token": map[string]any{ + "market": map[string]any{ + "priceUsd": 1678.67, + }, + }, + })) + })) + defer tokenAgg.Close() + + t.Setenv("BLOCKSCOUT_STATS_URL", blockscout.URL) + t.Setenv("TOKEN_AGGREGATION_BASE_URL", tokenAgg.URL) + stats := explorerStats{} + enrichNativeCoinMarket(context.Background(), &stats) + + require.NotNil(t, stats.CoinPrice) + require.Equal(t, "1678.67", *stats.CoinPrice) +} + +func TestEnrichNativeCoinMarketPrefersTokenAggregationWithHostOnlyBaseURL(t *testing.T) { + blockscout := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + require.NoError(t, json.NewEncoder(w).Encode(map[string]any{ + "coin_price": "1740.00", + })) + })) + defer blockscout.Close() + + tokenAgg := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + require.Equal(t, "/api/v1/tokens/"+chain138WETHAddress, r.URL.Path) + w.Header().Set("Content-Type", "application/json") + require.NoError(t, json.NewEncoder(w).Encode(map[string]any{ + "token": map[string]any{ + "market": map[string]any{ + "priceUsd": 1732.18, + }, + }, + })) + })) + defer tokenAgg.Close() + + t.Setenv("BLOCKSCOUT_STATS_URL", blockscout.URL) + t.Setenv("TOKEN_AGGREGATION_BASE_URL", tokenAgg.URL) + stats := explorerStats{} + enrichNativeCoinMarket(context.Background(), &stats) + + require.NotNil(t, stats.CoinPrice) + require.Equal(t, "1732.18", *stats.CoinPrice) +} + +func TestEnrichNativeCoinMarketPrefersTokenAggregationOverBlockscout(t *testing.T) { + blockscout := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + require.NoError(t, json.NewEncoder(w).Encode(map[string]any{ + "coin_price": "1740.00", + "coin_image": "https://example.com/eth.png", + })) + })) + defer blockscout.Close() + + tokenAgg := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + require.Contains(t, r.URL.Path, chain138WETHAddress) + w.Header().Set("Content-Type", "application/json") + require.NoError(t, json.NewEncoder(w).Encode(map[string]any{ + "token": map[string]any{ + "market": map[string]any{ + "priceUsd": 1732.18, + }, + }, + })) + })) + defer tokenAgg.Close() + + t.Setenv("BLOCKSCOUT_STATS_URL", blockscout.URL) + t.Setenv("TOKEN_AGGREGATION_BASE_URL", tokenAgg.URL) + stats := explorerStats{} + enrichNativeCoinMarket(context.Background(), &stats) + + require.NotNil(t, stats.CoinPrice) + require.Equal(t, "1732.18", *stats.CoinPrice) + require.NotNil(t, stats.CoinImage) + require.Equal(t, "https://example.com/eth.png", *stats.CoinImage) +} diff --git a/backend/config/metamask/DUAL_CHAIN_NETWORKS.json b/backend/config/metamask/DUAL_CHAIN_NETWORKS.json index f8dc9b0..a06a425 100644 --- a/backend/config/metamask/DUAL_CHAIN_NETWORKS.json +++ b/backend/config/metamask/DUAL_CHAIN_NETWORKS.json @@ -1,95 +1,52 @@ { - "name": "MetaMask Multi-Chain Networks (Chain 138 + Ethereum + ALL Mainnet + Cronos)", - "version": { - "major": 1, - "minor": 1, - "patch": 0 - }, + "name": "MetaMask Multi-Chain Networks (13 chains)", + "version": {"major": 1, "minor": 2, "patch": 1}, + "defaultChainId": 138, + "explorerUrl": "https://explorer.d-bis.org", + "tokenListUrl": "https://explorer.d-bis.org/api/config/token-list", + "generatedBy": "DBIS Explorer", "chains": [ { "chainId": "0x8a", "chainIdDecimal": 138, "chainName": "DeFi Oracle Meta Mainnet", - "rpcUrls": [ - "https://rpc-http-pub.d-bis.org", - "https://rpc.d-bis.org", - "https://rpc2.d-bis.org", - "https://rpc.defi-oracle.io" - ], - "nativeCurrency": { - "name": "Ether", - "symbol": "ETH", - "decimals": 18 - }, - "blockExplorerUrls": [ - "https://explorer.d-bis.org" - ], + "shortName": "dbis", + "rpcUrls": ["https://rpc-http-pub.d-bis.org"], + "nativeCurrency": {"name": "Ether", "symbol": "ETH", "decimals": 18}, + "blockExplorerUrls": ["https://explorer.d-bis.org"], + "infoURL": "https://d-bis.org", + "explorerApiUrl": "https://explorer.d-bis.org/api/v2", + "testnet": false, "iconUrls": [ - "https://explorer.d-bis.org/token-icons/chain-138.png", "https://explorer.d-bis.org/api/v1/report/logo/chain-138", + "https://explorer.d-bis.org/token-icons/chain-138.png", "https://explorer.d-bis.org/favicon.ico" + ], + "oracles": [ + {"name": "ETH/USD (proxy)", "address": "0x3304b747e565a97ec8ac220b0b6a1f6ffdb837e6", "decimals": 8}, + {"name": "ETH/USD (aggregator)", "address": "0x99b3511a2d315a497c8112c1fdd8d508d4b1e506", "decimals": 8} ] }, { "chainId": "0x1", "chainIdDecimal": 1, "chainName": "Ethereum Mainnet", - "rpcUrls": [ - "https://eth.llamarpc.com", - "https://rpc.ankr.com/eth", - "https://ethereum.publicnode.com", - "https://1rpc.io/eth" - ], - "nativeCurrency": { - "name": "Ether", - "symbol": "ETH", - "decimals": 18 - }, - "blockExplorerUrls": [ - "https://etherscan.io" - ], - "iconUrls": [ - "https://raw.githubusercontent.com/ethereum/ethereum.org/main/static/images/eth-diamond-black.png" - ] + "rpcUrls": ["https://eth.llamarpc.com", "https://rpc.ankr.com/eth", "https://ethereum.publicnode.com", "https://1rpc.io/eth"], + "nativeCurrency": {"name": "Ether", "symbol": "ETH", "decimals": 18}, + "blockExplorerUrls": ["https://etherscan.io"], + "iconUrls": ["https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2/logo.png"], + "oracles": [{"name": "ETH/USD", "address": "0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419", "decimals": 8}] }, - { - "chainId": "0x9f2c4", - "chainIdDecimal": 651940, - "chainName": "ALL Mainnet", - "rpcUrls": [ - "https://mainnet-rpc.alltra.global" - ], - "nativeCurrency": { - "name": "Ether", - "symbol": "ETH", - "decimals": 18 - }, - "blockExplorerUrls": [ - "https://alltra.global" - ], - "iconUrls": [ - "https://raw.githubusercontent.com/ethereum/ethereum.org/main/static/images/eth-diamond-black.png" - ] - }, - { - "chainId": "0x19", - "chainIdDecimal": 25, - "chainName": "Cronos Mainnet", - "rpcUrls": [ - "https://evm.cronos.org", - "https://cronos-rpc.publicnode.com" - ], - "nativeCurrency": { - "name": "CRO", - "symbol": "CRO", - "decimals": 18 - }, - "blockExplorerUrls": [ - "https://cronos.org/explorer" - ], - "iconUrls": [ - "https://ipfs.io/ipfs/Qma3FKtLce9MjgJgWbtyCxBiPjJ6xi8jGWUSKNS5Jc2ong" - ] - } + {"chainId": "0x9f2c4", "chainIdDecimal": 651940, "chainName": "ALL Mainnet", "rpcUrls": ["https://mainnet-rpc.alltra.global"], "nativeCurrency": {"name": "Ether", "symbol": "ETH", "decimals": 18}, "blockExplorerUrls": ["https://alltra.global"], "iconUrls": ["https://alltra.global/favicon.ico"], "oracles": []}, + {"chainId": "0x19", "chainIdDecimal": 25, "chainName": "Cronos Mainnet", "rpcUrls": ["https://evm.cronos.org", "https://cronos-rpc.publicnode.com"], "nativeCurrency": {"name": "CRO", "symbol": "CRO", "decimals": 18}, "blockExplorerUrls": ["https://cronos.org/explorer"], "iconUrls": ["https://ipfs.io/ipfs/Qma3FKtLce9MjgJgWbtyCxBiPjJ6xi8jGWUSKNS5Jc2ong"], "oracles": []}, + {"chainId": "0x38", "chainIdDecimal": 56, "chainName": "BNB Smart Chain", "rpcUrls": ["https://bsc-dataseed.binance.org", "https://bsc-dataseed1.defibit.io", "https://bsc-dataseed1.ninicoin.io"], "nativeCurrency": {"name": "BNB", "symbol": "BNB", "decimals": 18}, "blockExplorerUrls": ["https://bscscan.com"], "iconUrls": ["https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/smartchain/info/logo.png"], "oracles": []}, + {"chainId": "0x64", "chainIdDecimal": 100, "chainName": "Gnosis Chain", "rpcUrls": ["https://rpc.gnosischain.com", "https://gnosis-rpc.publicnode.com", "https://1rpc.io/gnosis"], "nativeCurrency": {"name": "xDAI", "symbol": "xDAI", "decimals": 18}, "blockExplorerUrls": ["https://gnosisscan.io"], "iconUrls": ["https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/xdai/info/logo.png"], "oracles": []}, + {"chainId": "0x89", "chainIdDecimal": 137, "chainName": "Polygon", "rpcUrls": ["https://polygon-rpc.com", "https://polygon.llamarpc.com", "https://polygon-bor-rpc.publicnode.com"], "nativeCurrency": {"name": "MATIC", "symbol": "MATIC", "decimals": 18}, "blockExplorerUrls": ["https://polygonscan.com"], "iconUrls": ["https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/polygon/info/logo.png"], "oracles": []}, + {"chainId": "0xa", "chainIdDecimal": 10, "chainName": "Optimism", "rpcUrls": ["https://mainnet.optimism.io", "https://optimism.llamarpc.com", "https://optimism-rpc.publicnode.com"], "nativeCurrency": {"name": "Ether", "symbol": "ETH", "decimals": 18}, "blockExplorerUrls": ["https://optimistic.etherscan.io"], "iconUrls": ["https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/optimism/info/logo.png"], "oracles": []}, + {"chainId": "0xa4b1", "chainIdDecimal": 42161, "chainName": "Arbitrum One", "rpcUrls": ["https://arb1.arbitrum.io/rpc", "https://arbitrum.llamarpc.com", "https://arbitrum-one-rpc.publicnode.com"], "nativeCurrency": {"name": "Ether", "symbol": "ETH", "decimals": 18}, "blockExplorerUrls": ["https://arbiscan.io"], "iconUrls": ["https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/arbitrum/info/logo.png"], "oracles": []}, + {"chainId": "0x2105", "chainIdDecimal": 8453, "chainName": "Base", "rpcUrls": ["https://mainnet.base.org", "https://base.llamarpc.com", "https://base-rpc.publicnode.com"], "nativeCurrency": {"name": "Ether", "symbol": "ETH", "decimals": 18}, "blockExplorerUrls": ["https://basescan.org"], "iconUrls": ["https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/base/info/logo.png"], "oracles": []}, + {"chainId": "0xa86a", "chainIdDecimal": 43114, "chainName": "Avalanche C-Chain", "rpcUrls": ["https://api.avax.network/ext/bc/C/rpc", "https://avalanche-c-chain-rpc.publicnode.com", "https://1rpc.io/avax/c"], "nativeCurrency": {"name": "AVAX", "symbol": "AVAX", "decimals": 18}, "blockExplorerUrls": ["https://snowtrace.io"], "iconUrls": ["https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/avalanchec/info/logo.png"], "oracles": []}, + {"chainId": "0xa4ec", "chainIdDecimal": 42220, "chainName": "Celo", "rpcUrls": ["https://forno.celo.org", "https://celo-mainnet-rpc.publicnode.com", "https://1rpc.io/celo"], "nativeCurrency": {"name": "CELO", "symbol": "CELO", "decimals": 18}, "blockExplorerUrls": ["https://celoscan.io"], "iconUrls": ["https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/celo/info/logo.png"], "oracles": []}, + {"chainId": "0x457", "chainIdDecimal": 1111, "chainName": "Wemix", "rpcUrls": ["https://api.wemix.com", "https://wemix-mainnet-rpc.publicnode.com"], "nativeCurrency": {"name": "WEMIX", "symbol": "WEMIX", "decimals": 18}, "blockExplorerUrls": ["https://scan.wemix.com"], "iconUrls": ["https://scan.wemix.com/favicon.ico"], "oracles": []} ] } diff --git a/backend/config/metamask/DUAL_CHAIN_TOKEN_LIST.tokenlist.json b/backend/config/metamask/DUAL_CHAIN_TOKEN_LIST.tokenlist.json index cd440dc..48e71cb 100644 --- a/backend/config/metamask/DUAL_CHAIN_TOKEN_LIST.tokenlist.json +++ b/backend/config/metamask/DUAL_CHAIN_TOKEN_LIST.tokenlist.json @@ -3,9 +3,9 @@ "version": { "major": 1, "minor": 3, - "patch": 5 + "patch": 4 }, - "timestamp": "2026-06-02T15:13:02.229Z", + "timestamp": "2026-04-04T04:23:46.263Z", "logoURI": "https://raw.githubusercontent.com/Order-of-Hospitallers/proxmox-cp/main/token-lists/logos/gru/chain138-list.svg", "keywords": [ "chain138", @@ -1552,6 +1552,287 @@ "wrapped" ] }, + { + "chainId": 138, + "address": "0xD51482e567c03899eecE3CAe8a058161FD56069D", + "name": "AUD Cash Electronic Money (Compliant)", + "symbol": "cAUDC", + "decimals": 6, + "logoURI": "https://raw.githubusercontent.com/Order-of-Hospitallers/proxmox-cp/main/token-lists/logos/gru/cAUDC.svg", + "tags": [ + "gru", + "compliant", + "electronic-money" + ] + }, + { + "chainId": 138, + "address": "0x54dBd40cF05e15906A2C21f600937e96787f5679", + "name": "CAD Cash Electronic Money (Compliant)", + "symbol": "cCADC", + "decimals": 6, + "logoURI": "https://raw.githubusercontent.com/Order-of-Hospitallers/proxmox-cp/main/token-lists/logos/gru/cCADC.svg", + "tags": [ + "gru", + "compliant", + "electronic-money" + ] + }, + { + "chainId": 138, + "address": "0x873990849DDa5117d7C644f0aF24370797C03885", + "name": "CHF Cash Electronic Money (Compliant)", + "symbol": "cCHFC", + "decimals": 6, + "logoURI": "https://raw.githubusercontent.com/Order-of-Hospitallers/proxmox-cp/main/token-lists/logos/gru/cCHFC.svg", + "tags": [ + "gru", + "compliant", + "electronic-money" + ] + }, + { + "chainId": 138, + "address": "0x8085961F9cF02b4d800A3c6d386D31da4B34266a", + "name": "EUR Cash Electronic Money (Compliant)", + "symbol": "cEURC", + "decimals": 6, + "logoURI": "https://raw.githubusercontent.com/Order-of-Hospitallers/proxmox-cp/main/token-lists/logos/gru/cEURC.svg", + "tags": [ + "gru", + "compliant", + "electronic-money" + ] + }, + { + "chainId": 138, + "address": "0xdf4b71c61E5912712C1Bdd451416B9aC26949d72", + "name": "EUR Treasury / Government Bond (Compliant)", + "symbol": "cEURT", + "decimals": 6, + "logoURI": "https://raw.githubusercontent.com/Order-of-Hospitallers/proxmox-cp/main/token-lists/logos/gru/cEURT.svg", + "tags": [ + "gru", + "compliant", + "treasury-bond" + ] + }, + { + "chainId": 138, + "address": "0x003960f16D9d34F2e98d62723B6721Fb92074aD2", + "name": "GBP Cash Electronic Money (Compliant)", + "symbol": "cGBPC", + "decimals": 6, + "logoURI": "https://raw.githubusercontent.com/Order-of-Hospitallers/proxmox-cp/main/token-lists/logos/gru/cGBPC.svg", + "tags": [ + "gru", + "compliant", + "electronic-money" + ] + }, + { + "chainId": 138, + "address": "0x350f54e4D23795f86A9c03988c7135357CCaD97c", + "name": "GBP Treasury / Government Bond (Compliant)", + "symbol": "cGBPT", + "decimals": 6, + "logoURI": "https://raw.githubusercontent.com/Order-of-Hospitallers/proxmox-cp/main/token-lists/logos/gru/cGBPT.svg", + "tags": [ + "gru", + "compliant", + "treasury-bond" + ] + }, + { + "chainId": 138, + "address": "0xEe269e1226a334182aace90056EE4ee5Cc8A6770", + "name": "JPY Cash Electronic Money (Compliant)", + "symbol": "cJPYC", + "decimals": 6, + "logoURI": "https://raw.githubusercontent.com/Order-of-Hospitallers/proxmox-cp/main/token-lists/logos/gru/cJPYC.svg", + "tags": [ + "gru", + "compliant", + "electronic-money" + ] + }, + { + "chainId": 138, + "address": "0xf22258f57794CC8E06237084b353Ab30fFfa640b", + "name": "USD Cash Electronic Money (Compliant)", + "symbol": "cUSDC", + "decimals": 6, + "logoURI": "https://explorer.d-bis.org/token-icons/cUSDC.png", + "tags": [ + "gru", + "compliant", + "electronic-money", + "fiat", + "cash" + ], + "extensions": { + "assetClass": "Cash & Equivalents", + "assetGroup": "MMF / Repo", + "instrumentType": "eMoney", + "underlying": "USD", + "gruLayer": "M1", + "rwaEligible": false, + "category": "gru-emoney", + "currency": "USD", + "settlement": "fiat", + "cashLike": true, + "backing": "cash,cash-equivalents" + } + }, + { + "chainId": 138, + "address": "0x93E66202A11B1772E55407B32B44e5Cd8eda7f22", + "name": "USD Treasury / Government Bond (Compliant)", + "symbol": "cUSDT", + "decimals": 6, + "logoURI": "https://explorer.d-bis.org/token-icons/cUSDT.png", + "tags": [ + "gru", + "compliant", + "treasury-bond", + "fiat", + "cash" + ], + "extensions": { + "assetClass": "Cash & Equivalents", + "assetGroup": "MMF / Repo", + "instrumentType": "eMoney", + "underlying": "USD", + "gruLayer": "M1", + "rwaEligible": false, + "category": "gru-emoney", + "currency": "USD", + "settlement": "fiat", + "cashLike": true, + "backing": "cash,cash-equivalents" + } + }, + { + "chainId": 138, + "address": "0x290E52a8819A4fbD0714E517225429aA2B70EC6b", + "name": "XAU Commodity (Compliant)", + "symbol": "cXAUC", + "decimals": 6, + "logoURI": "https://explorer.d-bis.org/token-icons/cXAUC.png", + "tags": [ + "gru", + "compliant" + ], + "extensions": { + "unitOfAccount": "troy_ounce", + "unitDescription": "1 full token (10^decimals base units) = 1 troy oz fine gold", + "assetClass": "Commodities", + "assetGroup": "Precious Metals", + "instrumentType": "eMoney", + "underlying": "Gold", + "gruLayer": "M1", + "rwaEligible": false, + "category": "gru-emoney", + "cashLike": false + } + }, + { + "chainId": 138, + "address": "0x94e408E26c6FD8F4ee00b54dF19082FDA07dC96E", + "name": "XAU Commodity (Compliant)", + "symbol": "cXAUT", + "decimals": 6, + "logoURI": "https://explorer.d-bis.org/token-icons/cXAUT.png", + "tags": [ + "gru", + "compliant" + ], + "extensions": { + "unitOfAccount": "troy_ounce", + "unitDescription": "1 full token (10^decimals base units) = 1 troy oz fine gold", + "assetClass": "Commodities", + "assetGroup": "Precious Metals", + "instrumentType": "eMoney", + "underlying": "Gold", + "gruLayer": "M1", + "rwaEligible": false, + "category": "gru-emoney", + "cashLike": false + } + }, + { + "chainId": 138, + "address": "0x3304b747e565a97ec8ac220b0b6a1f6ffdb837e6", + "name": "ETH/USD Price Feed", + "symbol": "ETH-USD", + "decimals": 8, + "logoURI": "https://ipfs.io/ipfs/QmPZuycjyJEe2otREuQ5HirvPJ8X6Yc6MBtwz1VhdD79pY", + "tags": [ + "oracle", + "price-feed" + ] + }, + { + "chainId": 138, + "address": "0xb7721dD53A8c629d9f1Ba31a5819AFe250002b03", + "name": "Chainlink Token", + "symbol": "LINK", + "decimals": 18, + "logoURI": "https://ipfs.io/ipfs/QmenWcmfNGfssz4HXvrRV912eZDiKqLTt6z2brRYuTGz9A", + "tags": [ + "defi", + "oracle", + "ccip" + ] + }, + { + "chainId": 138, + "address": "0x71D6687F38b93CCad569Fa6352c876eea967201b", + "name": "USD Coin (Official Mirror)", + "symbol": "USDC", + "decimals": 6, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48/logo.png", + "tags": [ + "reference-asset", + "defi" + ] + }, + { + "chainId": 138, + "address": "0x004b63A7B5b0E06f6bB6adb4a5F9f590BF3182D1", + "name": "Tether USD (Official Mirror)", + "symbol": "USDT", + "decimals": 6, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xdAC17F958D2ee523a2206206994597C13D831ec7/logo.png", + "tags": [ + "reference-asset", + "defi" + ] + }, + { + "chainId": 138, + "address": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", + "name": "Wrapped Ether", + "symbol": "WETH", + "decimals": 18, + "logoURI": "https://ipfs.io/ipfs/Qma3FKtLce9MjgJgWbtyCxBiPjJ6xi8jGWUSKNS5Jc2ong", + "tags": [ + "defi", + "wrapped" + ] + }, + { + "chainId": 138, + "address": "0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9F", + "name": "Wrapped Ether v10", + "symbol": "WETH10", + "decimals": 18, + "logoURI": "https://ipfs.io/ipfs/QmanDFPHxnbKd6SSNzzXHf9GbpL9dLXSphxDZSPPYE6ds4", + "tags": [ + "defi", + "wrapped" + ] + }, { "chainId": 1111, "address": "0xE3F5a90F9cb311505cd691a46596599aA1A0AD7D", @@ -2359,542 +2640,6 @@ "defi", "bridge" ] - }, - { - "chainId": 138, - "address": "0xD51482e567c03899eecE3CAe8a058161FD56069D", - "name": "Australian Dollar (Compliant)", - "symbol": "cAUDC", - "decimals": 6, - "logoURI": "https://ipfs.io/ipfs/Qma3FKtLce9MjgJgWbtyCxBiPjJ6xi8jGWUSKNS5Jc2ong", - "tags": [ - "stablecoin", - "defi", - "compliant", - "fiat", - "cash", - "gru" - ], - "extensions": { - "category": "tokenized-fiat", - "instrument": "emoney-or-fiat-backed-stablecoin", - "currency": "AUD", - "settlement": "fiat", - "cashLike": true, - "backing": "cash,cash-equivalents", - "gruVersion": "v1", - "gruFamily": "cAUDC", - "x402Ready": false, - "fwdCanon": false - } - }, - { - "chainId": 138, - "address": "0x54dBd40cF05e15906A2C21f600937e96787f5679", - "name": "Canadian Dollar (Compliant)", - "symbol": "cCADC", - "decimals": 6, - "logoURI": "https://ipfs.io/ipfs/Qma3FKtLce9MjgJgWbtyCxBiPjJ6xi8jGWUSKNS5Jc2ong", - "tags": [ - "stablecoin", - "defi", - "compliant", - "fiat", - "cash", - "gru" - ], - "extensions": { - "category": "tokenized-fiat", - "instrument": "emoney-or-fiat-backed-stablecoin", - "currency": "CAD", - "settlement": "fiat", - "cashLike": true, - "backing": "cash,cash-equivalents", - "gruVersion": "v1", - "gruFamily": "cCADC", - "x402Ready": false, - "fwdCanon": false - } - }, - { - "chainId": 138, - "address": "0x873990849DDa5117d7C644f0aF24370797C03885", - "name": "Swiss Franc (Compliant)", - "symbol": "cCHFC", - "decimals": 6, - "logoURI": "https://ipfs.io/ipfs/Qma3FKtLce9MjgJgWbtyCxBiPjJ6xi8jGWUSKNS5Jc2ong", - "tags": [ - "stablecoin", - "defi", - "compliant", - "fiat", - "cash", - "gru" - ], - "extensions": { - "category": "tokenized-fiat", - "instrument": "emoney-or-fiat-backed-stablecoin", - "currency": "CHF", - "settlement": "fiat", - "cashLike": true, - "backing": "cash,cash-equivalents", - "gruVersion": "v1", - "gruFamily": "cCHFC", - "x402Ready": false, - "fwdCanon": false - } - }, - { - "chainId": 138, - "address": "0x8085961F9cF02b4d800A3c6d386D31da4B34266a", - "name": "Euro Coin (Compliant)", - "symbol": "cEURC", - "decimals": 6, - "logoURI": "https://ipfs.io/ipfs/Qma3FKtLce9MjgJgWbtyCxBiPjJ6xi8jGWUSKNS5Jc2ong", - "tags": [ - "stablecoin", - "defi", - "compliant", - "fiat", - "cash", - "gru" - ], - "extensions": { - "category": "tokenized-fiat", - "instrument": "emoney-or-fiat-backed-stablecoin", - "currency": "EUR", - "settlement": "fiat", - "cashLike": true, - "backing": "cash,cash-equivalents", - "gruVersion": "v1", - "gruFamily": "cEURC", - "x402Ready": false, - "fwdCanon": false - } - }, - { - "chainId": 138, - "address": "0xdf4b71c61E5912712C1Bdd451416B9aC26949d72", - "name": "Tether EUR (Compliant)", - "symbol": "cEURT", - "decimals": 6, - "logoURI": "https://ipfs.io/ipfs/Qma3FKtLce9MjgJgWbtyCxBiPjJ6xi8jGWUSKNS5Jc2ong", - "tags": [ - "stablecoin", - "defi", - "compliant", - "fiat", - "cash", - "gru" - ], - "extensions": { - "category": "tokenized-fiat", - "instrument": "emoney-or-fiat-backed-stablecoin", - "currency": "EUR", - "settlement": "fiat", - "cashLike": true, - "backing": "cash,cash-equivalents", - "gruVersion": "v1", - "gruFamily": "cEURT", - "x402Ready": false, - "fwdCanon": false - } - }, - { - "chainId": 138, - "address": "0x003960f16D9d34F2e98d62723B6721Fb92074aD2", - "name": "Pound Sterling (Compliant)", - "symbol": "cGBPC", - "decimals": 6, - "logoURI": "https://ipfs.io/ipfs/Qma3FKtLce9MjgJgWbtyCxBiPjJ6xi8jGWUSKNS5Jc2ong", - "tags": [ - "stablecoin", - "defi", - "compliant", - "fiat", - "cash", - "gru" - ], - "extensions": { - "category": "tokenized-fiat", - "instrument": "emoney-or-fiat-backed-stablecoin", - "currency": "GBP", - "settlement": "fiat", - "cashLike": true, - "backing": "cash,cash-equivalents", - "gruVersion": "v1", - "gruFamily": "cGBPC", - "x402Ready": false, - "fwdCanon": false - } - }, - { - "chainId": 138, - "address": "0x350f54e4D23795f86A9c03988c7135357CCaD97c", - "name": "Tether GBP (Compliant)", - "symbol": "cGBPT", - "decimals": 6, - "logoURI": "https://ipfs.io/ipfs/Qma3FKtLce9MjgJgWbtyCxBiPjJ6xi8jGWUSKNS5Jc2ong", - "tags": [ - "stablecoin", - "defi", - "compliant", - "fiat", - "cash", - "gru" - ], - "extensions": { - "category": "tokenized-fiat", - "instrument": "emoney-or-fiat-backed-stablecoin", - "currency": "GBP", - "settlement": "fiat", - "cashLike": true, - "backing": "cash,cash-equivalents", - "gruVersion": "v1", - "gruFamily": "cGBPT", - "x402Ready": false, - "fwdCanon": false - } - }, - { - "chainId": 138, - "address": "0xEe269e1226a334182aace90056EE4ee5Cc8A6770", - "name": "Japanese Yen (Compliant)", - "symbol": "cJPYC", - "decimals": 6, - "logoURI": "https://ipfs.io/ipfs/Qma3FKtLce9MjgJgWbtyCxBiPjJ6xi8jGWUSKNS5Jc2ong", - "tags": [ - "stablecoin", - "defi", - "compliant", - "fiat", - "cash", - "gru" - ], - "extensions": { - "category": "tokenized-fiat", - "instrument": "emoney-or-fiat-backed-stablecoin", - "currency": "JPY", - "settlement": "fiat", - "cashLike": true, - "backing": "cash,cash-equivalents", - "gruVersion": "v1", - "gruFamily": "cJPYC", - "x402Ready": false, - "fwdCanon": false - } - }, - { - "chainId": 138, - "address": "0xf22258f57794CC8E06237084b353Ab30fFfa640b", - "name": "Compliant USD Coin", - "symbol": "cUSDC", - "decimals": 6, - "logoURI": "https://ipfs.io/ipfs/QmNPq4D5JXzurmi9jAhogVMzhAQRk1PZ1r9H3qQUV9gjDm", - "tags": [ - "stablecoin", - "defi", - "compliant", - "fiat", - "cash", - "gru" - ], - "extensions": { - "category": "gru-emoney", - "instrument": "emoney-or-fiat-backed-stablecoin", - "currency": "USD", - "settlement": "fiat", - "cashLike": true, - "backing": "cash,cash-equivalents", - "gruVersion": "v1", - "gruFamily": "cUSDC", - "x402Ready": false, - "fwdCanon": false, - "assetClass": "Cash & Equivalents", - "assetGroup": "MMF / Repo", - "instrumentType": "eMoney", - "underlying": "USD", - "gruLayer": "M1", - "rwaEligible": false - } - }, - { - "chainId": 138, - "address": "0x93E66202A11B1772E55407B32B44e5Cd8eda7f22", - "name": "Compliant Tether USD", - "symbol": "cUSDT", - "decimals": 6, - "logoURI": "https://ipfs.io/ipfs/QmRfhPs9DcyFPpGjKwF6CCoVDWUHSxkQR34n9NK7JSbPCP", - "tags": [ - "stablecoin", - "defi", - "compliant", - "fiat", - "cash", - "gru" - ], - "extensions": { - "category": "gru-emoney", - "instrument": "emoney-or-fiat-backed-stablecoin", - "currency": "USD", - "settlement": "fiat", - "cashLike": true, - "backing": "cash,cash-equivalents", - "gruVersion": "v1", - "gruFamily": "cUSDT", - "x402Ready": false, - "fwdCanon": false, - "assetClass": "Cash & Equivalents", - "assetGroup": "MMF / Repo", - "instrumentType": "eMoney", - "underlying": "USD", - "gruLayer": "M1", - "rwaEligible": false - } - }, - { - "chainId": 138, - "address": "0x290E52a8819A4fbD0714E517225429aA2B70EC6b", - "name": "Gold (Compliant)", - "symbol": "cXAUC", - "decimals": 6, - "logoURI": "https://ipfs.io/ipfs/Qma3FKtLce9MjgJgWbtyCxBiPjJ6xi8jGWUSKNS5Jc2ong", - "tags": [ - "defi", - "compliant", - "gru" - ], - "extensions": { - "category": "gru-emoney", - "instrument": "commodity-referenced-token", - "settlement": "commodity", - "cashLike": false, - "backing": "commodity-reserves", - "gruVersion": "v1", - "gruFamily": "cXAUC", - "walletClass": "token", - "commodity": "gold", - "unit": "troy_ounce", - "assetClass": "Commodities", - "assetGroup": "Precious Metals", - "instrumentType": "eMoney", - "underlying": "Gold", - "gruLayer": "M1", - "rwaEligible": false - } - }, - { - "chainId": 138, - "address": "0x94e408E26c6FD8F4ee00b54dF19082FDA07dC96E", - "name": "Tether XAU (Compliant)", - "symbol": "cXAUT", - "decimals": 6, - "logoURI": "https://ipfs.io/ipfs/Qma3FKtLce9MjgJgWbtyCxBiPjJ6xi8jGWUSKNS5Jc2ong", - "tags": [ - "defi", - "compliant", - "gru" - ], - "extensions": { - "category": "gru-emoney", - "instrument": "commodity-referenced-token", - "settlement": "commodity", - "cashLike": false, - "backing": "commodity-reserves", - "gruVersion": "v1", - "gruFamily": "cXAUT", - "walletClass": "token", - "commodity": "gold", - "unit": "troy_ounce", - "assetClass": "Commodities", - "assetGroup": "Precious Metals", - "instrumentType": "eMoney", - "underlying": "Gold", - "gruLayer": "M1", - "rwaEligible": false - } - }, - { - "chainId": 138, - "address": "0x3304b747E565a97ec8AC220b0B6A1f6ffDB837e6", - "name": "ETH/USD Price Feed", - "symbol": "ETH-USD", - "decimals": 8, - "logoURI": "https://ipfs.io/ipfs/QmPZuycjyJEe2otREuQ5HirvPJ8X6Yc6MBtwz1VhdD79pY", - "tags": [ - "oracle", - "pricefeed" - ] - }, - { - "chainId": 138, - "address": "0xc5b802662447d1ae492a1618c3ad7161a449ebc9", - "name": "Base Metals Group Index 1 (M00)", - "symbol": "LiBMG1", - "decimals": 6, - "tags": [ - "rwa", - "index", - "m00" - ], - "extensions": { - "category": "rwa-index", - "gruLayer": "M00", - "rwaEligible": true, - "notEmoney": true, - "assetClass": "Commodities", - "assetGroup": "Industrial Metals", - "instrumentType": "Basket Index", - "underlying": "Base Metals", - "collateralType": "physical" - } - }, - { - "chainId": 138, - "address": "0x2ca3b3e7f4f216015833b0b334273d44493c0c45", - "name": "Base Metals Group Index 2 (M00)", - "symbol": "LiBMG2", - "decimals": 6, - "tags": [ - "rwa", - "index", - "m00" - ], - "extensions": { - "category": "rwa-index", - "gruLayer": "M00", - "rwaEligible": true, - "notEmoney": true, - "assetClass": "Commodities", - "assetGroup": "Industrial Metals", - "instrumentType": "Basket Index", - "underlying": "Battery Materials", - "collateralType": "physical" - } - }, - { - "chainId": 138, - "address": "0xb03d872196c0e84fe6fae841335001db44bda6c7", - "name": "Base Metals Group Index 3 (M00)", - "symbol": "LiBMG3", - "decimals": 6, - "tags": [ - "rwa", - "index", - "m00" - ], - "extensions": { - "category": "rwa-index", - "gruLayer": "M00", - "rwaEligible": true, - "notEmoney": true, - "assetClass": "Commodities", - "assetGroup": "Industrial Metals", - "instrumentType": "Basket Index", - "underlying": "Building Metals", - "collateralType": "physical" - } - }, - { - "chainId": 138, - "address": "0xb7721dD53A8c629d9f1Ba31a5819AFe250002b03", - "name": "Chainlink Token", - "symbol": "LINK", - "decimals": 18, - "logoURI": "https://explorer.d-bis.org/api/v1/report/logo/LINK", - "tags": [ - "defi", - "oracle", - "ccip" - ] - }, - { - "chainId": 138, - "address": "0x148b0f5c6fc8c5975e9406635654d88b20db2ed6", - "name": "Precious Metals Group Index (M00)", - "symbol": "LiPMG", - "decimals": 6, - "tags": [ - "rwa", - "index", - "m00" - ], - "extensions": { - "category": "rwa-index", - "gruLayer": "M00", - "rwaEligible": true, - "notEmoney": true, - "assetClass": "Commodities", - "assetGroup": "Precious Metals", - "instrumentType": "Basket Index", - "underlying": "Precious Metals", - "collateralType": "physical" - } - }, - { - "chainId": 138, - "address": "0xff862f0d1f96aa4882a0c2d6b4a3516fd8d68e75", - "name": "XAU Liquidity Index (M00, not cXAUC eMoney)", - "symbol": "LiXAU", - "decimals": 6, - "tags": [ - "rwa", - "index", - "m00" - ], - "extensions": { - "category": "rwa-index", - "gruLayer": "M00", - "rwaEligible": true, - "notEmoney": true, - "assetClass": "Commodities", - "assetGroup": "Precious Metals", - "instrumentType": "Commodity Index", - "underlying": "Gold", - "collateralType": "physical" - } - }, - { - "chainId": 138, - "address": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", - "name": "Wrapped Ether", - "symbol": "WETH", - "decimals": 18, - "logoURI": "https://explorer.d-bis.org/api/v1/report/logo/ETH", - "tags": [ - "defi", - "wrapped" - ], - "extensions": { - "category": "wrapped-native", - "instrument": "wrapped-native", - "settlement": "crypto-native", - "cashLike": false, - "backing": "native-gas-asset", - "walletClass": "token", - "alias": "WETH9", - "aliasNote": "Expose WETH9 as a compatibility alias on s" - } - }, - { - "chainId": 138, - "address": "0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9F", - "name": "Wrapped Ether v10", - "symbol": "WETH10", - "decimals": 18, - "logoURI": "https://explorer.d-bis.org/api/v1/report/logo/ETH", - "tags": [ - "defi", - "wrapped" - ], - "extensions": { - "category": "wrapped-native", - "instrument": "wrapped-native", - "settlement": "crypto-native", - "cashLike": false, - "backing": "native-gas-asset", - "walletClass": "token" - } } ] } diff --git a/backend/go.mod b/backend/go.mod index 709bdac..17a15dd 100644 --- a/backend/go.mod +++ b/backend/go.mod @@ -9,7 +9,7 @@ require ( github.com/ethereum/go-ethereum v1.13.5 github.com/golang-jwt/jwt/v4 v4.5.2 github.com/gorilla/websocket v1.5.1 - github.com/jackc/pgx/v5 v5.5.1 + github.com/jackc/pgx/v5 v5.5.5 github.com/redis/go-redis/v9 v9.17.2 github.com/stretchr/testify v1.11.1 golang.org/x/crypto v0.36.0 @@ -33,6 +33,7 @@ require ( github.com/ethereum/c-kzg-4844 v0.4.0 // indirect github.com/go-ole/go-ole v1.2.5 // indirect github.com/go-stack/stack v1.8.1 // indirect + github.com/google/uuid v1.6.0 // indirect github.com/holiman/uint256 v1.2.3 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 // indirect @@ -40,6 +41,8 @@ require ( github.com/mattn/go-isatty v0.0.19 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/prometheus/client_golang v1.20.5 // indirect + github.com/rogpeppe/go-internal v1.10.0 // indirect github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect github.com/supranational/blst v0.3.11 // indirect github.com/tklauser/go-sysconf v0.3.12 // indirect @@ -51,6 +54,5 @@ require ( golang.org/x/sys v0.31.0 // indirect golang.org/x/text v0.23.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect - google.golang.org/protobuf v1.33.0 // indirect rsc.io/tmplfunc v0.0.3 // indirect ) diff --git a/backend/go.sum b/backend/go.sum index f48a81d..4f8c1b3 100644 --- a/backend/go.sum +++ b/backend/go.sum @@ -75,13 +75,11 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI= github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= @@ -98,14 +96,14 @@ github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsI github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 h1:L0QtFUgDarD7Fpv9jeVMgy/+Ec0mtnmYuImjTz6dtDA= github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= -github.com/jackc/pgx/v5 v5.5.1 h1:5I9etrGkLrN+2XPCsi6XLlV5DITbSL/xBZdmAxFcXPI= -github.com/jackc/pgx/v5 v5.5.1/go.mod h1:Ig06C2Vu0t5qXC60W8sqIthScaEnFvojjj9dSljmHRA= +github.com/jackc/pgx/v5 v5.5.5 h1:amBjrZVmksIdNjxGW/IiIMzxMKZFelXbUoPNb+8sjQw= +github.com/jackc/pgx/v5 v5.5.5/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A= github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk= github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= -github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw= -github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4= +github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= +github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -120,8 +118,6 @@ github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APP github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= -github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= @@ -129,26 +125,28 @@ github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8oh github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.12.0 h1:C+UIj/QWtmqY13Arb8kwMt5j34/0Z2iKamrJ+ryC0Gg= -github.com/prometheus/client_golang v1.12.0/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= -github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a h1:CmF68hwI0XsOQ5UwlBopMi2Ow4Pbg32akc4KIVCOm+Y= -github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= -github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4= -github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= -github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y= +github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= +github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= +github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= +github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= +github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/redis/go-redis/v9 v9.17.2 h1:P2EGsA4qVIM3Pp+aPocCJ7DguDHhqrXNhVcEp4ViluI= github.com/redis/go-redis/v9 v9.17.2/go.mod h1:u410H11HMLoB+TP67dz8rL9s6QW2j76l0//kSOd3370= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= -github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= @@ -198,8 +196,8 @@ golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/config/web3-identity-registry.v1.json b/config/web3-identity-registry.v1.json new file mode 100644 index 0000000..a83b998 --- /dev/null +++ b/config/web3-identity-registry.v1.json @@ -0,0 +1,756 @@ +{ + "schemaVersion": "1.0.0", + "updated": "2026-06-10", + "description": "Unified Web3 identity registry — addresses, ENS, explorer labels, and institutional identifier refs. SSOT for naming across Blockscout sync, explorer UI, and frontend-dapp.", + "policyDoc": "docs/04-configuration/WEB3_IDENTITY_AND_NAMING_POLICY.md", + "sources": [ + "smom-dbis-138/config/address-inventory.chain138.json", + "config/chain138-official-protocol-contracts.json", + "config/compliance/liquidity-vault-gnosis-safe-mainnet.v1.json", + "docs/04-configuration/mifos-omnl-central-bank/OMNL_ENTITY_MASTER_DATA.json" + ], + "entries": [ + { + "id": "deployer-defi-oracle", + "address": "0x4A666F96fC8764181194447A7dFdb7d471b301C8", + "chainIds": [ + 1, + 138 + ], + "roles": [ + "deployer", + "operator" + ], + "displayName": "DeFi Oracle Deployer", + "ens": { + "primary": "defi-oracle.eth", + "chainId": 1 + }, + "web3Domains": [], + "identifiers": [ + { + "type": "inventoryKey", + "value": "DEPLOYER_ADMIN_138" + } + ], + "explorer": { + "blockscoutLabel": "DeFi Oracle Deployer (defi-oracle.eth)", + "tagTypes": [ + "operator", + "deployer" + ] + }, + "eiLabel": null + }, + { + "id": "liquidity-vault-safe-mainnet", + "address": "0x93a42Bdc51BecE00a2F31C744Fceb4956C4B6f76", + "chainIds": [ + 1 + ], + "roles": [ + "treasury", + "multisig" + ], + "displayName": "LiquidityVault Safe", + "ens": null, + "web3Domains": [], + "identifiers": [ + { + "type": "inventoryKey", + "value": "LIQUIDITY_VAULT_SAFE_MAINNET" + }, + { + "type": "safe", + "value": "2-of-4", + "note": "Created by defi-oracle.eth" + } + ], + "explorer": { + "blockscoutLabel": "LiquidityVault Safe (2-of-4)", + "tagTypes": [ + "treasury", + "multisig" + ] + }, + "eiLabel": null + }, + { + "id": "dodo-pmm-integration-stack-a", + "address": "0x86ADA6Ef91A3B450F89f2b751e93B1b7A3218895", + "chainIds": [ + 138 + ], + "roles": [ + "protocol", + "dex", + "pmm" + ], + "displayName": "DODO PMM Integration (Stack A)", + "ens": null, + "web3Domains": [], + "identifiers": [ + { + "type": "inventoryKey", + "value": "DODO_PMM_INTEGRATION" + }, + { + "type": "protocol", + "value": "dodo_v2" + } + ], + "explorer": { + "blockscoutLabel": "DODO PMM Integration (live Stack A)", + "tagTypes": [ + "protocol", + "dex", + "pmm" + ] + }, + "eiLabel": null + }, + { + "id": "dodo-pmm-provider", + "address": "0x3f729632E9553EBacCdE2e9b4c8F2B285b014F2e", + "chainIds": [ + 138 + ], + "roles": [ + "protocol", + "dex", + "pmm" + ], + "displayName": "DODO PMM Provider", + "ens": null, + "web3Domains": [], + "identifiers": [ + { + "type": "inventoryKey", + "value": "DODO_PMM_PROVIDER" + } + ], + "explorer": { + "blockscoutLabel": "DODO PMM Provider (ILiquidityProvider)", + "tagTypes": [ + "protocol", + "dex" + ] + }, + "eiLabel": null + }, + { + "id": "dodo-v2-proxy", + "address": "0xEF6E6F41A522896a9EE1C580C87C05E409193F8d", + "chainIds": [ + 138 + ], + "roles": [ + "protocol", + "dex", + "router" + ], + "displayName": "DODOV2Proxy02", + "ens": null, + "web3Domains": [], + "identifiers": [ + { + "type": "inventoryKey", + "value": "DODO_V2_PROXY" + }, + { + "type": "protocol", + "value": "dodo_v2" + } + ], + "explorer": { + "blockscoutLabel": "DODOV2Proxy02", + "tagTypes": [ + "protocol", + "router" + ] + }, + "eiLabel": null + }, + { + "id": "canonical-cusdt-138", + "address": "0x93E66202A11B1772E55407B32B44e5Cd8eda7f22", + "chainIds": [ + 138 + ], + "roles": [ + "token", + "stablecoin" + ], + "displayName": "cUSDT (canonical)", + "ens": null, + "web3Domains": [], + "identifiers": [ + { + "type": "symbol", + "value": "cUSDT" + }, + { + "type": "decimals", + "value": "6" + } + ], + "explorer": { + "blockscoutLabel": "cUSDT (Compliant USDT)", + "tagTypes": [ + "token", + "stablecoin", + "gru" + ] + }, + "eiLabel": null + }, + { + "id": "canonical-cusdc-138", + "address": "0xf22258f57794CC8E06237084b353Ab30fFfa640b", + "chainIds": [ + 138 + ], + "roles": [ + "token", + "stablecoin" + ], + "displayName": "cUSDC (canonical)", + "ens": null, + "web3Domains": [], + "identifiers": [ + { + "type": "symbol", + "value": "cUSDC" + }, + { + "type": "decimals", + "value": "6" + } + ], + "explorer": { + "blockscoutLabel": "cUSDC (Compliant USDC)", + "tagTypes": [ + "token", + "stablecoin", + "gru" + ] + }, + "eiLabel": null + }, + { + "id": "canonical-cbtc-138", + "address": "0xe94260c555ac1d9d3cc9e1632883452ebdf0082e", + "chainIds": [ + 138 + ], + "roles": [ + "token" + ], + "displayName": "cBTC (canonical)", + "ens": null, + "web3Domains": [], + "identifiers": [ + { + "type": "symbol", + "value": "cBTC" + }, + { + "type": "decimals", + "value": "8" + } + ], + "explorer": { + "blockscoutLabel": "cBTC (Compliant BTC)", + "tagTypes": [ + "token", + "gru" + ] + }, + "eiLabel": null + }, + { + "id": "pmm-pool-cusdt-cusdc", + "address": "0x9e89bAe009adf128782E19e8341996c596ac40dC", + "chainIds": [ + 138 + ], + "roles": [ + "pool", + "pmm" + ], + "displayName": "PMM Pool cUSDT/cUSDC", + "ens": null, + "web3Domains": [], + "identifiers": [ + { + "type": "pair", + "value": "cUSDT/cUSDC" + } + ], + "explorer": { + "blockscoutLabel": "DODO PMM cUSDT/cUSDC (live)", + "tagTypes": [ + "pool", + "pmm", + "dex" + ] + }, + "eiLabel": null + }, + { + "id": "ccip-router-138", + "address": "0x42DAb7b888Dd382bD5Adcf9E038dBF1fD03b4817", + "chainIds": [ + 138 + ], + "roles": [ + "bridge", + "ccip" + ], + "displayName": "CCIP Router (Chain 138)", + "ens": null, + "web3Domains": [], + "identifiers": [ + { + "type": "inventoryKey", + "value": "CCIP_ROUTER_138" + } + ], + "explorer": { + "blockscoutLabel": "Chainlink CCIP Router", + "tagTypes": [ + "bridge", + "ccip" + ] + }, + "eiLabel": null + }, + { + "id": "oracle-aggregator-138", + "address": "0x99b3511a2d315a497c8112c1fdd8d508d4b1e506", + "chainIds": [ + 138 + ], + "roles": [ + "oracle" + ], + "displayName": "Oracle Aggregator", + "ens": null, + "web3Domains": [], + "identifiers": [ + { + "type": "inventoryKey", + "value": "ORACLE_AGGREGATOR_ADDRESS" + } + ], + "explorer": { + "blockscoutLabel": "Oracle Aggregator", + "tagTypes": [ + "oracle" + ] + }, + "eiLabel": null + }, + { + "id": "multicall3-138", + "address": "0xcA11bde05977b3631167028862bE2a173976CA11", + "chainIds": [ + 138 + ], + "roles": [ + "utility" + ], + "displayName": "Multicall3", + "ens": null, + "web3Domains": [], + "identifiers": [ + { + "type": "inventoryKey", + "value": "MULTICALL3" + }, + { + "type": "protocol", + "value": "multicall3" + } + ], + "explorer": { + "blockscoutLabel": "Multicall3", + "tagTypes": [ + "utility" + ] + }, + "eiLabel": null + }, + { + "id": "liquidity-owner-adam", + "address": "0x348775A05CF5b6fC9d18830CfBd63DAE0Fb3c668", + "chainIds": [ + 1 + ], + "roles": [ + "multisig-owner" + ], + "displayName": "AdamMultiSig (LiquidityVault owner)", + "ens": null, + "web3Domains": [], + "identifiers": [ + { + "type": "safeOwner", + "value": "LiquidityVault" + } + ], + "explorer": { + "blockscoutLabel": "LiquidityVault Owner — AdamMultiSig", + "tagTypes": [ + "multisig-owner" + ] + }, + "eiLabel": null + }, + { + "id": "liquidity-owner-benard", + "address": "0x3F5BD2e9DA51Dc76f7F3308daa904C1B9E90460f", + "chainIds": [ + 1 + ], + "roles": [ + "multisig-owner" + ], + "displayName": "BenardMultiSig (LiquidityVault owner)", + "ens": null, + "web3Domains": [], + "identifiers": [ + { + "type": "safeOwner", + "value": "LiquidityVault" + } + ], + "explorer": { + "blockscoutLabel": "LiquidityVault Owner — BenardMultiSig", + "tagTypes": [ + "multisig-owner" + ] + }, + "eiLabel": null + }, + { + "id": "liquidity-owner-nathan", + "address": "0x8c906Bd27ba9Ea828B32DaE484eea5982b20CDb9", + "chainIds": [ + 1 + ], + "roles": [ + "multisig-owner" + ], + "displayName": "NathanMultiSig (LiquidityVault owner)", + "ens": null, + "web3Domains": [], + "identifiers": [ + { + "type": "safeOwner", + "value": "LiquidityVault" + } + ], + "explorer": { + "blockscoutLabel": "LiquidityVault Owner — NathanMultiSig", + "tagTypes": [ + "multisig-owner" + ] + }, + "eiLabel": null + }, + { + "id": "liquidity-owner-target", + "address": "0x16285b235b413bFd376ECBe66F2F9f5F6EA5313C", + "chainIds": [ + 1 + ], + "roles": [ + "multisig-owner" + ], + "displayName": "0xLiquidity (planned Safe owner)", + "ens": null, + "web3Domains": [], + "identifiers": [ + { + "type": "safeOwner", + "value": "LiquidityVault", + "note": "planned owner swap target" + } + ], + "explorer": { + "blockscoutLabel": "LiquidityVault Owner — 0xLiquidity (planned)", + "tagTypes": [ + "multisig-owner" + ] + }, + "eiLabel": null + }, + { + "id": "enhanced-swap-router-v2", + "address": "0xa421706768aeb7fafa2d912c5e10824ef3437ad4", + "chainIds": [ + 138 + ], + "roles": [ + "protocol", + "router" + ], + "displayName": "EnhancedSwapRouter V2", + "ens": null, + "web3Domains": [], + "identifiers": [ + { + "type": "inventoryKey", + "value": "ENHANCED_SWAP_ROUTER_V2_ADDRESS" + } + ], + "explorer": { + "blockscoutLabel": "EnhancedSwapRouter V2", + "tagTypes": [ + "protocol", + "router" + ] + }, + "eiLabel": null + }, + { + "id": "pmm-pool-cusdt-usdt", + "address": "0x866Cb44b59303d8dc5f4F9E3E7A8e8b0bf238d66", + "chainIds": [ + 138 + ], + "roles": [ + "pool", + "pmm" + ], + "displayName": "PMM Pool cUSDT/USDT", + "ens": null, + "web3Domains": [], + "identifiers": [ + { + "type": "pair", + "value": "cUSDT/USDT" + } + ], + "explorer": { + "blockscoutLabel": "DODO PMM cUSDT/USDT (live)", + "tagTypes": [ + "pool", + "pmm" + ] + }, + "eiLabel": null + }, + { + "id": "pmm-pool-cusdc-usdc", + "address": "0xc39B7D0F40838cbFb54649d327f49a6DAC964062", + "chainIds": [ + 138 + ], + "roles": [ + "pool", + "pmm" + ], + "displayName": "PMM Pool cUSDC/USDC", + "ens": null, + "web3Domains": [], + "identifiers": [ + { + "type": "pair", + "value": "cUSDC/USDC" + } + ], + "explorer": { + "blockscoutLabel": "DODO PMM cUSDC/USDC (live)", + "tagTypes": [ + "pool", + "pmm" + ] + }, + "eiLabel": null + }, + { + "id": "pmm-pool-cbtc-cusdt", + "address": "0x67049e7333481e2cac91af61403ac7bddfab7bcd", + "chainIds": [ + 138 + ], + "roles": [ + "pool", + "pmm" + ], + "displayName": "PMM Pool cBTC/cUSDT", + "ens": null, + "web3Domains": [], + "identifiers": [ + { + "type": "pair", + "value": "cBTC/cUSDT" + } + ], + "explorer": { + "blockscoutLabel": "DODO PMM cBTC/cUSDT (live)", + "tagTypes": [ + "pool", + "pmm" + ] + }, + "eiLabel": null + }, + { + "id": "pmm-pool-cbtc-cusdc", + "address": "0x72f1a0794153c3b8a1e8a731f1d8e1a52cb10dc5", + "chainIds": [ + 138 + ], + "roles": [ + "pool", + "pmm" + ], + "displayName": "PMM Pool cBTC/cUSDC", + "ens": null, + "web3Domains": [], + "identifiers": [ + { + "type": "pair", + "value": "cBTC/cUSDC" + } + ], + "explorer": { + "blockscoutLabel": "DODO PMM cBTC/cUSDC (live)", + "tagTypes": [ + "pool", + "pmm" + ] + }, + "eiLabel": null + }, + { + "id": "pmm-pool-weth-usdc", + "address": "0xb53a0508940b1ff90f1aad4f6cb50a7012fe5593", + "chainIds": [ + 138 + ], + "roles": [ + "pool", + "pmm" + ], + "displayName": "PMM Pool WETH/USDC", + "ens": null, + "web3Domains": [], + "identifiers": [ + { + "type": "pair", + "value": "WETH/USDC" + } + ], + "explorer": { + "blockscoutLabel": "DODO PMM WETH/USDC (live)", + "tagTypes": [ + "pool", + "pmm" + ] + }, + "eiLabel": null + }, + { + "id": "pmm-pool-weth-usdt", + "address": "0xe227f6c0520c0c6e8786fe56fa76c4914f861533", + "chainIds": [ + 138 + ], + "roles": [ + "pool", + "pmm" + ], + "displayName": "PMM Pool WETH/USDT", + "ens": null, + "web3Domains": [], + "identifiers": [ + { + "type": "pair", + "value": "WETH/USDT" + } + ], + "explorer": { + "blockscoutLabel": "DODO PMM WETH/USDT (live)", + "tagTypes": [ + "pool", + "pmm" + ] + }, + "eiLabel": null + }, + { + "id": "pmm-pool-cbtc-cxauc", + "address": "0xf3e8a07d419b61f002114e64d79f7cf8f7989433", + "chainIds": [ + 138 + ], + "roles": [ + "pool", + "pmm" + ], + "displayName": "PMM Pool cBTC/cXAUC", + "ens": null, + "web3Domains": [], + "identifiers": [ + { + "type": "pair", + "value": "cBTC/cXAUC" + } + ], + "explorer": { + "blockscoutLabel": "DODO PMM cBTC/cXAUC (live)", + "tagTypes": [ + "pool", + "pmm" + ] + }, + "eiLabel": null + } + ], + "entities": [ + { + "id": "omnl-head-office", + "displayName": "OMNL Head Office (DBIS) – Central Bank", + "lei": "98450070C57395F6B906", + "entityRef": "omnl-entity-master:1", + "roles": [ + "entity", + "central-bank" + ] + }, + { + "id": "omnl-nrb", + "displayName": "Nepal Rastra Bank", + "lei": "25490000MX377HHPSR96", + "entityRef": "omnl-entity-master:18", + "roles": [ + "entity", + "central-bank" + ] + }, + { + "id": "omnl-sanima", + "displayName": "Sanima Bank Limited", + "lei": "25490043FER1B108XE95", + "entityRef": "omnl-entity-master:19", + "roles": [ + "entity", + "bank" + ] + }, + { + "id": "omnl-cbuae", + "displayName": "Central Bank of the UAE", + "lei": "5493006P6LOOFH8TB150", + "entityRef": "omnl-entity-master:23", + "roles": [ + "entity", + "central-bank" + ] + } + ] +} diff --git a/docs/CHAIN138_VISUAL_TOPOLOGY_SOURCE.md b/docs/CHAIN138_VISUAL_TOPOLOGY_SOURCE.md new file mode 100644 index 0000000..5dc7e52 --- /dev/null +++ b/docs/CHAIN138_VISUAL_TOPOLOGY_SOURCE.md @@ -0,0 +1,35 @@ +# Chain 138 visual topology — command center source + +Canonical maintainer doc for `frontend/public/chain138-command-center.html` (live at `/chain138-command-center.html` and `/topology`). + +Diagrams are **informational**; live addresses and guardrails are served by the explorer: + +- `/protocols` and `/token-aggregation/api/v1/report/official-protocols` +- `/pools`, `/liquidity`, `/routes` +- `/bridge` (managed relay fleet + CCIP lane health) +- `/docs/gru`, `/docs/posture-glossary`, `/docs/transaction-review` + +## PMM production canon (Chain 138) + +| Role | Address | +|------|---------| +| DODOPMMIntegration Stack A (live) | `0x86ADA6Ef91A3B450F89f2b751e93B1b7A3218895` | +| DODOPMMProvider Stack A (live) | `0x3f729632E9553EBacCdE2e9b4c8F2B285b014F2e` | +| EnhancedSwapRouter (live) | `0xE6Cc7643ae2A4C720A28D8263BC4972905d7DE0f` | +| Stack B integration (do not wire) | `0x5BDc62f1ae7D630c37A8B363a1d49845356Ee72d` | + +EnhancedSwapRouterV2 remains a planned Phase 4b deploy; it is not the default production router. + +## Managed relay lanes (explorer `/bridge`) + +`mainnet_weth`, `mainnet_cw`, `bsc`, `avax`, `avax_cw`, `avax_to_138` + +## External references (proxmox monorepo) + +When editing diagrams, cross-check: + +- `docs/11-references/PMM_DEX_ROUTING_STATUS.md` +- `docs/11-references/CONTRACT_ADDRESSES_REFERENCE.md` +- `docs/11-references/EXPLORER_TOKEN_LIST_CROSSCHECK.md` (§5 canonical tokens) + +Bundle metadata: `frontend/public/chain138-command-center.meta.json` (refresh via `scripts/refresh-chain138-command-center-meta.sh`). diff --git a/docs/EXPLORER_API_ACCESS.md b/docs/EXPLORER_API_ACCESS.md index f487c44..63596b4 100644 --- a/docs/EXPLORER_API_ACCESS.md +++ b/docs/EXPLORER_API_ACCESS.md @@ -388,7 +388,7 @@ The script checks: - HTTP 200 on `/api/v2/stats`, `/api/v2/blocks`, `/api/v2/transactions`. - Explorer frontend at `/` returns 200. - Chain 138 Snap companion site at `/snap/` returns 200 or 301 and contains expected content when 200. -- The static Visual Command Center at `/chain138-command-center.html` returns 200 and contains expected architecture text. +- The static Visual Command Center at `/chain138-command-center.html` (alias `/topology`) returns 200, includes Stack A PMM canon text, and `/chain138-command-center.meta.json` exposes bundle metadata. - Mission Control endpoints return healthy responses: - `/explorer-api/v1/mission-control/stream` - `/explorer-api/v1/mission-control/bridge/trace` diff --git a/frontend/libs/frontend-ui-primitives/Address.tsx b/frontend/libs/frontend-ui-primitives/Address.tsx index 0cc26e1..3270b6c 100644 --- a/frontend/libs/frontend-ui-primitives/Address.tsx +++ b/frontend/libs/frontend-ui-primitives/Address.tsx @@ -1,9 +1,13 @@ -import { useState } from 'react' +import { useEffect, useState } from 'react' import clsx from 'clsx' +import { getKnownDisplayName } from '@/utils/web3IdentityRegistry' +import { resolveEnsName } from '@/utils/ens' interface AddressProps { address: string chainId?: number + /** Blockscout or caller-provided label (highest precedence). */ + label?: string | null showCopy?: boolean showENS?: boolean truncate?: boolean @@ -12,14 +16,30 @@ interface AddressProps { export function Address({ address, - chainId, + chainId: _chainId, + label, showCopy = true, showENS = false, truncate = false, className, }: AddressProps) { const [copied, setCopied] = useState(false) + const [ensName, setEnsName] = useState(null) + const registryLabel = getKnownDisplayName(address) + + useEffect(() => { + if (!showENS || !address) return + let active = true + void resolveEnsName(address).then((name) => { + if (active) setEnsName(name) + }) + return () => { + active = false + } + }, [address, showENS]) + + const primaryLabel = label || registryLabel || (showENS ? ensName : null) || null const displayAddress = truncate ? `${address.slice(0, 6)}...${address.slice(-4)}` : address @@ -42,14 +62,20 @@ export function Address({ className )} > - - {displayAddress} - +
+ {primaryLabel ? ( +
{primaryLabel}
+ ) : null} + + {displayAddress} + +
{showCopy && ( - - - - - - - - +
+
+ + + + + + + + + +
- Back to Operations + Operations hub
-

Hub, leaf endings, CCIP destinations, Alltra, the dedicated Avalanche cW corridor, the public cW mesh, and pending programs. Mainnet cW mint corridors and the optional TRUU rail are summarized under the Ethereum anchor.

+

Hub, leaf endings, CCIP destinations, Alltra, Avalanche cW corridor, public cW mesh, and pending programs. Mainnet cW mint corridors and optional TRUU sit under the Ethereum anchor.

flowchart TB subgraph LEAF_INGRESS["Leaves — access to 138"] @@ -187,44 +304,44 @@ flowchart TB end subgraph LEAF_EDGE["Leaves — services that index or front 138"] - EXP[Explorer · Blockscout · token-aggregation] + EXP[explorer.d-bis.org · blockscout.defi-oracle.io · token-aggregation] INFO[info.defi-oracle.io] - DAPP[dapp.d-bis.org bridge UI] + DAPP[dapp.d-bis.org bridge UI · atomic-swap.defi-oracle.io] DBIS[dbis-api Core hosts] X402[x402 payment API] MCP[MCP PMM controller] end subgraph HUB["CHAIN 138 — origin hub"] - C138["Besu EVM · tokens core · DODO PMM V2/V3 · RouterV2 · UniV3 / Balancer / Curve / 1inch pilots · CCIP bridges + router · AlltraAdapter · BridgeVault · ISO channels · mirror reserve vault settlement · Lockbox · Truth / Tron / Solana adapters"] + C138["Besu EVM · tokens · DODO PMM Stack A · EnhancedSwapRouter live · UniV3 / Balancer / Curve / 1inch pilots · CCIP · AlltraAdapter · BridgeVault · ISO · reserve vault · Lockbox · Truth / Tron / Solana adapters"] end subgraph CCIP_ETH["Ethereum 1 — CCIP anchor"] ETH1["WETH9 / WETH10 bridges · CCIPRelayRouter · RelayBridge · Logger · optional trustless stack"] - LEAF_ETH["Leaf — Mainnet native DEX venues · Li.Fi touchpoints on other chains · first-wave cW DODO pools · optional TRUU PMM rail"] + LEAF_ETH["Mainnet DEX · Li.Fi touchpoints · first-wave cW DODO pools · optional TRUU PMM rail"] end subgraph CCIP_L2["Other live CCIP EVM destinations"] L2CLU["OP 10 · Base 8453 · Arb 42161 · Polygon 137 · BSC 56 · Avax 43114 · Gnosis 100 · Celo 42220 · Cronos 25"] - LEAF_L2["Leaf — per-chain native DEX · cW public-network representation · partial edge pools"] + LEAF_L2["Per-chain native DEX · cW representation · partial edge pools"] end subgraph ALLTRA["ALL Mainnet 651940"] A651["AlltraAdapter peer · AUSDT · WETH · WALL · HYDX · DEX env placeholders"] - LEAF_651["Leaf — ALL native venues when configured"] + LEAF_651["ALL native venues when configured"] end subgraph SPECIAL["Dedicated corridor from 138"] AVAXCW["138 cUSDT to Avax cWUSDT mint path"] - LEAF_AVAX["Leaf — recipient on 43114"] + LEAF_AVAX["Recipient on 43114"] end subgraph CW_MESH["Public cW GRU mesh"] CW["Cross-public-EVM token matrix · pool design · Mainnet DODO concentration"] end - subgraph PENDING["Pending separate scaffold"] - WEMIX[Wemix 1111 CCIP pending] + subgraph PENDING["Pending or degraded scaffold"] + WEMIX[Wemix 1111 CCIP lane degraded] XDC[XDC Zero parallel program] SCAFF[Etherlink Tezos OP L2 design] PNON[Truth pointer · Tron adapter · Solana partial] @@ -265,13 +382,14 @@ flowchart TB