Skip to content

Commit

Permalink
address comments
Browse files Browse the repository at this point in the history
  • Loading branch information
sukantoraymond committed May 29, 2024
1 parent 2fee577 commit 5e1a7c6
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 65 deletions.
106 changes: 62 additions & 44 deletions keychain/keychain.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package keychain

import (
"fmt"
"github.com/ava-labs/avalanchego/utils/formatting/address"

"avalanche-tooling-sdk-go/avalanche"
"avalanche-tooling-sdk-go/key"
Expand All @@ -22,50 +23,6 @@ type Keychain struct {
ledgerIndices []uint32
}

func (kc *Keychain) P() ([]string, error) {
return utils.P(kc.network.HRP(), kc.Addresses().List())
}

func (kc *Keychain) LedgerEnabled() bool {
return kc.ledgerDevice != nil
}

func (kc *Keychain) AddLedgerIndices(indices []uint32) error {
if kc.LedgerEnabled() {
kc.ledgerIndices = utils.Unique(append(kc.ledgerIndices, indices...))
utils.Uint32Sort(kc.ledgerIndices)
newKc, err := keychain.NewLedgerKeychainFromIndices(kc.ledgerDevice, kc.ledgerIndices)
if err != nil {
return err
}
kc.Keychain = newKc
return nil
}
return fmt.Errorf("keychain is not ledger enabled")
}

func (kc *Keychain) AddLedgerAddresses(addresses []string) error {
if kc.LedgerEnabled() {
indices, err := kc.ledgerDevice.FindAddresses(addresses, 0)
if err != nil {
return err
}
return kc.AddLedgerIndices(maps.Values(indices))
}
return fmt.Errorf("keychain is not ledger enabled")
}

func (kc *Keychain) AddLedgerFunds(amount uint64) error {
if kc.LedgerEnabled() {
indices, err := kc.ledgerDevice.FindFunds(kc.network, amount, 0)
if err != nil {
return err
}
return kc.AddLedgerIndices(indices)
}
return fmt.Errorf("keychain is not ledger enabled")
}

func NewKeychain(
network avalanche.Network,
keyPath string,
Expand Down Expand Up @@ -123,3 +80,64 @@ func NewKeychain(
}
return nil, fmt.Errorf("not keychain option defined")
}

func (kc *Keychain) P() ([]string, error) {
return utils.P(kc.network.HRP(), kc.Addresses().List())
}

func (kc *Keychain) LedgerEnabled() bool {
return kc.ledgerDevice != nil
}

func (kc *Keychain) AddLedgerIndices(indices []uint32) error {
if kc.LedgerEnabled() {
kc.ledgerIndices = utils.Unique(append(kc.ledgerIndices, indices...))
utils.Uint32Sort(kc.ledgerIndices)
newKc, err := keychain.NewLedgerKeychainFromIndices(kc.ledgerDevice, kc.ledgerIndices)
if err != nil {
return err
}
kc.Keychain = newKc
return nil
}
return fmt.Errorf("keychain is not ledger enabled")
}

func (kc *Keychain) AddLedgerAddresses(addresses []string) error {
if kc.LedgerEnabled() {
indices, err := kc.ledgerDevice.FindAddresses(addresses, 0)
if err != nil {
return err
}
return kc.AddLedgerIndices(maps.Values(indices))
}
return fmt.Errorf("keychain is not ledger enabled")
}

func (kc *Keychain) AddLedgerFunds(amount uint64) error {
if kc.LedgerEnabled() {
indices, err := kc.ledgerDevice.FindFunds(kc.network, amount, 0)
if err != nil {
return err
}
return kc.AddLedgerIndices(indices)
}
return fmt.Errorf("keychain is not ledger enabled")
}

func (kc *Keychain) PChainFormattedStrAddresses() ([]string, error) {
addrs := kc.Addresses().List()
if len(addrs) == 0 {
return nil, fmt.Errorf("no addresses in keychain")
}
hrp := kc.network.HRP()
addrsStr := []string{}
for _, addr := range addrs {
addrStr, err := address.Format("P", hrp, addr[:])
if err != nil {
return nil, err
}
addrsStr = append(addrsStr, addrStr)
}
return addrsStr, nil
}
20 changes: 10 additions & 10 deletions subnet/add_validator_subnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package subnet
import "C"
import (
"avalanche-tooling-sdk-go/avalanche"
"avalanche-tooling-sdk-go/multisig"
"avalanche-tooling-sdk-go/wallet"
"fmt"
"github.com/ava-labs/avalanchego/ids"
Expand All @@ -29,18 +30,17 @@ type ValidatorParams struct {
}

// AddValidator adds validator to subnet
func (c *Subnet) AddValidator(wallet wallet.Wallet, validatorInput ValidatorParams) error {
controlKeys, threshold, err := getOwners(network, c.SubnetID, c.DeployInfo.TransferSubnetOwnershipTxID)
func (c *Subnet) AddValidator(wallet wallet.Wallet, validatorInput ValidatorParams) (*multisig.Multisig, error) {
controlKeys, threshold, err := GetOwners(network, c.SubnetID, c.DeployInfo.TransferSubnetOwnershipTxID)
if err != nil {
return err
}
if err := CheckSubnetAuthKeys(kcKeys, c.DeployInfo.SubnetAuthKeys, controlKeys, threshold); err != nil {
return err
if err := checkSubnetAuthKeys(wallet.Keychain, c.DeployInfo.SubnetAuthKeys, controlKeys, threshold); err != nil {
return nil, err
}
validator := &txs.SubnetValidator{
Validator: txs.Validator{
NodeID: validatorInput.NodeID,
Start: uint64(validatorInput.StartTime.Unix()),
End: uint64(validatorInput.StartTime.Add(validatorInput.Duration).Unix()),
Wght: validatorInput.Weight,
},
Expand All @@ -50,16 +50,16 @@ func (c *Subnet) AddValidator(wallet wallet.Wallet, validatorInput ValidatorPara
wallet.SetSubnetAuthMultisig(c.DeployInfo.SubnetAuthKeys)
unsignedTx, err := wallet.P().Builder().NewAddSubnetValidatorTx(validator)
if err != nil {
return fmt.Errorf("error building tx: %w", err)
return nil, fmt.Errorf("error building tx: %w", err)
}
tx := txs.Tx{Unsigned: unsignedTx}
if err := wallet.P().Signer().Sign(context.Background(), &tx); err != nil {
return fmt.Errorf("error signing tx: %w", err)
return nil, fmt.Errorf("error signing tx: %w", err)
}
return nil
return multisig.New(&tx), nil
}

func CheckSubnetAuthKeys(walletKeys []string, subnetAuthKeys []string, controlKeys []string, threshold uint32) error {
func checkSubnetAuthKeys(walletKeys []string, subnetAuthKeys []string, controlKeys []string, threshold uint32) error {
for _, walletKey := range walletKeys {
if slices.Contains(controlKeys, walletKey) && !slices.Contains(subnetAuthKeys, walletKey) {
return fmt.Errorf("wallet key %s is a subnet control key so it must be included in subnet auth keys", walletKey)
Expand All @@ -83,7 +83,7 @@ func CheckSubnetAuthKeys(walletKeys []string, subnetAuthKeys []string, controlKe
return nil
}

func getOwners(network avalanche.Network, subnetID ids.ID, transferSubnetOwnershipTxID ids.ID) ([]string, uint32, error) {
func GetOwners(network avalanche.Network, subnetID ids.ID, transferSubnetOwnershipTxID ids.ID) ([]string, uint32, error) {
pClient := platformvm.NewClient(network.Endpoint)
ctx := context.Background()
var owner *secp256k1fx.OutputOwners
Expand Down
22 changes: 11 additions & 11 deletions wallet/wallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import (

type Wallet struct {
primary.Wallet
keychain keychain.Keychain
options []common.Option
Keychain keychain.Keychain
Options []common.Option
}

func New(ctx context.Context, config *primary.WalletConfig) (Wallet, error) {
Expand All @@ -26,35 +26,35 @@ func New(ctx context.Context, config *primary.WalletConfig) (Wallet, error) {
)
return Wallet{
Wallet: wallet,
keychain: keychain.Keychain{
Keychain: keychain.Keychain{
Keychain: config.AVAXKeychain,
},
}, err
}

// SecureWalletIsChangeOwner ensures that a fee paying address (wallet's keychain) will receive
// SecureWalletIsChangeOwner ensures that a fee paying address (wallet's Keychain) will receive
// the change UTXO and not a randomly selected auth key that may not be paying fees
func (w *Wallet) SecureWalletIsChangeOwner() {
addrs := w.keychain.Addresses().List()
addrs := w.Keychain.Addresses().List()
changeAddr := addrs[0]
// sets change to go to wallet addr (instead of any other subnet auth key)
changeOwner := &secp256k1fx.OutputOwners{
Threshold: 1,
Addrs: []ids.ShortID{changeAddr},
}
w.options = append(w.options, common.WithChangeOwner(changeOwner))
w.Wallet = primary.NewWalletWithOptions(w.Wallet, w.options...)
w.Options = append(w.Options, common.WithChangeOwner(changeOwner))
w.Wallet = primary.NewWalletWithOptions(w.Wallet, w.Options...)
}

// SetAuthKeys sets auth keys that will be used when signing txs, besides the wallet's keychain fee
// SetAuthKeys sets auth keys that will be used when signing txs, besides the wallet's Keychain fee
// paying ones
func (w *Wallet) SetAuthKeys(authKeys []ids.ShortID) {
addrs := w.keychain.Addresses().List()
addrs := w.Keychain.Addresses().List()
addrsSet := set.Set[ids.ShortID]{}
addrsSet.Add(addrs...)
addrsSet.Add(authKeys...)
w.options = append(w.options, common.WithCustomAddresses(addrsSet))
w.Wallet = primary.NewWalletWithOptions(w.Wallet, w.options...)
w.Options = append(w.Options, common.WithCustomAddresses(addrsSet))
w.Wallet = primary.NewWalletWithOptions(w.Wallet, w.Options...)
}

func (w *Wallet) SetSubnetAuthMultisig(authKeys []ids.ShortID) {
Expand Down

0 comments on commit 5e1a7c6

Please sign in to comment.