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 }