From d2c12352e9bd64ff6aa97b9192e3f2719871f233 Mon Sep 17 00:00:00 2001 From: Aaron Buchwald Date: Sat, 26 Dec 2020 16:36:58 -0500 Subject: [PATCH 1/2] Add confirmTx method to avm client --- vms/avm/client.go | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/vms/avm/client.go b/vms/avm/client.go index 9bfb42c7c8f0..44469fa6b730 100644 --- a/vms/avm/client.go +++ b/vms/avm/client.go @@ -51,6 +51,27 @@ func (c *Client) GetTxStatus(txID ids.ID) (choices.Status, error) { return res.Status, err } +// ConfirmTx attempts to confirm [txID] by checking its status [attempts] times +// with a [delay] in between each attempt. If the transaction has not been decided +// by the final attempt, it returns the status of the last attempt. +// Note: ConfirmTx will block until either the last attempt finishes or the client +// returns a decided status. +func (c *Client) ConfirmTx(txID ids.ID, attempts int, delay time.Duration) (choices.Status, error) { + for i := 0; i < attempts-1; i++ { + status, err := c.GetTxStatus(txID) + if err != nil { + return status, err + } + + if status.Decided() { + return status, nil + } + time.Sleep(delay) + } + + return c.GetTxStatus(txID) +} + // GetTx returns the byte representation of [txID] func (c *Client) GetTx(txID ids.ID) ([]byte, error) { res := &api.FormattedTx{} From 0a2ccfc1cd0d511fd837b919e8e13d85c93701a5 Mon Sep 17 00:00:00 2001 From: Aaron Buchwald Date: Sat, 26 Dec 2020 16:37:23 -0500 Subject: [PATCH 2/2] Add avm wallet client --- vms/avm/wallet_client.go | 89 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 vms/avm/wallet_client.go diff --git a/vms/avm/wallet_client.go b/vms/avm/wallet_client.go new file mode 100644 index 000000000000..cdc9c50cc27d --- /dev/null +++ b/vms/avm/wallet_client.go @@ -0,0 +1,89 @@ +// (c) 2019-2020, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package avm + +import ( + "fmt" + "time" + + "github.com/ava-labs/avalanchego/api" + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/formatting" + cjson "github.com/ava-labs/avalanchego/utils/json" + "github.com/ava-labs/avalanchego/utils/rpc" +) + +// WalletClient ... +type WalletClient struct { + requester rpc.EndpointRequester +} + +// NewWalletClient returns an AVM wallet client for interacting with avm managed wallet on [chain] +func NewWalletClient(uri, chain string, requestTimeout time.Duration) *WalletClient { + return &WalletClient{ + requester: rpc.NewEndpointRequester(uri, fmt.Sprintf("/ext/bc/%s/wallet", chain), "wallet", requestTimeout), + } +} + +// IssueTx issues a transaction to a node and returns the TxID +func (c *WalletClient) IssueTx(txBytes []byte) (ids.ID, error) { + txStr, err := formatting.Encode(formatting.Hex, txBytes) + if err != nil { + return ids.ID{}, err + } + res := &api.JSONTxID{} + err = c.requester.SendRequest("issueTx", &api.FormattedTx{ + Tx: txStr, + Encoding: formatting.Hex, + }, res) + return res.TxID, err +} + +// Send [amount] of [assetID] to address [to] +func (c *WalletClient) Send( + user api.UserPass, + from []string, + changeAddr string, + amount uint64, + assetID, + to, + memo string, +) (ids.ID, error) { + res := &api.JSONTxID{} + err := c.requester.SendRequest("send", &SendArgs{ + JSONSpendHeader: api.JSONSpendHeader{ + UserPass: user, + JSONFromAddrs: api.JSONFromAddrs{From: from}, + JSONChangeAddr: api.JSONChangeAddr{ChangeAddr: changeAddr}, + }, + SendOutput: SendOutput{ + Amount: cjson.Uint64(amount), + AssetID: assetID, + To: to, + }, + Memo: memo, + }, res) + return res.TxID, err +} + +// SendMultiple sends a transaction from [user] funding all [outputs] +func (c *WalletClient) SendMultiple( + user api.UserPass, + from []string, + changeAddr string, + outputs []SendOutput, + memo string, +) (ids.ID, error) { + res := &api.JSONTxID{} + err := c.requester.SendRequest("sendMultiple", &SendMultipleArgs{ + JSONSpendHeader: api.JSONSpendHeader{ + UserPass: user, + JSONFromAddrs: api.JSONFromAddrs{From: from}, + JSONChangeAddr: api.JSONChangeAddr{ChangeAddr: changeAddr}, + }, + Outputs: outputs, + Memo: memo, + }, res) + return res.TxID, err +}