Add support for Sui in the `tx-tracker` service (#416)
### Description This pull request modifies the `tx-tracker` service to support the Sui blockchain. In particular, this will make the Sui sender addresses available for the Wormhole Scan UI.
This commit is contained in:
parent
97946d5a56
commit
bf3be056b4
|
@ -67,6 +67,10 @@ spec:
|
|||
value: {{ .SOLANA_BASE_URL }}
|
||||
- name: SOLANA_REQUESTS_PER_MINUTE
|
||||
value: "{{ .SOLANA_REQUESTS_PER_MINUTE }}"
|
||||
- name: SUI_BASE_URL
|
||||
value: {{ .SUI_BASE_URL }}
|
||||
- name: SUI_REQUESTS_PER_MINUTE
|
||||
value: "{{ .SUI_REQUESTS_PER_MINUTE }}"
|
||||
- name: NUM_WORKERS
|
||||
value: "100"
|
||||
- name: BULK_SIZE
|
||||
|
|
|
@ -93,6 +93,10 @@ spec:
|
|||
value: {{ .SOLANA_BASE_URL }}
|
||||
- name: SOLANA_REQUESTS_PER_MINUTE
|
||||
value: "{{ .SOLANA_REQUESTS_PER_MINUTE }}"
|
||||
- name: SUI_BASE_URL
|
||||
value: {{ .SUI_BASE_URL }}
|
||||
- name: SUI_REQUESTS_PER_MINUTE
|
||||
value: "{{ .SUI_REQUESTS_PER_MINUTE }}"
|
||||
resources:
|
||||
limits:
|
||||
memory: {{ .RESOURCES_LIMITS_MEMORY }}
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
package chains
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
"github.com/wormhole-foundation/wormhole-explorer/txtracker/config"
|
||||
)
|
||||
|
||||
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,
|
||||
cfg *config.RpcProviderSettings,
|
||||
txHash string,
|
||||
) (*TxDetail, error) {
|
||||
|
||||
// Initialize RPC client
|
||||
client, err := rpc.DialContext(ctx, cfg.SuiBaseUrl)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to initialize RPC client: %w", err)
|
||||
}
|
||||
defer client.Close()
|
||||
|
||||
// Query transaction data
|
||||
var reply suiGetTransactionBlockResponse
|
||||
opts := suiGetTransactionBlockOpts{ShowInput: true}
|
||||
err = client.CallContext(ctx, &reply, "sui_getTransactionBlock", txHash, opts)
|
||||
if err != nil {
|
||||
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,
|
||||
Timestamp: time.UnixMilli(reply.TimestampMs),
|
||||
}
|
||||
return &txDetail, nil
|
||||
}
|
|
@ -39,6 +39,7 @@ var tickers = struct {
|
|||
optimism *time.Ticker
|
||||
polygon *time.Ticker
|
||||
solana *time.Ticker
|
||||
sui *time.Ticker
|
||||
}{}
|
||||
|
||||
func Initialize(cfg *config.RpcProviderSettings) {
|
||||
|
@ -52,6 +53,9 @@ func Initialize(cfg *config.RpcProviderSettings) {
|
|||
return time.Duration(roundedUp)
|
||||
}
|
||||
|
||||
// this adapter sends 1 request per txHash
|
||||
tickers.sui = time.NewTicker(f(cfg.SuiRequestsPerMinute))
|
||||
|
||||
// these adapters send 2 requests per txHash
|
||||
tickers.arbitrum = time.NewTicker(f(cfg.ArbitrumRequestsPerMinute / 2))
|
||||
tickers.avalanche = time.NewTicker(f(cfg.AvalancheRequestsPerMinute / 2))
|
||||
|
@ -119,6 +123,9 @@ func FetchTx(
|
|||
return fetchEthTx(ctx, txHash, cfg.AvalancheBaseUrl)
|
||||
}
|
||||
rateLimiter = *tickers.avalanche
|
||||
case vaa.ChainIDSui:
|
||||
fetchFunc = fetchSuiTx
|
||||
rateLimiter = *tickers.sui
|
||||
default:
|
||||
return nil, ErrChainNotSupported
|
||||
}
|
||||
|
|
|
@ -77,6 +77,8 @@ type RpcProviderSettings struct {
|
|||
PolygonRequestsPerMinute uint16 `split_words:"true" required:"true"`
|
||||
SolanaBaseUrl string `split_words:"true" required:"true"`
|
||||
SolanaRequestsPerMinute uint16 `split_words:"true" required:"true"`
|
||||
SuiBaseUrl string `split_words:"true" required:"true"`
|
||||
SuiRequestsPerMinute uint16 `split_words:"true" required:"true"`
|
||||
}
|
||||
|
||||
func LoadFromEnv[T any]() (*T, error) {
|
||||
|
|
Loading…
Reference in New Issue