114 lines
3.0 KiB
Go
114 lines
3.0 KiB
Go
package chains
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"time"
|
|
)
|
|
|
|
type cosmosRequest struct {
|
|
Jsonrpc string `json:"jsonrpc"`
|
|
ID int `json:"id"`
|
|
Method string `json:"method"`
|
|
Params struct {
|
|
Query string `json:"query"`
|
|
Page string `json:"page"`
|
|
} `json:"params"`
|
|
}
|
|
|
|
type cosmosTxSearchParams struct {
|
|
Sequence string
|
|
Timestamp string
|
|
SrcChannel string
|
|
DstChannel string
|
|
}
|
|
|
|
type cosmosTxSearchResponse struct {
|
|
Jsonrpc string `json:"jsonrpc"`
|
|
ID int `json:"id"`
|
|
Result struct {
|
|
Txs []struct {
|
|
Hash string `json:"hash"`
|
|
Height string `json:"height"`
|
|
Index int `json:"index"`
|
|
TxResult struct {
|
|
Code int `json:"code"`
|
|
Data string `json:"data"`
|
|
Log string `json:"log"`
|
|
Info string `json:"info"`
|
|
GasWanted string `json:"gas_wanted"`
|
|
GasUsed string `json:"gas_used"`
|
|
Events []struct {
|
|
Type string `json:"type"`
|
|
Attributes []struct {
|
|
Key string `json:"key"`
|
|
Value string `json:"value"`
|
|
Index bool `json:"index"`
|
|
} `json:"attributes"`
|
|
} `json:"events"`
|
|
Codespace string `json:"codespace"`
|
|
} `json:"tx_result"`
|
|
Tx string `json:"tx"`
|
|
} `json:"txs"`
|
|
TotalCount string `json:"total_count"`
|
|
} `json:"result"`
|
|
}
|
|
|
|
type cosmosEventResponse struct {
|
|
Type string `json:"type"`
|
|
Attributes []struct {
|
|
Key string `json:"key"`
|
|
Value string `json:"value"`
|
|
} `json:"attributes"`
|
|
}
|
|
|
|
type cosmosLogWrapperResponse struct {
|
|
Events []cosmosEventResponse `json:"events"`
|
|
}
|
|
|
|
type txSearchExtractor[T any] func(tx *cosmosTxSearchResponse, log []cosmosLogWrapperResponse) (T, error)
|
|
|
|
func fetchTxSearch[T any](ctx context.Context, baseUrl string, rl *time.Ticker, p *cosmosTxSearchParams, extractor txSearchExtractor[*T]) (*T, error) {
|
|
queryTemplate := `send_packet.packet_sequence='%s' AND send_packet.packet_timeout_timestamp='%s' AND send_packet.packet_src_channel='%s' AND send_packet.packet_dst_channel='%s'`
|
|
query := fmt.Sprintf(queryTemplate, p.Sequence, p.Timestamp, p.SrcChannel, p.DstChannel)
|
|
q := cosmosRequest{
|
|
Jsonrpc: "2.0",
|
|
ID: 1,
|
|
Method: "tx_search",
|
|
Params: struct {
|
|
Query string `json:"query"`
|
|
Page string `json:"page"`
|
|
}{
|
|
Query: query,
|
|
Page: "1",
|
|
},
|
|
}
|
|
response, err := httpPost(ctx, rl, baseUrl, q)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return parseTxSearchResponse[T](response, p, extractor)
|
|
}
|
|
|
|
func parseTxSearchResponse[T any](body []byte, p *cosmosTxSearchParams, extractor txSearchExtractor[*T]) (*T, error) {
|
|
var txSearchReponse cosmosTxSearchResponse
|
|
err := json.Unmarshal(body, &txSearchReponse)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if len(txSearchReponse.Result.Txs) == 0 {
|
|
return nil, fmt.Errorf("can not found hash for sequence %s, timestamp %s, srcChannel %s, dstChannel %s", p.Sequence, p.Timestamp, p.SrcChannel, p.DstChannel)
|
|
}
|
|
|
|
var log []cosmosLogWrapperResponse
|
|
err = json.Unmarshal([]byte(txSearchReponse.Result.Txs[0].TxResult.Log), &log)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return extractor(&txSearchReponse, log)
|
|
}
|