feat: explorer API, wallet, CCIP scripts, and config refresh

- Backend REST/gateway/track routes, analytics, Blockscout proxy paths.
- Frontend wallet and liquidity surfaces; MetaMask token list alignment.
- Deployment docs, verification scripts, address inventory updates.

Check: go build ./... under backend/ (pass).
Made-with: Cursor
This commit is contained in:
defiQUG
2026-04-07 23:22:12 -07:00
parent d931be8e19
commit 6eef6b07f6
224 changed files with 19671 additions and 3291 deletions

View File

@@ -1,17 +1,22 @@
package track1
import (
"context"
"encoding/json"
"fmt"
"math/big"
"net/http"
"regexp"
"strconv"
"strings"
"time"
"github.com/ethereum/go-ethereum/common"
"github.com/explorer/backend/libs/go-rpc-gateway"
)
var track1HashPattern = regexp.MustCompile(`^0x[a-fA-F0-9]{64}$`)
// Server handles Track 1 endpoints (uses RPC gateway from lib)
type Server struct {
rpcGateway *gateway.RPCGateway
@@ -173,7 +178,12 @@ func (s *Server) HandleBlockDetail(w http.ResponseWriter, r *http.Request) {
}
path := strings.TrimPrefix(r.URL.Path, "/api/v1/track1/block/")
blockNumStr := fmt.Sprintf("0x%x", parseBlockNumber(path))
blockNumber, err := strconv.ParseInt(strings.TrimSpace(path), 10, 64)
if err != nil || blockNumber < 0 {
writeError(w, http.StatusBadRequest, "bad_request", "Invalid block number")
return
}
blockNumStr := fmt.Sprintf("0x%x", blockNumber)
blockResp, err := s.rpcGateway.GetBlockByNumber(r.Context(), blockNumStr, false)
if err != nil {
@@ -203,7 +213,11 @@ func (s *Server) HandleTransactionDetail(w http.ResponseWriter, r *http.Request)
}
path := strings.TrimPrefix(r.URL.Path, "/api/v1/track1/tx/")
txHash := path
txHash := strings.TrimSpace(path)
if !track1HashPattern.MatchString(txHash) {
writeError(w, http.StatusBadRequest, "bad_request", "Invalid transaction hash")
return
}
txResp, err := s.rpcGateway.GetTransactionByHash(r.Context(), txHash)
if err != nil {
@@ -239,7 +253,11 @@ func (s *Server) HandleAddressBalance(w http.ResponseWriter, r *http.Request) {
return
}
address := parts[0]
address := strings.TrimSpace(parts[0])
if !common.IsHexAddress(address) {
writeError(w, http.StatusBadRequest, "bad_request", "Invalid address")
return
}
balanceResp, err := s.rpcGateway.GetBalance(r.Context(), address, "latest")
if err != nil {
writeError(w, http.StatusInternalServerError, "rpc_error", err.Error())
@@ -278,31 +296,25 @@ func (s *Server) HandleBridgeStatus(w http.ResponseWriter, r *http.Request) {
return
}
// Return bridge status (simplified - in production, query bridge contracts)
ctx, cancel := context.WithTimeout(r.Context(), 12*time.Second)
defer cancel()
data := s.BuildBridgeStatusData(ctx)
response := map[string]interface{}{
"data": map[string]interface{}{
"status": "operational",
"chains": map[string]interface{}{
"138": map[string]interface{}{
"name": "Defi Oracle Meta Mainnet",
"status": "operational",
"last_sync": time.Now().UTC().Format(time.RFC3339),
},
"1": map[string]interface{}{
"name": "Ethereum Mainnet",
"status": "operational",
"last_sync": time.Now().UTC().Format(time.RFC3339),
},
},
"total_transfers_24h": 150,
"total_volume_24h": "5000000000000000000000",
},
"data": data,
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
}
func chainStatusFromProbe(p RPCProbeResult) string {
if p.OK {
return "operational"
}
return "unreachable"
}
// Helper functions
func writeError(w http.ResponseWriter, statusCode int, code, message string) {
w.Header().Set("Content-Type", "application/json")
@@ -320,14 +332,6 @@ func hexToInt(hex string) (int64, error) {
return strconv.ParseInt(hex, 16, 64)
}
func parseBlockNumber(s string) int64 {
num, err := strconv.ParseInt(s, 10, 64)
if err != nil {
return 0
}
return num
}
func transformBlock(blockData map[string]interface{}) map[string]interface{} {
return map[string]interface{}{
"number": parseHexField(blockData["number"]),