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) }