github.com/ava-labs/avalanchego@v1.11.11/wallet/subnet/primary/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 primary 5 6 import ( 7 "context" 8 9 "github.com/ava-labs/avalanchego/ids" 10 "github.com/ava-labs/avalanchego/utils/constants" 11 "github.com/ava-labs/avalanchego/utils/crypto/keychain" 12 "github.com/ava-labs/avalanchego/vms/platformvm" 13 "github.com/ava-labs/avalanchego/wallet/chain/c" 14 "github.com/ava-labs/avalanchego/wallet/chain/p" 15 "github.com/ava-labs/avalanchego/wallet/chain/x" 16 "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" 17 18 pbuilder "github.com/ava-labs/avalanchego/wallet/chain/p/builder" 19 psigner "github.com/ava-labs/avalanchego/wallet/chain/p/signer" 20 pwallet "github.com/ava-labs/avalanchego/wallet/chain/p/wallet" 21 xbuilder "github.com/ava-labs/avalanchego/wallet/chain/x/builder" 22 xsigner "github.com/ava-labs/avalanchego/wallet/chain/x/signer" 23 ) 24 25 var _ Wallet = (*wallet)(nil) 26 27 // Wallet provides chain wallets for the primary network. 28 type Wallet interface { 29 P() pwallet.Wallet 30 X() x.Wallet 31 C() c.Wallet 32 } 33 34 type wallet struct { 35 p pwallet.Wallet 36 x x.Wallet 37 c c.Wallet 38 } 39 40 func (w *wallet) P() pwallet.Wallet { 41 return w.p 42 } 43 44 func (w *wallet) X() x.Wallet { 45 return w.x 46 } 47 48 func (w *wallet) C() c.Wallet { 49 return w.c 50 } 51 52 // Creates a new default wallet 53 func NewWallet(p pwallet.Wallet, x x.Wallet, c c.Wallet) Wallet { 54 return &wallet{ 55 p: p, 56 x: x, 57 c: c, 58 } 59 } 60 61 // Creates a Wallet with the given set of options 62 func NewWalletWithOptions(w Wallet, options ...common.Option) Wallet { 63 return NewWallet( 64 pwallet.WithOptions(w.P(), options...), 65 x.NewWalletWithOptions(w.X(), options...), 66 c.NewWalletWithOptions(w.C(), options...), 67 ) 68 } 69 70 type WalletConfig struct { 71 // Base URI to use for all node requests. 72 URI string // required 73 // Keys to use for signing all transactions. 74 AVAXKeychain keychain.Keychain // required 75 EthKeychain c.EthKeychain // required 76 // Subnet IDs that the wallet should know about to be able to 77 // generate transactions. 78 SubnetIDs []ids.ID // optional 79 } 80 81 // MakeWallet returns a wallet that supports issuing transactions to the chains 82 // living in the primary network. 83 // 84 // On creation, the wallet attaches to the provided uri and fetches all UTXOs 85 // that reference any of the provided keys. If the UTXOs are modified through an 86 // external issuance process, such as another instance of the wallet, the UTXOs 87 // may become out of sync. The wallet will also fetch all requested P-chain 88 // transactions. 89 // 90 // The wallet manages all state locally, and performs all tx signing locally. 91 func MakeWallet(ctx context.Context, config *WalletConfig) (Wallet, error) { 92 avaxAddrs := config.AVAXKeychain.Addresses() 93 avaxState, err := FetchState(ctx, config.URI, avaxAddrs) 94 if err != nil { 95 return nil, err 96 } 97 98 ethAddrs := config.EthKeychain.EthAddresses() 99 ethState, err := FetchEthState(ctx, config.URI, ethAddrs) 100 if err != nil { 101 return nil, err 102 } 103 104 subnetOwners, err := platformvm.GetSubnetOwners(avaxState.PClient, ctx, config.SubnetIDs...) 105 if err != nil { 106 return nil, err 107 } 108 pUTXOs := common.NewChainUTXOs(constants.PlatformChainID, avaxState.UTXOs) 109 pBackend := pwallet.NewBackend(avaxState.PCTX, pUTXOs, subnetOwners) 110 pClient := p.NewClient(avaxState.PClient, pBackend) 111 pBuilder := pbuilder.New(avaxAddrs, avaxState.PCTX, pBackend) 112 pSigner := psigner.New(config.AVAXKeychain, pBackend) 113 114 xChainID := avaxState.XCTX.BlockchainID 115 xUTXOs := common.NewChainUTXOs(xChainID, avaxState.UTXOs) 116 xBackend := x.NewBackend(avaxState.XCTX, xUTXOs) 117 xBuilder := xbuilder.New(avaxAddrs, avaxState.XCTX, xBackend) 118 xSigner := xsigner.New(config.AVAXKeychain, xBackend) 119 120 cChainID := avaxState.CCTX.BlockchainID 121 cUTXOs := common.NewChainUTXOs(cChainID, avaxState.UTXOs) 122 cBackend := c.NewBackend(cUTXOs, ethState.Accounts) 123 cBuilder := c.NewBuilder(avaxAddrs, ethAddrs, avaxState.CCTX, cBackend) 124 cSigner := c.NewSigner(config.AVAXKeychain, config.EthKeychain, cBackend) 125 126 return NewWallet( 127 pwallet.New(pClient, pBuilder, pSigner), 128 x.NewWallet(xBuilder, xSigner, avaxState.XClient, xBackend), 129 c.NewWallet(cBuilder, cSigner, avaxState.CClient, ethState.Client, cBackend), 130 ), nil 131 }