Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions vms/avm/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{}
Expand Down
89 changes: 89 additions & 0 deletions vms/avm/wallet_client.go
Original file line number Diff line number Diff line change
@@ -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
}