github.com/wormhole-foundation/wormhole-explorer/common@v0.0.0-20240604151348-09585b5b97c5/client/txtracker/txtracker.go (about)

     1  package txtracker
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"errors"
     7  	"fmt"
     8  	"net/http"
     9  	"time"
    10  
    11  	"go.uber.org/zap"
    12  )
    13  
    14  const DefaultTimeout = 30
    15  
    16  var (
    17  	ErrCallEndpoint  = errors.New("ERROR CALL ENPOINT")
    18  	ErrBadRequest    = errors.New("BAD REQUEST")
    19  	ErrInternalError = errors.New("INTERNAL ERROR")
    20  )
    21  
    22  // TxTrackerAPIClient tx tracker api client.
    23  type TxTrackerAPIClient struct {
    24  	Client  http.Client
    25  	BaseURL string
    26  	Logger  *zap.Logger
    27  }
    28  
    29  // NewTxTrackerAPIClient create new instances of TxTrackerAPIClient.
    30  func NewTxTrackerAPIClient(timeout int64, baseURL string, logger *zap.Logger) (TxTrackerAPIClient, error) {
    31  	if timeout == 0 {
    32  		timeout = DefaultTimeout
    33  	}
    34  	if baseURL == "" {
    35  		return TxTrackerAPIClient{}, errors.New("baseURL can not be empty")
    36  	}
    37  
    38  	return TxTrackerAPIClient{
    39  		Client: http.Client{
    40  			Timeout: time.Duration(timeout) * time.Second,
    41  		},
    42  		BaseURL: baseURL,
    43  		Logger:  logger,
    44  	}, nil
    45  }
    46  
    47  // ProcessVaaResponse represent a process vaa response.
    48  type ProcessVaaResponse struct {
    49  	From         string `json:"from"`
    50  	NativeTxHash string `json:"nativeTxHash"`
    51  	Attributes   any    `json:"attributes"`
    52  }
    53  
    54  // Process process vaa.
    55  func (c *TxTrackerAPIClient) Process(vaaID string) (*ProcessVaaResponse, error) {
    56  	endpointUrl := fmt.Sprintf("%s/vaa/process", c.BaseURL)
    57  
    58  	// create request body.
    59  	payload := struct {
    60  		VaaID string `json:"id"`
    61  	}{
    62  		VaaID: vaaID,
    63  	}
    64  
    65  	body, err := json.Marshal(payload)
    66  	if err != nil {
    67  		c.Logger.Error("error marshalling payload", zap.Error(err), zap.String("vaaID", vaaID))
    68  		return nil, err
    69  	}
    70  
    71  	response, err := c.Client.Post(endpointUrl, "application/json", bytes.NewBuffer(body))
    72  	if err != nil {
    73  		c.Logger.Error("error call parse vaa endpoint", zap.Error(err), zap.String("vaaID", vaaID))
    74  		return nil, ErrCallEndpoint
    75  	}
    76  	defer response.Body.Close()
    77  	switch response.StatusCode {
    78  	case http.StatusOK:
    79  		var processVaaResponse ProcessVaaResponse
    80  		json.NewDecoder(response.Body).Decode(&processVaaResponse)
    81  		return &processVaaResponse, nil
    82  	case http.StatusInternalServerError:
    83  		return nil, ErrInternalError
    84  	default:
    85  		return nil, ErrInternalError
    86  	}
    87  }
    88  
    89  // CreateTxHashFunc represent a create tx hash function.
    90  type CreateTxHashFunc func(vaaID, txHash string) (*TxHashResponse, error)
    91  
    92  // TxHashResponse represent a create tx hash response.
    93  type TxHashResponse struct {
    94  	NativeTxHash string `json:"nativeTxHash"`
    95  }
    96  
    97  // CreateTxHash create tx hash.
    98  func (c *TxTrackerAPIClient) CreateTxHash(vaaID, txHash string) (*TxHashResponse, error) {
    99  	endpoint := fmt.Sprintf("%s/vaa/tx-hash", c.BaseURL)
   100  
   101  	// create request body.
   102  	payload := struct {
   103  		VaaID  string `json:"id"`
   104  		TxHash string `json:"txHash"`
   105  	}{
   106  		VaaID:  vaaID,
   107  		TxHash: txHash,
   108  	}
   109  
   110  	body, err := json.Marshal(payload)
   111  	if err != nil {
   112  		c.Logger.Error("error marshalling payload", zap.Error(err), zap.String("vaaID", vaaID), zap.String("txHash", txHash))
   113  		return nil, err
   114  	}
   115  
   116  	response, err := c.Client.Post(endpoint, "application/json", bytes.NewBuffer(body))
   117  	if err != nil {
   118  		c.Logger.Error("error call create tx hash endpoint",
   119  			zap.Error(err),
   120  			zap.String("vaaID", vaaID),
   121  			zap.String("txHash", txHash))
   122  		return nil, ErrCallEndpoint
   123  	}
   124  
   125  	defer response.Body.Close()
   126  	switch response.StatusCode {
   127  	case http.StatusOK:
   128  		var txHashResponse TxHashResponse
   129  		json.NewDecoder(response.Body).Decode(&txHashResponse)
   130  		return &txHashResponse, nil
   131  	case http.StatusBadRequest:
   132  		return nil, ErrBadRequest
   133  	case http.StatusInternalServerError:
   134  		return nil, ErrInternalError
   135  	default:
   136  		return nil, ErrInternalError
   137  	}
   138  
   139  }