Files
zeekayandHanzo Dev 64519916bf the corporate name is Lux Industries Inc
Lux Partners Limited is not the entity behind this work. Every place the
old name stood — copyright lines, site footers, brand config, legal and
compliance text — now names the company that actually holds it.

lux.fund is the exception and is not renamed to match: that site belongs
to Lux Assets Management LLC, a different company, and it says so.

Two kinds of line were left for a person rather than rewritten. A dated
news item recording that Lux Partners Limited was established in the Isle
of Man is a historical fact, and renaming it would falsify the record. And
a sentence asserting that the company is domiciled in the Isle of Man is a
claim about a jurisdiction, not a name — an Inc or an LLC is not an Isle
of Man company, so swapping the name there would assert something untrue.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-28 13:01:04 -07:00

406 lines
17 KiB
Go

// Copyright (c) 2025 Lux Industries Inc
// SPDX-License-Identifier: MIT
// Package api provides REST, RPC, GraphQL, and WebSocket APIs for the EVM indexer.
// API design follows the explorer v2 format for frontend compatibility.
package api
import (
"encoding/json"
"math/big"
"time"
)
// Pagination parameters
type Pagination struct {
Page int `json:"page"`
PageSize int `json:"page_size"`
TotalRows int `json:"total_rows"`
}
// NextPageParams for cursor-based pagination
type NextPageParams struct {
BlockNumber *uint64 `json:"block_number,omitempty"`
Index *int `json:"index,omitempty"`
ItemsCount int `json:"items_count,omitempty"`
TransactionIndex *int `json:"transaction_index,omitempty"`
Hash string `json:"hash,omitempty"`
}
// PaginatedResponse wraps items with pagination info
type PaginatedResponse struct {
Items interface{} `json:"items"`
NextPageParams *NextPageParams `json:"next_page_params,omitempty"`
}
// Block represents a block in explorer v2 format
type Block struct {
Height uint64 `json:"height"`
Hash string `json:"hash"`
ParentHash string `json:"parent_hash"`
Timestamp time.Time `json:"timestamp"`
TransactionCount int `json:"tx_count"`
GasUsed string `json:"gas_used"`
GasLimit string `json:"gas_limit"`
BaseFeePerGas string `json:"base_fee_per_gas,omitempty"`
BurntFees string `json:"burnt_fees,omitempty"`
Priority string `json:"priority_fee,omitempty"`
Size uint64 `json:"size"`
Miner *Address `json:"miner"`
Nonce string `json:"nonce,omitempty"`
Difficulty string `json:"difficulty,omitempty"`
TotalDifficulty string `json:"total_difficulty,omitempty"`
StateRoot string `json:"state_root,omitempty"`
TransactionsRoot string `json:"transactions_root,omitempty"`
ReceiptsRoot string `json:"receipts_root,omitempty"`
Withdrawals []Withdrawal `json:"withdrawals,omitempty"`
Rewards []BlockReward `json:"rewards,omitempty"`
Type string `json:"type"` // block, reorg, uncle
Confirmations int `json:"confirmations,omitempty"`
InternalTxsIndexed bool `json:"has_internal_transactions"`
TokenTransferCount int `json:"token_transfer_count,omitempty"`
}
// Withdrawal represents a beacon chain withdrawal
type Withdrawal struct {
Index uint64 `json:"index"`
ValidatorIndex uint64 `json:"validator_index"`
Address *Address `json:"address"`
Amount string `json:"amount"`
}
// BlockReward represents a block reward
type BlockReward struct {
Type string `json:"type"` // block, uncle, emission
Address *Address `json:"address"`
Amount string `json:"amount"`
}
// Transaction in explorer v2 format
type Transaction struct {
Hash string `json:"hash"`
BlockHash string `json:"block_hash,omitempty"`
BlockNumber *uint64 `json:"block_number,omitempty"`
Timestamp *time.Time `json:"timestamp,omitempty"`
Confirmations int `json:"confirmations,omitempty"`
From *Address `json:"from"`
To *Address `json:"to,omitempty"`
CreatedContract *Address `json:"created_contract,omitempty"`
Value string `json:"value"`
Gas uint64 `json:"gas_limit"`
GasPrice string `json:"gas_price"`
GasUsed *uint64 `json:"gas_used,omitempty"`
MaxFeePerGas string `json:"max_fee_per_gas,omitempty"`
MaxPriorityFee string `json:"max_priority_fee_per_gas,omitempty"`
BaseFee string `json:"base_fee_per_gas,omitempty"`
TransactionFee string `json:"fee,omitempty"`
BurntFee string `json:"tx_burnt_fee,omitempty"`
Nonce uint64 `json:"nonce"`
Position *int `json:"position,omitempty"`
TransactionIndex *int `json:"transaction_index,omitempty"`
Input string `json:"raw_input"`
DecodedInput *DecodedInput `json:"decoded_input,omitempty"`
Type int `json:"type"`
Status string `json:"status,omitempty"` // ok, error, pending
Result string `json:"result,omitempty"` // success, revert, out of gas
RevertReason string `json:"revert_reason,omitempty"`
Method string `json:"method,omitempty"`
TokenTransfers []TokenTransfer `json:"token_transfers,omitempty"`
TokenTransferCount int `json:"token_transfers_count,omitempty"`
InternalTxsCount int `json:"internal_txs_count,omitempty"`
ExchangeRate string `json:"exchange_rate,omitempty"`
Actions []TxAction `json:"actions,omitempty"`
HasErrorInternalTxs bool `json:"has_error_in_internal_txs"`
}
// DecodedInput represents decoded function call
type DecodedInput struct {
MethodID string `json:"method_id"`
MethodCall string `json:"method_call"`
Parameters []DecodedParam `json:"parameters,omitempty"`
}
// DecodedParam represents a decoded parameter
type DecodedParam struct {
Name string `json:"name"`
Type string `json:"type"`
Value interface{} `json:"value"`
}
// TxAction represents a transaction action (swap, bridge, etc.)
type TxAction struct {
Protocol string `json:"protocol"`
Type string `json:"type"`
Data map[string]interface{} `json:"data"`
}
// Address in explorer v2 format
type Address struct {
Hash string `json:"hash"`
Name string `json:"name,omitempty"`
ENS string `json:"ens_domain_name,omitempty"`
IsContract bool `json:"is_contract"`
IsVerified bool `json:"is_verified,omitempty"`
IsScam bool `json:"is_scam,omitempty"`
IsProxy bool `json:"is_proxy,omitempty"`
Implementation *Address `json:"implementation,omitempty"`
ImplementationName string `json:"implementation_name,omitempty"`
Balance string `json:"coin_balance,omitempty"`
FetchedCoinBalance string `json:"fetched_coin_balance,omitempty"`
TransactionCount *uint64 `json:"tx_count,omitempty"`
TokenBalance string `json:"token_balance,omitempty"`
TokenCount *int `json:"token_count,omitempty"`
GasUsed *uint64 `json:"gas_used,omitempty"`
BlockNumberCreated *uint64 `json:"block_number_balance_updated_at,omitempty"`
Creator *Address `json:"creator_address,omitempty"`
CreationTxHash string `json:"creation_tx_hash,omitempty"`
Token *Token `json:"token,omitempty"`
HasDecompiledCode bool `json:"has_decompiled_code,omitempty"`
HasValidatedBlocks bool `json:"has_validated_blocks,omitempty"`
HasLogs bool `json:"has_logs,omitempty"`
HasTokenTransfers bool `json:"has_token_transfers,omitempty"`
WatchlistNames []WatchlistName `json:"watchlist_names,omitempty"`
PrivateTags []AddressTag `json:"private_tags,omitempty"`
PublicTags []AddressTag `json:"public_tags,omitempty"`
}
// WatchlistName for user's address labels
type WatchlistName struct {
Label string `json:"label"`
DisplayName string `json:"display_name"`
}
// AddressTag for public/private tagging
type AddressTag struct {
Label string `json:"label"`
DisplayName string `json:"display_name"`
Type string `json:"address_tag,omitempty"`
URL string `json:"url,omitempty"`
}
// Token in explorer v2 format
type Token struct {
Address string `json:"address"`
Name string `json:"name"`
Symbol string `json:"symbol"`
Decimals *uint8 `json:"decimals,omitempty"`
TotalSupply string `json:"total_supply,omitempty"`
CirculatingCap string `json:"circulating_market_cap,omitempty"`
Type string `json:"type"` // ERC-20, ERC-721, ERC-1155
HolderCount *uint64 `json:"holders,omitempty"`
TransferCount *uint64 `json:"transfers_count,omitempty"`
ExchangeRate string `json:"exchange_rate,omitempty"`
IconURL string `json:"icon_url,omitempty"`
Volume24h string `json:"volume_24h,omitempty"`
IsVerified bool `json:"is_verified_via_admin_panel,omitempty"`
}
// TokenBalance for address token holdings
type TokenBalance struct {
Token *Token `json:"token"`
TokenID string `json:"token_id,omitempty"`
Value string `json:"value"`
TokenInstance *NFT `json:"token_instance,omitempty"`
}
// TokenTransfer in explorer v2 format
type TokenTransfer struct {
TxHash string `json:"tx_hash"`
BlockHash string `json:"block_hash,omitempty"`
BlockNumber uint64 `json:"block_number"`
LogIndex int `json:"log_index"`
Timestamp *time.Time `json:"timestamp,omitempty"`
From *Address `json:"from"`
To *Address `json:"to"`
Token *Token `json:"token"`
TokenID string `json:"token_id,omitempty"`
Total *TokenTotal `json:"total,omitempty"`
TokenIDs []string `json:"token_ids,omitempty"` // ERC-1155 batch
Amounts []string `json:"amounts,omitempty"` // ERC-1155 batch
Type string `json:"type,omitempty"` // token_minting, token_burning, token_transfer
Method string `json:"method,omitempty"`
}
// TokenTotal for transfer value/tokenId
type TokenTotal struct {
Value string `json:"value,omitempty"`
Decimals *uint8 `json:"decimals,omitempty"`
TokenID string `json:"token_id,omitempty"`
}
// InternalTransaction for traces
type InternalTransaction struct {
TxHash string `json:"transaction_hash"`
BlockNumber uint64 `json:"block_number"`
BlockHash string `json:"block_hash,omitempty"`
Index int `json:"index"`
Timestamp *time.Time `json:"timestamp,omitempty"`
Type string `json:"type"` // call, create, suicide, reward
CallType string `json:"call_type,omitempty"` // call, delegatecall, staticcall
From *Address `json:"from"`
To *Address `json:"to,omitempty"`
Value string `json:"value"`
Gas uint64 `json:"gas_limit"`
GasUsed *uint64 `json:"gas_used,omitempty"`
Input string `json:"input,omitempty"`
Output string `json:"output,omitempty"`
Error string `json:"error,omitempty"`
Success *bool `json:"success"` // nil = pending, true/false = finalized
Created *Address `json:"created_contract,omitempty"`
}
// Log represents an event log
type Log struct {
TxHash string `json:"tx_hash"`
BlockNumber uint64 `json:"block_number"`
BlockHash string `json:"block_hash"`
Index int `json:"index"`
Address *Address `json:"address"`
Data string `json:"data"`
Topics []string `json:"topics"`
Decoded *DecodedLog `json:"decoded,omitempty"`
}
// DecodedLog represents a decoded event
type DecodedLog struct {
MethodID string `json:"method_id"`
MethodCall string `json:"method_call"`
Parameters []DecodedParam `json:"parameters,omitempty"`
}
// SmartContract in explorer v2 format
type SmartContract struct {
Address string `json:"address_hash"`
Name string `json:"name,omitempty"`
CompilerVersion string `json:"compiler_version,omitempty"`
OptimizationEnabled bool `json:"optimization_enabled"`
OptimizationRuns int `json:"optimization_runs,omitempty"`
EVMVersion string `json:"evm_version,omitempty"`
SourceCode string `json:"source_code,omitempty"`
ABI json.RawMessage `json:"abi,omitempty"`
ConstructorArgs string `json:"constructor_arguments,omitempty"`
DecodedConstructorArgs []DecodedParam `json:"decoded_constructor_arguments,omitempty"`
IsVerified bool `json:"is_verified"`
VerifiedAt *time.Time `json:"verified_at,omitempty"`
IsProxy bool `json:"is_proxy"`
ProxyType string `json:"proxy_type,omitempty"`
Implementations []Implementation `json:"implementations,omitempty"`
ContractSourceCode []SourceFile `json:"contract_source_code,omitempty"`
ExternalLibraries []Library `json:"external_libraries,omitempty"`
Language string `json:"language,omitempty"` // solidity, vyper
LicenseType string `json:"license_type,omitempty"`
IsFullMatch bool `json:"is_fully_verified"`
IsPartialMatch bool `json:"is_partially_verified,omitempty"`
}
// Implementation for proxy contracts
type Implementation struct {
Address string `json:"address"`
Name string `json:"name,omitempty"`
}
// SourceFile for multi-file contracts
type SourceFile struct {
FileName string `json:"file_name"`
SourceCode string `json:"source_code"`
}
// Library for external libraries
type Library struct {
Name string `json:"name"`
Address string `json:"address_hash"`
}
// NFT represents an NFT instance
type NFT struct {
ID string `json:"id"`
Token *Token `json:"token"`
Metadata map[string]interface{} `json:"metadata,omitempty"`
Owner *Address `json:"owner,omitempty"`
IsUnique bool `json:"is_unique,omitempty"`
ImageURL string `json:"image_url,omitempty"`
AnimationURL string `json:"animation_url,omitempty"`
ExternalURL string `json:"external_app_url,omitempty"`
}
// ChainStats for /v1/explorer/stats
type ChainStats struct {
TotalBlocks int64 `json:"total_blocks"`
TotalTransactions int64 `json:"total_transactions"`
TotalAddresses int64 `json:"total_addresses"`
TotalContracts int64 `json:"total_contracts,omitempty"`
TotalTokens int64 `json:"total_tokens,omitempty"`
TotalTokenTransfers int64 `json:"total_token_transfers,omitempty"`
AverageBlockTime float64 `json:"average_block_time"`
CoinPrice string `json:"coin_price,omitempty"`
CoinPriceChange float64 `json:"coin_price_change_percentage,omitempty"`
TotalGasUsed string `json:"total_gas_used,omitempty"`
GasPrice string `json:"gas_prices,omitempty"`
NetworkUtilization float64 `json:"network_utilization_percentage,omitempty"`
TxnsToday int64 `json:"transactions_today,omitempty"`
MarketCap string `json:"market_cap,omitempty"`
TVL string `json:"tvl,omitempty"`
}
// GasPrice information
type GasPrice struct {
Slow GasPriceTier `json:"slow"`
Average GasPriceTier `json:"average"`
Fast GasPriceTier `json:"fast"`
}
// GasPriceTier for gas estimates
type GasPriceTier struct {
Price string `json:"price"`
FiatPrice string `json:"fiat_price,omitempty"`
BaseFee string `json:"base_fee,omitempty"`
Priority string `json:"priority_fee,omitempty"`
Time float64 `json:"time,omitempty"` // estimated seconds
}
// SearchResult for universal search
type SearchResult struct {
Type string `json:"type"` // address, contract, token, transaction, block, ens
Address string `json:"address,omitempty"`
Hash string `json:"hash,omitempty"`
BlockNumber *uint64 `json:"block_number,omitempty"`
Name string `json:"name,omitempty"`
Symbol string `json:"symbol,omitempty"`
TokenType string `json:"token_type,omitempty"`
ExchangeRate string `json:"exchange_rate,omitempty"`
IsSmartContract bool `json:"is_smart_contract_verified,omitempty"`
URL string `json:"url,omitempty"`
Priority int `json:"priority,omitempty"`
}
// Error response format
type ErrorResponse struct {
Error string `json:"error,omitempty"`
Message string `json:"message,omitempty"`
}
// Helper for big.Int JSON handling
type BigInt big.Int
func (b *BigInt) String() string {
if b == nil {
return "0"
}
return (*big.Int)(b).String()
}
func (b *BigInt) MarshalJSON() ([]byte, error) {
return json.Marshal(b.String())
}
func (b *BigInt) UnmarshalJSON(data []byte) error {
var s string
if err := json.Unmarshal(data, &s); err != nil {
return err
}
bi := new(big.Int)
bi.SetString(s, 10)
*b = BigInt(*bi)
return nil
}