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:
@@ -15,9 +15,12 @@ func (s *Server) handleGetAddress(w http.ResponseWriter, r *http.Request) {
|
||||
writeMethodNotAllowed(w)
|
||||
return
|
||||
}
|
||||
if !s.requireDB(w) {
|
||||
return
|
||||
}
|
||||
|
||||
// Parse address from URL
|
||||
address := r.URL.Query().Get("address")
|
||||
address := normalizeAddress(r.URL.Query().Get("address"))
|
||||
if address == "" {
|
||||
writeValidationError(w, fmt.Errorf("address required"))
|
||||
return
|
||||
@@ -36,7 +39,7 @@ func (s *Server) handleGetAddress(w http.ResponseWriter, r *http.Request) {
|
||||
// Get transaction count
|
||||
var txCount int64
|
||||
err := s.db.QueryRow(ctx,
|
||||
`SELECT COUNT(*) FROM transactions WHERE chain_id = $1 AND (from_address = $2 OR to_address = $2)`,
|
||||
`SELECT COUNT(*) FROM transactions WHERE chain_id = $1 AND (LOWER(from_address) = $2 OR LOWER(to_address) = $2)`,
|
||||
s.chainID, address,
|
||||
).Scan(&txCount)
|
||||
if err != nil {
|
||||
@@ -47,7 +50,7 @@ func (s *Server) handleGetAddress(w http.ResponseWriter, r *http.Request) {
|
||||
// Get token count
|
||||
var tokenCount int
|
||||
err = s.db.QueryRow(ctx,
|
||||
`SELECT COUNT(DISTINCT token_address) FROM token_transfers WHERE chain_id = $1 AND (from_address = $2 OR to_address = $2)`,
|
||||
`SELECT COUNT(DISTINCT token_contract) FROM token_transfers WHERE chain_id = $1 AND (LOWER(from_address) = $2 OR LOWER(to_address) = $2)`,
|
||||
s.chainID, address,
|
||||
).Scan(&tokenCount)
|
||||
if err != nil {
|
||||
@@ -57,44 +60,42 @@ func (s *Server) handleGetAddress(w http.ResponseWriter, r *http.Request) {
|
||||
// Get label
|
||||
var label sql.NullString
|
||||
s.db.QueryRow(ctx,
|
||||
`SELECT label FROM address_labels WHERE chain_id = $1 AND address = $2 AND label_type = 'public' LIMIT 1`,
|
||||
`SELECT label FROM address_labels WHERE chain_id = $1 AND LOWER(address) = $2 AND label_type = 'public' LIMIT 1`,
|
||||
s.chainID, address,
|
||||
).Scan(&label)
|
||||
|
||||
// Get tags
|
||||
rows, _ := s.db.Query(ctx,
|
||||
`SELECT tag FROM address_tags WHERE chain_id = $1 AND address = $2`,
|
||||
rows, err := s.db.Query(ctx,
|
||||
`SELECT tag FROM address_tags WHERE chain_id = $1 AND LOWER(address) = $2`,
|
||||
s.chainID, address,
|
||||
)
|
||||
defer rows.Close()
|
||||
|
||||
tags := []string{}
|
||||
for rows.Next() {
|
||||
var tag string
|
||||
if err := rows.Scan(&tag); err == nil {
|
||||
tags = append(tags, tag)
|
||||
if err == nil {
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
var tag string
|
||||
if err := rows.Scan(&tag); err == nil {
|
||||
tags = append(tags, tag)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check if contract
|
||||
var isContract bool
|
||||
s.db.QueryRow(ctx,
|
||||
`SELECT EXISTS(SELECT 1 FROM contracts WHERE chain_id = $1 AND address = $2)`,
|
||||
`SELECT EXISTS(SELECT 1 FROM contracts WHERE chain_id = $1 AND LOWER(address) = $2)`,
|
||||
s.chainID, address,
|
||||
).Scan(&isContract)
|
||||
|
||||
// Get balance (if we have RPC access, otherwise 0)
|
||||
balance := "0"
|
||||
// TODO: Add RPC call to get balance if needed
|
||||
|
||||
response := map[string]interface{}{
|
||||
"address": address,
|
||||
"chain_id": s.chainID,
|
||||
"balance": balance,
|
||||
"transaction_count": txCount,
|
||||
"token_count": tokenCount,
|
||||
"is_contract": isContract,
|
||||
"tags": tags,
|
||||
"address": address,
|
||||
"chain_id": s.chainID,
|
||||
"balance": nil,
|
||||
"balance_unavailable": true,
|
||||
"transaction_count": txCount,
|
||||
"token_count": tokenCount,
|
||||
"is_contract": isContract,
|
||||
"tags": tags,
|
||||
}
|
||||
|
||||
if label.Valid {
|
||||
|
||||
Reference in New Issue
Block a user