github.com/MetalBlockchain/metalgo@v1.11.9/vms/avm/wallet_client.go (about) 1 // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. 2 // See the file LICENSE for licensing terms. 3 4 package avm 5 6 import ( 7 "context" 8 "fmt" 9 10 "github.com/MetalBlockchain/metalgo/api" 11 "github.com/MetalBlockchain/metalgo/ids" 12 "github.com/MetalBlockchain/metalgo/utils/constants" 13 "github.com/MetalBlockchain/metalgo/utils/formatting" 14 "github.com/MetalBlockchain/metalgo/utils/json" 15 "github.com/MetalBlockchain/metalgo/utils/rpc" 16 ) 17 18 var _ WalletClient = (*client)(nil) 19 20 // interface of an AVM wallet client for interacting with avm managed wallet on [chain] 21 type WalletClient interface { 22 // IssueTx issues a transaction to a node and returns the TxID 23 IssueTx(ctx context.Context, tx []byte, options ...rpc.Option) (ids.ID, error) 24 // Send [amount] of [assetID] to address [to] 25 // 26 // Deprecated: Transactions should be issued using the 27 // `avalanchego/wallet/chain/x.Wallet` utility. 28 Send( 29 ctx context.Context, 30 user api.UserPass, 31 from []ids.ShortID, 32 changeAddr ids.ShortID, 33 amount uint64, 34 assetID string, 35 to ids.ShortID, 36 memo string, 37 options ...rpc.Option, 38 ) (ids.ID, error) 39 // SendMultiple sends a transaction from [user] funding all [outputs] 40 // 41 // Deprecated: Transactions should be issued using the 42 // `avalanchego/wallet/chain/x.Wallet` utility. 43 SendMultiple( 44 ctx context.Context, 45 user api.UserPass, 46 from []ids.ShortID, 47 changeAddr ids.ShortID, 48 outputs []ClientSendOutput, 49 memo string, 50 options ...rpc.Option, 51 ) (ids.ID, error) 52 } 53 54 // implementation of an AVM wallet client for interacting with avm managed wallet on [chain] 55 type walletClient struct { 56 requester rpc.EndpointRequester 57 } 58 59 // NewWalletClient returns an AVM wallet client for interacting with avm managed wallet on [chain] 60 // 61 // Deprecated: Transactions should be issued using the 62 // `avalanchego/wallet/chain/x.Wallet` utility. 63 func NewWalletClient(uri, chain string) WalletClient { 64 path := fmt.Sprintf( 65 "%s/ext/%s/%s/wallet", 66 uri, 67 constants.ChainAliasPrefix, 68 chain, 69 ) 70 return &walletClient{ 71 requester: rpc.NewEndpointRequester(path), 72 } 73 } 74 75 func (c *walletClient) IssueTx(ctx context.Context, txBytes []byte, options ...rpc.Option) (ids.ID, error) { 76 txStr, err := formatting.Encode(formatting.Hex, txBytes) 77 if err != nil { 78 return ids.Empty, err 79 } 80 res := &api.JSONTxID{} 81 err = c.requester.SendRequest(ctx, "wallet.issueTx", &api.FormattedTx{ 82 Tx: txStr, 83 Encoding: formatting.Hex, 84 }, res, options...) 85 return res.TxID, err 86 } 87 88 // ClientSendOutput specifies that [Amount] of asset [AssetID] be sent to [To] 89 type ClientSendOutput struct { 90 // The amount of funds to send 91 Amount uint64 92 93 // ID of the asset being sent 94 AssetID string 95 96 // Address of the recipient 97 To ids.ShortID 98 } 99 100 func (c *walletClient) Send( 101 ctx context.Context, 102 user api.UserPass, 103 from []ids.ShortID, 104 changeAddr ids.ShortID, 105 amount uint64, 106 assetID string, 107 to ids.ShortID, 108 memo string, 109 options ...rpc.Option, 110 ) (ids.ID, error) { 111 res := &api.JSONTxID{} 112 err := c.requester.SendRequest(ctx, "wallet.send", &SendArgs{ 113 JSONSpendHeader: api.JSONSpendHeader{ 114 UserPass: user, 115 JSONFromAddrs: api.JSONFromAddrs{From: ids.ShortIDsToStrings(from)}, 116 JSONChangeAddr: api.JSONChangeAddr{ChangeAddr: changeAddr.String()}, 117 }, 118 SendOutput: SendOutput{ 119 Amount: json.Uint64(amount), 120 AssetID: assetID, 121 To: to.String(), 122 }, 123 Memo: memo, 124 }, res, options...) 125 return res.TxID, err 126 } 127 128 func (c *walletClient) SendMultiple( 129 ctx context.Context, 130 user api.UserPass, 131 from []ids.ShortID, 132 changeAddr ids.ShortID, 133 outputs []ClientSendOutput, 134 memo string, 135 options ...rpc.Option, 136 ) (ids.ID, error) { 137 res := &api.JSONTxID{} 138 serviceOutputs := make([]SendOutput, len(outputs)) 139 for i, output := range outputs { 140 serviceOutputs[i].Amount = json.Uint64(output.Amount) 141 serviceOutputs[i].AssetID = output.AssetID 142 serviceOutputs[i].To = output.To.String() 143 } 144 err := c.requester.SendRequest(ctx, "wallet.sendMultiple", &SendMultipleArgs{ 145 JSONSpendHeader: api.JSONSpendHeader{ 146 UserPass: user, 147 JSONFromAddrs: api.JSONFromAddrs{From: ids.ShortIDsToStrings(from)}, 148 JSONChangeAddr: api.JSONChangeAddr{ChangeAddr: changeAddr.String()}, 149 }, 150 Outputs: serviceOutputs, 151 Memo: memo, 152 }, res, options...) 153 return res.TxID, err 154 }