Add bridge lane health API and config-ready lane UI for Tier A Week 3.
Some checks failed
Deploy Explorer Live / deploy (push) Failing after 13s
Validate Explorer / frontend (push) Failing after 21s
Validate Explorer / smoke-e2e (push) Has been skipped

Probe LINK balances on CCIP bridge contracts, expose proof-transfer metadata on bridge status, and render funded/unfunded lane health on /bridge with extended smoke coverage.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
defiQUG
2026-05-23 04:21:44 -07:00
parent 763ca75c21
commit 228fa0eef6
14 changed files with 605 additions and 3 deletions

View File

@@ -0,0 +1,255 @@
package track1
import (
"context"
_ "embed"
"encoding/json"
"math/big"
"net/http"
"os"
"strconv"
"strings"
"time"
)
//go:embed bridge_lanes_default.json
var defaultBridgeLanesJSON []byte
type bridgeLaneDefinition struct {
Key string `json:"key"`
ChainName string `json:"chain_name"`
ChainID int64 `json:"chain_id"`
ConfigReady bool `json:"config_ready"`
RPCEnvs []string `json:"rpc_envs"`
RPCDefault string `json:"rpc_default"`
LinkToken string `json:"link_token"`
WETH9Bridge string `json:"weth9_bridge"`
WETH10Bridge string `json:"weth10_bridge"`
}
type bridgeLanesConfig struct {
Updated string `json:"updated"`
MinLinkWei string `json:"min_link_wei"`
Lanes []bridgeLaneDefinition `json:"lanes"`
}
func loadBridgeLanesConfig() bridgeLanesConfig {
path := strings.TrimSpace(os.Getenv("MISSION_CONTROL_BRIDGE_LANES_JSON"))
if path != "" {
if b, err := os.ReadFile(path); err == nil && len(b) > 0 {
var cfg bridgeLanesConfig
if json.Unmarshal(b, &cfg) == nil && len(cfg.Lanes) > 0 {
return cfg
}
}
}
var cfg bridgeLanesConfig
_ = json.Unmarshal(defaultBridgeLanesJSON, &cfg)
return cfg
}
func resolveLaneRPC(def bridgeLaneDefinition) string {
for _, key := range def.RPCEnvs {
if value := strings.TrimSpace(os.Getenv(key)); value != "" {
return value
}
}
for _, row := range ParseExtraRPCProbes() {
chainKey := row[2]
if chainKey == strconv.FormatInt(def.ChainID, 10) {
return row[1]
}
}
return strings.TrimSpace(def.RPCDefault)
}
func erc20BalanceOf(ctx context.Context, rpcURL, tokenAddress, holderAddress string) (string, error) {
tokenAddress = strings.ToLower(strings.TrimSpace(tokenAddress))
holderAddress = strings.ToLower(strings.TrimPrefix(strings.TrimSpace(holderAddress), "0x"))
if len(holderAddress) != 40 {
return "0", nil
}
data := "0x70a08231" + strings.Repeat("0", 24) + holderAddress
raw, _, err := postJSONRPC(ctx, bridgeLaneHTTPClient(), rpcURL, "eth_call", []interface{}{
map[string]interface{}{
"to": tokenAddress,
"data": data,
},
"latest",
})
if err != nil {
return "", err
}
var hex string
if err := json.Unmarshal(raw, &hex); err != nil {
return "", err
}
hex = strings.TrimSpace(hex)
if hex == "" || hex == "0x" {
return "0", nil
}
value := new(big.Int)
if _, ok := value.SetString(strings.TrimPrefix(hex, "0x"), 16); !ok {
return "0", nil
}
return value.String(), nil
}
func bridgeLaneHTTPClient() *http.Client {
return &http.Client{Timeout: 6 * time.Second}
}
func bridgeFundingStatus(linkBalanceWei, minLinkWei string) string {
balance, okBalance := new(big.Int).SetString(strings.TrimSpace(linkBalanceWei), 10)
minimum, okMin := new(big.Int).SetString(strings.TrimSpace(minLinkWei), 10)
if !okBalance || !okMin {
return "unknown"
}
if balance.Cmp(minimum) >= 0 {
return "funded"
}
if balance.Sign() > 0 {
return "degraded"
}
return "unfunded"
}
func proofStatusForLane(key string, proofs map[string]interface{}) string {
if proofs == nil {
return "proof-pending"
}
laneProofs, ok := proofs[key].([]interface{})
if !ok || len(laneProofs) == 0 {
return "proof-pending"
}
for _, item := range laneProofs {
row, ok := item.(map[string]interface{})
if !ok {
continue
}
if tx, ok := row["tx_hash"].(string); ok && strings.TrimSpace(tx) != "" {
return "proof-recorded"
}
}
return "proof-pending"
}
func readProofTransfersJSON() map[string]interface{} {
path := strings.TrimSpace(os.Getenv("MISSION_CONTROL_PROOF_TRANSFERS_JSON"))
if path == "" {
return nil
}
b, err := os.ReadFile(path)
if err != nil || len(b) == 0 {
return map[string]interface{}{"error": "unreadable or empty", "path": path}
}
if len(b) > 512*1024 {
return map[string]interface{}{"error": "file too large", "path": path}
}
var payload map[string]interface{}
if err := json.Unmarshal(b, &payload); err != nil {
return map[string]interface{}{"error": err.Error(), "path": path}
}
return payload
}
func probeBridgeContract(ctx context.Context, rpcURL, linkToken, bridgeAddress, minLinkWei string) map[string]interface{} {
result := map[string]interface{}{
"bridge": strings.TrimSpace(bridgeAddress),
}
if rpcURL == "" {
result["status"] = "unknown"
result["error"] = "rpc unavailable"
return result
}
if linkToken == "" || bridgeAddress == "" {
result["status"] = "unknown"
result["error"] = "missing link token or bridge address"
return result
}
balance, err := erc20BalanceOf(ctx, rpcURL, linkToken, bridgeAddress)
if err != nil {
result["status"] = "unknown"
result["error"] = err.Error()
return result
}
result["link_balance_wei"] = balance
result["status"] = bridgeFundingStatus(balance, minLinkWei)
return result
}
func aggregateLaneStatus(weth9Status, weth10Status, proofStatus string) string {
statuses := []string{weth9Status, weth10Status}
hasUnfunded := false
hasDegraded := false
hasUnknown := false
for _, status := range statuses {
switch status {
case "unfunded":
hasUnfunded = true
case "degraded":
hasDegraded = true
case "unknown":
hasUnknown = true
}
}
if hasUnfunded {
return "unfunded"
}
if hasDegraded {
return "degraded"
}
if hasUnknown {
return "unknown"
}
if proofStatus == "proof-pending" {
return "proof-pending"
}
return "funded"
}
func BuildBridgeLaneHealth(ctx context.Context) (map[string]interface{}, map[string]interface{}) {
cfg := loadBridgeLanesConfig()
minLinkWei := strings.TrimSpace(cfg.MinLinkWei)
if minLinkWei == "" {
minLinkWei = "1000000000000000000"
}
proofPayload := readProofTransfersJSON()
proofByLane := map[string]interface{}{}
if proofPayload != nil {
if lanes, ok := proofPayload["lanes"].(map[string]interface{}); ok {
proofByLane = lanes
}
}
lanes := make([]map[string]interface{}, 0, len(cfg.Lanes))
for _, def := range cfg.Lanes {
rpcURL := resolveLaneRPC(def)
weth9 := probeBridgeContract(ctx, rpcURL, def.LinkToken, def.WETH9Bridge, minLinkWei)
weth10 := probeBridgeContract(ctx, rpcURL, def.LinkToken, def.WETH10Bridge, minLinkWei)
weth9Status, _ := weth9["status"].(string)
weth10Status, _ := weth10["status"].(string)
proofStatus := proofStatusForLane(def.Key, proofByLane)
lanes = append(lanes, map[string]interface{}{
"key": def.Key,
"chain_name": def.ChainName,
"chain_id": def.ChainID,
"config_ready": def.ConfigReady,
"link_token": def.LinkToken,
"status": aggregateLaneStatus(weth9Status, weth10Status, proofStatus),
"proof_status": proofStatus,
"weth9": weth9,
"weth10": weth10,
"rpc_endpoint": redactRPCOrigin(rpcURL),
})
}
laneHealth := map[string]interface{}{
"updated_at": time.Now().UTC().Format(time.RFC3339),
"min_link_wei": minLinkWei,
"lanes": lanes,
}
return laneHealth, proofPayload
}

View File

@@ -0,0 +1,61 @@
{
"updated": "2026-05-23",
"min_link_wei": "1000000000000000000",
"lanes": [
{
"key": "chain138",
"chain_name": "Defi Oracle Meta Mainnet (138)",
"chain_id": 138,
"config_ready": true,
"rpc_envs": ["RPC_URL", "RPC_URL_138"],
"rpc_default": "http://192.168.11.211:8545",
"link_token": "0xb7721dd53a8c629d9f1ba31a5819afe250002b03",
"weth9_bridge": "0xcacfd227A040002e49e2e01626363071324f820a",
"weth10_bridge": "0xe0E93247376aa097dB308B92e6Ba36bA015535D0"
},
{
"key": "gnosis",
"chain_name": "Gnosis (100)",
"chain_id": 100,
"config_ready": true,
"rpc_envs": ["GNOSIS_RPC", "GNOSIS_MAINNET_RPC", "GNOSIS_RPC_URL"],
"rpc_default": "https://rpc.gnosischain.com",
"link_token": "0xE2e73A1c69ecF83F464EFCE6A5be353a37cA09b2",
"weth9_bridge": "0xc8656F24488cb90c452058da92d1a25BA464eaAE",
"weth10_bridge": "0xa846aeAD3071df1b6439d5D813156aCE7C2c1DA1"
},
{
"key": "cronos",
"chain_name": "Cronos (25)",
"chain_id": 25,
"config_ready": true,
"rpc_envs": ["CRONOS_RPC", "CRONOS_RPC_URL", "CRONOS_MAINNET_RPC"],
"rpc_default": "https://evm.cronos.org",
"link_token": "0x8c80A01F461f297Df7F9DA3A4f740D7297C8Ac85",
"weth9_bridge": "0x3Cc23d086fCcbAe1e5f3FE2bA4A263E1D27d8Cab",
"weth10_bridge": "0x105F8A15b819948a89153505762444Ee9f324684"
},
{
"key": "celo",
"chain_name": "Celo (42220)",
"chain_id": 42220,
"config_ready": true,
"rpc_envs": ["CELO_RPC", "CELO_MAINNET_RPC"],
"rpc_default": "https://forno.celo.org",
"link_token": "0xd07294e6E917e07dfDcee882dd1e2565085C2ae0",
"weth9_bridge": "0xAb57BF30F1354CA0590af22D8974c7f24DB2DbD7",
"weth10_bridge": "0xa780ef19A041745d353c9432f2a7f5A241335ffE"
},
{
"key": "wemix",
"chain_name": "Wemix (1111)",
"chain_id": 1111,
"config_ready": true,
"rpc_envs": ["WEMIX_RPC", "WEMIX_MAINNET_RPC"],
"rpc_default": "https://api.wemix.com",
"link_token": "0x80f1FcdC96B55e459BF52b998aBBE2c364935d69",
"weth9_bridge": "0xD3AD6831aacB5386B8A25BB8D8176a6C8a026f04",
"weth10_bridge": "0xa4B9DD039565AeD9641D45b57061f99d9cA6Df08"
}
]
}

View File

@@ -0,0 +1,37 @@
package track1
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestBridgeFundingStatus(t *testing.T) {
require.Equal(t, "funded", bridgeFundingStatus("2000000000000000000", "1000000000000000000"))
require.Equal(t, "degraded", bridgeFundingStatus("500000000000000000", "1000000000000000000"))
require.Equal(t, "unfunded", bridgeFundingStatus("0", "1000000000000000000"))
}
func TestAggregateLaneStatus(t *testing.T) {
require.Equal(t, "unfunded", aggregateLaneStatus("unfunded", "funded", "proof-recorded"))
require.Equal(t, "degraded", aggregateLaneStatus("degraded", "funded", "proof-recorded"))
require.Equal(t, "proof-pending", aggregateLaneStatus("funded", "funded", "proof-pending"))
require.Equal(t, "funded", aggregateLaneStatus("funded", "funded", "proof-recorded"))
}
func TestProofStatusForLane(t *testing.T) {
proofs := map[string]interface{}{
"gnosis": []interface{}{
map[string]interface{}{"tx_hash": "0xabc"},
},
}
require.Equal(t, "proof-recorded", proofStatusForLane("gnosis", proofs))
require.Equal(t, "proof-pending", proofStatusForLane("cronos", proofs))
}
func TestLoadBridgeLanesConfigDefault(t *testing.T) {
t.Setenv("MISSION_CONTROL_BRIDGE_LANES_JSON", "")
cfg := loadBridgeLanesConfig()
require.NotEmpty(t, cfg.Lanes)
require.NotEmpty(t, cfg.MinLinkWei)
}

View File

@@ -30,6 +30,14 @@ func TestResolveBridgeDeliveryModeMixedWhenTransactionVisibilityStale(t *testing
require.Equal(t, "bridge_monitoring_and_homepage", got.Scope)
}
func TestResolveBridgeDeliveryModeMixedWhenQuietChain(t *testing.T) {
diagnostics := &freshness.Diagnostics{
ActivityState: "quiet_chain",
}
got := resolveBridgeDeliveryMode(false, diagnostics, freshness.CompletenessComplete)
require.Equal(t, "live", got.Kind)
}
func TestIsStaleTransactionVisibility(t *testing.T) {
require.True(t, isStaleTransactionVisibility(&freshness.Diagnostics{ActivityState: "fresh_head_stale_transaction_visibility"}))
require.False(t, isStaleTransactionVisibility(&freshness.Diagnostics{ActivityState: "healthy"}))

View File

@@ -198,6 +198,12 @@ func (s *Server) BuildBridgeStatusData(ctx context.Context) map[string]interface
}
}
}
if laneHealth, proofTransfers := BuildBridgeLaneHealth(ctx); laneHealth != nil {
data["bridge_lanes"] = laneHealth
if proofTransfers != nil {
data["proof_transfers"] = proofTransfers
}
}
if mode, ok := data["mode"].(map[string]interface{}); ok {
if relays, ok := data["ccip_relays"].(map[string]interface{}); ok && len(relays) > 0 {
var diagnostics *freshness.Diagnostics