wormhole-explorer/tx-tracker/chains/api_sui.go

96 lines
2.3 KiB
Go
Raw Normal View History

package chains
import (
"context"
"fmt"
"strings"
"github.com/ethereum/go-ethereum/rpc"
"github.com/wormhole-foundation/wormhole-explorer/common/pool"
"github.com/wormhole-foundation/wormhole-explorer/txtracker/internal/metrics"
"go.uber.org/zap"
)
type suiGetTransactionBlockResponse struct {
Digest string `json:"digest"`
TimestampMs int64 `json:"timestampMs,string"`
Transaction struct {
Data struct {
Sender string `json:"sender"`
} `json:"data"`
} `json:"transaction"`
}
type suiGetTransactionBlockOpts struct {
ShowInput bool `json:"showInput"`
ShowRawInput bool `json:"showRawInput"`
ShowEffects bool `json:"showEffects"`
ShowEvents bool `json:"showEvents"`
ShowObjectChanges bool `json:"showObjectChanges"`
ShowBalanceChanges bool `json:"showBalanceChanges"`
}
func FetchSuiTx(
ctx context.Context,
pool *pool.Pool,
txHash string,
metrics metrics.Metrics,
logger *zap.Logger,
) (*TxDetail, error) {
// get rpc sorted by score and priority.
rpcs := pool.GetItems()
if len(rpcs) == 0 {
return nil, ErrChainNotSupported
}
var txDetail *TxDetail
var err error
for _, rpc := range rpcs {
// Wait for the RPC rate limiter
rpc.Wait(ctx)
txDetail, err = fetchSuiTx(ctx, rpc.Id, txHash)
if err != nil {
logger.Debug("Failed to fetch transaction from SUI node", zap.String("url", rpc.Id), zap.Error(err))
continue
}
return txDetail, nil
}
return txDetail, err
}
func fetchSuiTx(
ctx context.Context,
baseUrl string,
txHash string,
) (*TxDetail, error) {
// Initialize RPC client
client, err := rpc.DialContext(ctx, baseUrl)
if err != nil {
return nil, fmt.Errorf("failed to initialize RPC client: %w", err)
}
defer client.Close()
// Query transaction data
var reply suiGetTransactionBlockResponse
{
// Execute the remote procedure call
opts := suiGetTransactionBlockOpts{ShowInput: true}
err = client.CallContext(ctx, &reply, "sui_getTransactionBlock", txHash, opts)
if err != nil {
if strings.Contains(err.Error(), "Could not find the referenced transaction") {
return nil, ErrTransactionNotFound
}
return nil, fmt.Errorf("failed to get tx by hash: %w", err)
}
}
// Populate the response struct and return
txDetail := TxDetail{
NativeTxHash: reply.Digest,
From: reply.Transaction.Data.Sender,
}
return &txDetail, nil
}