You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
276 lines
5.9 KiB
276 lines
5.9 KiB
2 months ago
|
package grpc
|
||
|
|
||
|
import (
|
||
|
"encoding/json"
|
||
|
"errors"
|
||
|
"fmt"
|
||
|
"github.com/fbsobreira/gotron-sdk/pkg/address"
|
||
|
"github.com/fbsobreira/gotron-sdk/pkg/client"
|
||
|
"github.com/fbsobreira/gotron-sdk/pkg/proto/api"
|
||
|
"github.com/fbsobreira/gotron-sdk/pkg/proto/core"
|
||
|
"google.golang.org/grpc"
|
||
|
"math/big"
|
||
|
"strings"
|
||
|
"time"
|
||
|
"wallet-system/internal/pkg/logging/applogger"
|
||
|
)
|
||
|
|
||
|
type Client struct {
|
||
|
node string
|
||
|
GRPC *client.GrpcClient
|
||
|
}
|
||
|
|
||
|
// NewClient
|
||
|
//
|
||
|
// @Description:
|
||
|
// @param node
|
||
|
// @return *Client
|
||
|
// @return error
|
||
|
func NewClient(node string) (*Client, error) {
|
||
|
c := new(Client)
|
||
|
c.node = node
|
||
|
c.GRPC = client.NewGrpcClient(node)
|
||
|
|
||
|
err := c.GRPC.Start(grpc.WithInsecure())
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("grpc client start error:%v", err)
|
||
|
}
|
||
|
return c, nil
|
||
|
}
|
||
|
|
||
|
// SetTimeout
|
||
|
//
|
||
|
// @Description:
|
||
|
// @receiver c
|
||
|
// @param timeout
|
||
|
// @return error
|
||
|
func (c *Client) SetTimeout(timeout time.Duration) error {
|
||
|
if c == nil {
|
||
|
return errors.New("client is nil ptr")
|
||
|
}
|
||
|
c.GRPC = client.NewGrpcClientWithTimeout(c.node, timeout)
|
||
|
err := c.GRPC.Start()
|
||
|
if err != nil {
|
||
|
return fmt.Errorf("grpc start error: %v", err)
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// keepConnect
|
||
|
//
|
||
|
// @Description:
|
||
|
// @receiver c
|
||
|
// @return error
|
||
|
func (c *Client) keepConnect() error {
|
||
|
_, err := c.GRPC.GetNodeInfo()
|
||
|
if err != nil {
|
||
|
if strings.Contains(err.Error(), "no such host") {
|
||
|
return c.GRPC.Reconnect(c.node)
|
||
|
}
|
||
|
return fmt.Errorf("node connect error: %v", err)
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// Transfer
|
||
|
//
|
||
|
// @Description:
|
||
|
// @receiver c
|
||
|
// @param from
|
||
|
// @param to
|
||
|
// @param amount
|
||
|
// @return *api.TransactionExtention
|
||
|
// @return error
|
||
|
func (c *Client) Transfer(from, to string, amount int64) (*api.TransactionExtention, error) {
|
||
|
err := c.keepConnect()
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
return c.GRPC.Transfer(from, to, amount)
|
||
|
}
|
||
|
|
||
|
// GetTrc10Balance
|
||
|
//
|
||
|
// @Description:
|
||
|
// @receiver c
|
||
|
// @param addr
|
||
|
// @param assetId
|
||
|
// @return int64
|
||
|
// @return error
|
||
|
func (c *Client) GetTrc10Balance(addr, assetId string) (int64, error) {
|
||
|
err := c.keepConnect()
|
||
|
if err != nil {
|
||
|
return 0, err
|
||
|
}
|
||
|
acc, err := c.GRPC.GetAccount(addr)
|
||
|
if err != nil || acc == nil {
|
||
|
return 0, fmt.Errorf("get %s account error:%v", addr, err)
|
||
|
}
|
||
|
for key, value := range acc.AssetV2 {
|
||
|
if key == assetId {
|
||
|
return value, nil
|
||
|
}
|
||
|
}
|
||
|
return 0, fmt.Errorf("%s do not find this assetID=%s amount", addr, assetId)
|
||
|
}
|
||
|
|
||
|
// GetTrxBalance
|
||
|
//
|
||
|
// @Description:
|
||
|
// @receiver c
|
||
|
// @param addr
|
||
|
// @return *core.Account
|
||
|
// @return error
|
||
|
func (c *Client) GetTrxBalance(addr string) (*core.Account, error) {
|
||
|
err := c.keepConnect()
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
return c.GRPC.GetAccount(addr)
|
||
|
}
|
||
|
|
||
|
// GetTrc20Balance
|
||
|
//
|
||
|
// @Description:
|
||
|
// @receiver c
|
||
|
// @param addr
|
||
|
// @param contractAddress
|
||
|
// @return *big.Int
|
||
|
// @return error
|
||
|
func (c *Client) GetTrc20Balance(addr, contractAddress string) (*big.Int, error) {
|
||
|
err := c.keepConnect()
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
return c.GRPC.TRC20ContractBalance(addr, contractAddress)
|
||
|
}
|
||
|
|
||
|
// TransferTrc10
|
||
|
//
|
||
|
// @Description:
|
||
|
// @receiver c
|
||
|
// @param from
|
||
|
// @param to
|
||
|
// @param assetId
|
||
|
// @param amount
|
||
|
// @return *api.TransactionExtention
|
||
|
// @return error
|
||
|
func (c *Client) TransferTrc10(from, to, assetId string, amount int64) (*api.TransactionExtention, error) {
|
||
|
err := c.keepConnect()
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
fromAddr, err := address.Base58ToAddress(from)
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("from address is not equal")
|
||
|
}
|
||
|
toAddr, err := address.Base58ToAddress(to)
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("to address is not equal")
|
||
|
}
|
||
|
return c.GRPC.TransferAsset(fromAddr.String(), toAddr.String(), assetId, amount)
|
||
|
}
|
||
|
|
||
|
// TransferTrc20
|
||
|
//
|
||
|
// @Description:
|
||
|
// @receiver c
|
||
|
// @param from
|
||
|
// @param to
|
||
|
// @param contract
|
||
|
// @param amount
|
||
|
// @param feeLimit
|
||
|
// @return *api.TransactionExtention
|
||
|
// @return error
|
||
|
func (c *Client) TransferTrc20(from, to, contract string, amount *big.Int, feeLimit int64) (*api.TransactionExtention, error) {
|
||
|
err := c.keepConnect()
|
||
|
if err != nil {
|
||
|
applogger.Error("link failure:%v", err)
|
||
|
return nil, err
|
||
|
}
|
||
|
return c.GRPC.TRC20Send(from, to, contract, amount, feeLimit)
|
||
|
}
|
||
|
|
||
|
// BroadcastTransaction
|
||
|
//
|
||
|
// @Description:
|
||
|
// @receiver c
|
||
|
// @param transaction
|
||
|
// @return error
|
||
|
func (c *Client) BroadcastTransaction(transaction *core.Transaction) error {
|
||
|
err := c.keepConnect()
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
result, err := c.GRPC.Broadcast(transaction)
|
||
|
if err != nil {
|
||
|
return fmt.Errorf("broadcast transaction error:%v", err)
|
||
|
}
|
||
|
if result.Code != 0 {
|
||
|
return fmt.Errorf("bad transaction:%v", string(result.GetMessage()))
|
||
|
}
|
||
|
if result.Result == true {
|
||
|
return nil
|
||
|
}
|
||
|
d, _ := json.Marshal(result)
|
||
|
return fmt.Errorf("tx send fail:%s", string(d))
|
||
|
}
|
||
|
|
||
|
// TRC20Approve
|
||
|
//
|
||
|
// @Description:
|
||
|
// @receiver c
|
||
|
// @param from
|
||
|
// @param to
|
||
|
// @param contract
|
||
|
// @param amount
|
||
|
// @param feeLimit
|
||
|
// @return *api.TransactionExtention
|
||
|
// @return error
|
||
|
func (c *Client) TRC20Approve(from, to, contract string, amount *big.Int, feeLimit int64) (*api.TransactionExtention, error) {
|
||
|
err := c.keepConnect()
|
||
|
if err != nil {
|
||
|
applogger.Error("link failure:%v", err)
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
return c.GRPC.TRC20Approve(from, to, contract, amount, feeLimit)
|
||
|
}
|
||
|
|
||
|
// GetContractABI .
|
||
|
//
|
||
|
// @Description:
|
||
|
// @receiver c
|
||
|
// @param contractAddress
|
||
|
// @return *core.SmartContract_ABI
|
||
|
// @return error
|
||
|
func (c *Client) GetContractABI(contractAddress string) (*core.SmartContract_ABI, error) {
|
||
|
err := c.keepConnect()
|
||
|
if err != nil {
|
||
|
applogger.Error("link failure:%v", err)
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
return c.GRPC.GetContractABI(contractAddress)
|
||
|
}
|
||
|
|
||
|
// TransferAsset from to base58 address
|
||
|
//
|
||
|
// @Description:
|
||
|
// @receiver c
|
||
|
// @param from
|
||
|
// @param toAddress
|
||
|
// @param assetName
|
||
|
// @param amount
|
||
|
// @return *api.TransactionExtention
|
||
|
// @return error
|
||
|
func (c *Client) TransferAsset(from, toAddress, assetName string, amount int64) (*api.TransactionExtention, error) {
|
||
|
err := c.keepConnect()
|
||
|
if err != nil {
|
||
|
applogger.Error("link failure:%v", err)
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
return c.GRPC.TransferAsset(from, toAddress, assetName, amount)
|
||
|
}
|