gitlab.com/flarenetwork/coreth@v0.1.1/plugin/evm/client.go (about)

     1  // (c) 2019-2020, Ava Labs, Inc. All rights reserved.
     2  // See the file LICENSE for licensing terms.
     3  
     4  package evm
     5  
     6  import (
     7  	"fmt"
     8  	"time"
     9  
    10  	"github.com/ava-labs/avalanchego/api"
    11  	"github.com/ava-labs/avalanchego/ids"
    12  	"github.com/ava-labs/avalanchego/utils/formatting"
    13  	cjson "github.com/ava-labs/avalanchego/utils/json"
    14  	"github.com/ava-labs/avalanchego/utils/rpc"
    15  )
    16  
    17  // Client ...
    18  type Client struct {
    19  	requester rpc.EndpointRequester
    20  }
    21  
    22  // NewClient returns a Client for interacting with EVM [chain]
    23  func NewClient(uri, chain string, requestTimeout time.Duration) *Client {
    24  	return &Client{
    25  		requester: rpc.NewEndpointRequester(uri, fmt.Sprintf("/ext/bc/%s/avax", chain), "avax", requestTimeout),
    26  	}
    27  }
    28  
    29  // NewCChainClient returns a Client for interacting with the C Chain
    30  func NewCChainClient(uri string, requestTimeout time.Duration) *Client {
    31  	return NewClient(uri, "C", requestTimeout)
    32  }
    33  
    34  // IssueTx issues a transaction to a node and returns the TxID
    35  func (c *Client) IssueTx(txBytes []byte) (ids.ID, error) {
    36  	res := &api.JSONTxID{}
    37  	txStr, err := formatting.EncodeWithChecksum(formatting.Hex, txBytes)
    38  	if err != nil {
    39  		return res.TxID, fmt.Errorf("problem hex encoding bytes: %w", err)
    40  	}
    41  	err = c.requester.SendRequest("issueTx", &api.FormattedTx{
    42  		Tx:       txStr,
    43  		Encoding: formatting.Hex,
    44  	}, res)
    45  	return res.TxID, err
    46  }
    47  
    48  // GetAtomicTxStatus returns the status of [txID]
    49  func (c *Client) GetAtomicTxStatus(txID ids.ID) (Status, error) {
    50  	res := &GetAtomicTxStatusReply{}
    51  	err := c.requester.SendRequest("getAtomicTxStatus", &api.JSONTxID{
    52  		TxID: txID,
    53  	}, res)
    54  	return res.Status, err
    55  }
    56  
    57  // GetAtomicTx returns the byte representation of [txID]
    58  func (c *Client) GetAtomicTx(txID ids.ID) ([]byte, error) {
    59  	res := &api.FormattedTx{}
    60  	err := c.requester.SendRequest("getAtomicTx", &api.GetTxArgs{
    61  		TxID:     txID,
    62  		Encoding: formatting.Hex,
    63  	}, res)
    64  	if err != nil {
    65  		return nil, err
    66  	}
    67  
    68  	return formatting.Decode(formatting.Hex, res.Tx)
    69  }
    70  
    71  // GetAtomicUTXOs returns the byte representation of the atomic UTXOs controlled by [addresses]
    72  // from [sourceChain]
    73  func (c *Client) GetAtomicUTXOs(addrs []string, sourceChain string, limit uint32, startAddress, startUTXOID string) ([][]byte, api.Index, error) {
    74  	res := &api.GetUTXOsReply{}
    75  	err := c.requester.SendRequest("getUTXOs", &api.GetUTXOsArgs{
    76  		Addresses:   addrs,
    77  		SourceChain: sourceChain,
    78  		Limit:       cjson.Uint32(limit),
    79  		StartIndex: api.Index{
    80  			Address: startAddress,
    81  			UTXO:    startUTXOID,
    82  		},
    83  		Encoding: formatting.Hex,
    84  	}, res)
    85  	if err != nil {
    86  		return nil, api.Index{}, err
    87  	}
    88  
    89  	utxos := make([][]byte, len(res.UTXOs))
    90  	for i, utxo := range res.UTXOs {
    91  		b, err := formatting.Decode(formatting.Hex, utxo)
    92  		if err != nil {
    93  			return nil, api.Index{}, err
    94  		}
    95  		utxos[i] = b
    96  	}
    97  	return utxos, res.EndIndex, nil
    98  }
    99  
   100  // ListAddresses returns all addresses on this chain controlled by [user]
   101  func (c *Client) ListAddresses(user api.UserPass) ([]string, error) {
   102  	res := &api.JSONAddresses{}
   103  	err := c.requester.SendRequest("listAddresses", &user, res)
   104  	return res.Addresses, err
   105  }
   106  
   107  // ExportKey returns the private key corresponding to [addr] controlled by [user]
   108  // in both Avalanche standard format and hex format
   109  func (c *Client) ExportKey(user api.UserPass, addr string) (string, string, error) {
   110  	res := &ExportKeyReply{}
   111  	err := c.requester.SendRequest("exportKey", &ExportKeyArgs{
   112  		UserPass: user,
   113  		Address:  addr,
   114  	}, res)
   115  	return res.PrivateKey, res.PrivateKeyHex, err
   116  }
   117  
   118  // ImportKey imports [privateKey] to [user]
   119  func (c *Client) ImportKey(user api.UserPass, privateKey string) (string, error) {
   120  	res := &api.JSONAddress{}
   121  	err := c.requester.SendRequest("importKey", &ImportKeyArgs{
   122  		UserPass:   user,
   123  		PrivateKey: privateKey,
   124  	}, res)
   125  	return res.Address, err
   126  }
   127  
   128  // Import sends an import transaction to import funds from [sourceChain] and
   129  // returns the ID of the newly created transaction
   130  func (c *Client) Import(user api.UserPass, to, sourceChain string) (ids.ID, error) {
   131  	res := &api.JSONTxID{}
   132  	err := c.requester.SendRequest("import", &ImportArgs{
   133  		UserPass:    user,
   134  		To:          to,
   135  		SourceChain: sourceChain,
   136  	}, res)
   137  	return res.TxID, err
   138  }
   139  
   140  // ExportAVAX sends AVAX from this chain to the address specified by [to].
   141  // Returns the ID of the newly created atomic transaction
   142  func (c *Client) ExportAVAX(
   143  	user api.UserPass,
   144  	amount uint64,
   145  	to string,
   146  ) (ids.ID, error) {
   147  	return c.Export(user, amount, to, "AVAX")
   148  }
   149  
   150  // Export sends an asset from this chain to the P/C-Chain.
   151  // After this tx is accepted, the AVAX must be imported to the P/C-chain with an importTx.
   152  // Returns the ID of the newly created atomic transaction
   153  func (c *Client) Export(
   154  	user api.UserPass,
   155  	amount uint64,
   156  	to string,
   157  	assetID string,
   158  ) (ids.ID, error) {
   159  	res := &api.JSONTxID{}
   160  	err := c.requester.SendRequest("export", &ExportArgs{
   161  		ExportAVAXArgs: ExportAVAXArgs{
   162  			UserPass: user,
   163  			Amount:   cjson.Uint64(amount),
   164  			To:       to,
   165  		},
   166  		AssetID: assetID,
   167  	}, res)
   168  	return res.TxID, err
   169  }