github.com/ava-labs/avalanchego@v1.11.11/wallet/chain/x/wallet.go (about) 1 // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. 2 // See the file LICENSE for licensing terms. 3 4 package x 5 6 import ( 7 "github.com/ava-labs/avalanchego/ids" 8 "github.com/ava-labs/avalanchego/vms/avm" 9 "github.com/ava-labs/avalanchego/vms/avm/txs" 10 "github.com/ava-labs/avalanchego/vms/components/avax" 11 "github.com/ava-labs/avalanchego/vms/components/verify" 12 "github.com/ava-labs/avalanchego/vms/secp256k1fx" 13 "github.com/ava-labs/avalanchego/wallet/chain/x/builder" 14 "github.com/ava-labs/avalanchego/wallet/chain/x/signer" 15 "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" 16 ) 17 18 var _ Wallet = (*wallet)(nil) 19 20 type Wallet interface { 21 // Builder returns the builder that will be used to create the transactions. 22 Builder() builder.Builder 23 24 // Signer returns the signer that will be used to sign the transactions. 25 Signer() signer.Signer 26 27 // IssueBaseTx creates, signs, and issues a new simple value transfer. 28 // 29 // - [outputs] specifies all the recipients and amounts that should be sent 30 // from this transaction. 31 IssueBaseTx( 32 outputs []*avax.TransferableOutput, 33 options ...common.Option, 34 ) (*txs.Tx, error) 35 36 // IssueCreateAssetTx creates, signs, and issues a new asset. 37 // 38 // - [name] specifies a human readable name for this asset. 39 // - [symbol] specifies a human readable abbreviation for this asset. 40 // - [denomination] specifies how many times the asset can be split. For 41 // example, a denomination of [4] would mean that the smallest unit of the 42 // asset would be 0.001 units. 43 // - [initialState] specifies the supported feature extensions for this 44 // asset as well as the initial outputs for the asset. 45 IssueCreateAssetTx( 46 name string, 47 symbol string, 48 denomination byte, 49 initialState map[uint32][]verify.State, 50 options ...common.Option, 51 ) (*txs.Tx, error) 52 53 // IssueOperationTx creates, signs, and issues state changes on the UTXO 54 // set. These state changes may be more complex than simple value transfers. 55 // 56 // - [operations] specifies the state changes to perform. 57 IssueOperationTx( 58 operations []*txs.Operation, 59 options ...common.Option, 60 ) (*txs.Tx, error) 61 62 // IssueOperationTxMintFT creates, signs, and issues a set of state changes 63 // that mint new tokens for the requested assets. 64 // 65 // - [outputs] maps the assetID to the output that should be created for the 66 // asset. 67 IssueOperationTxMintFT( 68 outputs map[ids.ID]*secp256k1fx.TransferOutput, 69 options ...common.Option, 70 ) (*txs.Tx, error) 71 72 // IssueOperationTxMintNFT creates, signs, and issues a state change that 73 // mints new NFTs for the requested asset. 74 // 75 // - [assetID] specifies the asset to mint the NFTs under. 76 // - [payload] specifies the payload to provide each new NFT. 77 // - [owners] specifies the new owners of each NFT. 78 IssueOperationTxMintNFT( 79 assetID ids.ID, 80 payload []byte, 81 owners []*secp256k1fx.OutputOwners, 82 options ...common.Option, 83 ) (*txs.Tx, error) 84 85 // IssueOperationTxMintProperty creates, signs, and issues a state change 86 // that mints a new property for the requested asset. 87 // 88 // - [assetID] specifies the asset to mint the property under. 89 // - [owner] specifies the new owner of the property. 90 IssueOperationTxMintProperty( 91 assetID ids.ID, 92 owner *secp256k1fx.OutputOwners, 93 options ...common.Option, 94 ) (*txs.Tx, error) 95 96 // IssueOperationTxBurnProperty creates, signs, and issues state changes 97 // that burns all the properties of the requested asset. 98 // 99 // - [assetID] specifies the asset to burn the property of. 100 IssueOperationTxBurnProperty( 101 assetID ids.ID, 102 options ...common.Option, 103 ) (*txs.Tx, error) 104 105 // IssueImportTx creates, signs, and issues an import transaction that 106 // attempts to consume all the available UTXOs and import the funds to [to]. 107 // 108 // - [chainID] specifies the chain to be importing funds from. 109 // - [to] specifies where to send the imported funds to. 110 IssueImportTx( 111 chainID ids.ID, 112 to *secp256k1fx.OutputOwners, 113 options ...common.Option, 114 ) (*txs.Tx, error) 115 116 // IssueExportTx creates, signs, and issues an export transaction that 117 // attempts to send all the provided [outputs] to the requested [chainID]. 118 // 119 // - [chainID] specifies the chain to be exporting the funds to. 120 // - [outputs] specifies the outputs to send to the [chainID]. 121 IssueExportTx( 122 chainID ids.ID, 123 outputs []*avax.TransferableOutput, 124 options ...common.Option, 125 ) (*txs.Tx, error) 126 127 // IssueUnsignedTx signs and issues the unsigned tx. 128 IssueUnsignedTx( 129 utx txs.UnsignedTx, 130 options ...common.Option, 131 ) (*txs.Tx, error) 132 133 // IssueTx issues the signed tx. 134 IssueTx( 135 tx *txs.Tx, 136 options ...common.Option, 137 ) error 138 } 139 140 func NewWallet( 141 builder builder.Builder, 142 signer signer.Signer, 143 client avm.Client, 144 backend Backend, 145 ) Wallet { 146 return &wallet{ 147 backend: backend, 148 builder: builder, 149 signer: signer, 150 client: client, 151 } 152 } 153 154 type wallet struct { 155 backend Backend 156 builder builder.Builder 157 signer signer.Signer 158 client avm.Client 159 } 160 161 func (w *wallet) Builder() builder.Builder { 162 return w.builder 163 } 164 165 func (w *wallet) Signer() signer.Signer { 166 return w.signer 167 } 168 169 func (w *wallet) IssueBaseTx( 170 outputs []*avax.TransferableOutput, 171 options ...common.Option, 172 ) (*txs.Tx, error) { 173 utx, err := w.builder.NewBaseTx(outputs, options...) 174 if err != nil { 175 return nil, err 176 } 177 return w.IssueUnsignedTx(utx, options...) 178 } 179 180 func (w *wallet) IssueCreateAssetTx( 181 name string, 182 symbol string, 183 denomination byte, 184 initialState map[uint32][]verify.State, 185 options ...common.Option, 186 ) (*txs.Tx, error) { 187 utx, err := w.builder.NewCreateAssetTx(name, symbol, denomination, initialState, options...) 188 if err != nil { 189 return nil, err 190 } 191 return w.IssueUnsignedTx(utx, options...) 192 } 193 194 func (w *wallet) IssueOperationTx( 195 operations []*txs.Operation, 196 options ...common.Option, 197 ) (*txs.Tx, error) { 198 utx, err := w.builder.NewOperationTx(operations, options...) 199 if err != nil { 200 return nil, err 201 } 202 return w.IssueUnsignedTx(utx, options...) 203 } 204 205 func (w *wallet) IssueOperationTxMintFT( 206 outputs map[ids.ID]*secp256k1fx.TransferOutput, 207 options ...common.Option, 208 ) (*txs.Tx, error) { 209 utx, err := w.builder.NewOperationTxMintFT(outputs, options...) 210 if err != nil { 211 return nil, err 212 } 213 return w.IssueUnsignedTx(utx, options...) 214 } 215 216 func (w *wallet) IssueOperationTxMintNFT( 217 assetID ids.ID, 218 payload []byte, 219 owners []*secp256k1fx.OutputOwners, 220 options ...common.Option, 221 ) (*txs.Tx, error) { 222 utx, err := w.builder.NewOperationTxMintNFT(assetID, payload, owners, options...) 223 if err != nil { 224 return nil, err 225 } 226 return w.IssueUnsignedTx(utx, options...) 227 } 228 229 func (w *wallet) IssueOperationTxMintProperty( 230 assetID ids.ID, 231 owner *secp256k1fx.OutputOwners, 232 options ...common.Option, 233 ) (*txs.Tx, error) { 234 utx, err := w.builder.NewOperationTxMintProperty(assetID, owner, options...) 235 if err != nil { 236 return nil, err 237 } 238 return w.IssueUnsignedTx(utx, options...) 239 } 240 241 func (w *wallet) IssueOperationTxBurnProperty( 242 assetID ids.ID, 243 options ...common.Option, 244 ) (*txs.Tx, error) { 245 utx, err := w.builder.NewOperationTxBurnProperty(assetID, options...) 246 if err != nil { 247 return nil, err 248 } 249 return w.IssueUnsignedTx(utx, options...) 250 } 251 252 func (w *wallet) IssueImportTx( 253 chainID ids.ID, 254 to *secp256k1fx.OutputOwners, 255 options ...common.Option, 256 ) (*txs.Tx, error) { 257 utx, err := w.builder.NewImportTx(chainID, to, options...) 258 if err != nil { 259 return nil, err 260 } 261 return w.IssueUnsignedTx(utx, options...) 262 } 263 264 func (w *wallet) IssueExportTx( 265 chainID ids.ID, 266 outputs []*avax.TransferableOutput, 267 options ...common.Option, 268 ) (*txs.Tx, error) { 269 utx, err := w.builder.NewExportTx(chainID, outputs, options...) 270 if err != nil { 271 return nil, err 272 } 273 return w.IssueUnsignedTx(utx, options...) 274 } 275 276 func (w *wallet) IssueUnsignedTx( 277 utx txs.UnsignedTx, 278 options ...common.Option, 279 ) (*txs.Tx, error) { 280 ops := common.NewOptions(options) 281 ctx := ops.Context() 282 tx, err := signer.SignUnsigned(ctx, w.signer, utx) 283 if err != nil { 284 return nil, err 285 } 286 287 return tx, w.IssueTx(tx, options...) 288 } 289 290 func (w *wallet) IssueTx( 291 tx *txs.Tx, 292 options ...common.Option, 293 ) error { 294 ops := common.NewOptions(options) 295 ctx := ops.Context() 296 txID, err := w.client.IssueTx(ctx, tx.Bytes()) 297 if err != nil { 298 return err 299 } 300 301 if f := ops.PostIssuanceFunc(); f != nil { 302 f(txID) 303 } 304 305 if ops.AssumeDecided() { 306 return w.backend.AcceptTx(ctx, tx) 307 } 308 309 if err := avm.AwaitTxAccepted(w.client, ctx, txID, ops.PollFrequency()); err != nil { 310 return err 311 } 312 313 return w.backend.AcceptTx(ctx, tx) 314 }