From b22671614679c3af97483a42af504c1cf0c6c3ea Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Wed, 21 Dec 2022 22:32:22 -0500 Subject: [PATCH] Add more wallet examples (#2382) --- .../add-permissioned-subnet-validator/main.go | 70 ++++++++++++++++ .../examples/add-primary-validator/main.go | 79 +++++++++++++++++++ .../primary/examples/create-chain/main.go | 63 +++++++++++++++ .../primary/examples/create-subnet/main.go | 51 ++++++++++++ 4 files changed, 263 insertions(+) create mode 100644 wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go create mode 100644 wallet/subnet/primary/examples/add-primary-validator/main.go create mode 100644 wallet/subnet/primary/examples/create-chain/main.go create mode 100644 wallet/subnet/primary/examples/create-subnet/main.go diff --git a/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go b/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go new file mode 100644 index 000000000000..5c4fd9cda730 --- /dev/null +++ b/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go @@ -0,0 +1,70 @@ +// Copyright (C) 2019-2022, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package main + +import ( + "context" + "log" + "time" + + "github.com/ava-labs/avalanchego/api/info" + "github.com/ava-labs/avalanchego/genesis" + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/units" + "github.com/ava-labs/avalanchego/vms/platformvm/validator" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary" +) + +func main() { + key := genesis.EWOQKey + uri := primary.LocalAPIURI + kc := secp256k1fx.NewKeychain(key) + subnetIDStr := "29uVeLPJB1eQJkzRemU8g8wZDw5uJRqpab5U2mX9euieVwiEbL" + startTime := time.Now().Add(time.Minute) + duration := 2 * 7 * 24 * time.Hour // 2 weeks + weight := units.Schmeckle + + subnetID, err := ids.FromString(subnetIDStr) + if err != nil { + log.Fatalf("failed to parse subnet ID: %s\n", err) + } + + ctx := context.Background() + infoClient := info.NewClient(uri) + + nodeInfoStartTime := time.Now() + nodeID, _, err := infoClient.GetNodeID(ctx) + if err != nil { + log.Fatalf("failed to fetch node IDs: %s\n", err) + } + log.Printf("fetched node ID %s in %s\n", nodeID, time.Since(nodeInfoStartTime)) + + // NewWalletFromURI fetches the available UTXOs owned by [kc] on the network + // that [uri] is hosting. + walletSyncStartTime := time.Now() + wallet, err := primary.NewWalletWithTxs(ctx, uri, kc, subnetID) + if err != nil { + log.Fatalf("failed to initialize wallet: %s\n", err) + } + log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime)) + + // Get the P-chain wallet + pWallet := wallet.P() + + addValidatorStartTime := time.Now() + addValidatorTxID, err := pWallet.IssueAddSubnetValidatorTx(&validator.SubnetValidator{ + Validator: validator.Validator{ + NodeID: nodeID, + Start: uint64(startTime.Unix()), + End: uint64(startTime.Add(duration).Unix()), + Wght: weight, + }, + Subnet: subnetID, + }) + if err != nil { + log.Fatalf("failed to issue add subnet validator transaction: %s\n", err) + } + log.Printf("added new subnet validator %s to %s with %s in %s\n", nodeID, subnetID, addValidatorTxID, time.Since(addValidatorStartTime)) +} diff --git a/wallet/subnet/primary/examples/add-primary-validator/main.go b/wallet/subnet/primary/examples/add-primary-validator/main.go new file mode 100644 index 000000000000..0a2dce7809a5 --- /dev/null +++ b/wallet/subnet/primary/examples/add-primary-validator/main.go @@ -0,0 +1,79 @@ +// Copyright (C) 2019-2022, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package main + +import ( + "context" + "log" + "time" + + "github.com/ava-labs/avalanchego/api/info" + "github.com/ava-labs/avalanchego/genesis" + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/units" + "github.com/ava-labs/avalanchego/vms/platformvm/reward" + "github.com/ava-labs/avalanchego/vms/platformvm/validator" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary" +) + +func main() { + key := genesis.EWOQKey + uri := primary.LocalAPIURI + kc := secp256k1fx.NewKeychain(key) + startTime := time.Now().Add(time.Minute) + duration := 3 * 7 * 24 * time.Hour // 3 weeks + weight := 2_000 * units.Avax + validatorRewardAddr := key.Address() + delegatorRewardAddr := key.Address() + delegationFee := uint32(reward.PercentDenominator / 2) // 50% + + ctx := context.Background() + infoClient := info.NewClient(uri) + + nodeInfoStartTime := time.Now() + nodeID, nodePOP, err := infoClient.GetNodeID(ctx) + if err != nil { + log.Fatalf("failed to fetch node IDs: %s\n", err) + } + log.Printf("fetched node ID %s in %s\n", nodeID, time.Since(nodeInfoStartTime)) + + // NewWalletFromURI fetches the available UTXOs owned by [kc] on the network + // that [uri] is hosting. + walletSyncStartTime := time.Now() + wallet, err := primary.NewWalletFromURI(ctx, uri, kc) + if err != nil { + log.Fatalf("failed to initialize wallet: %s\n", err) + } + log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime)) + + // Get the P-chain wallet + pWallet := wallet.P() + avaxAssetID := pWallet.AVAXAssetID() + + addValidatorStartTime := time.Now() + addValidatorTxID, err := pWallet.IssueAddPermissionlessValidatorTx( + &validator.SubnetValidator{Validator: validator.Validator{ + NodeID: nodeID, + Start: uint64(startTime.Unix()), + End: uint64(startTime.Add(duration).Unix()), + Wght: weight, + }}, + nodePOP, + avaxAssetID, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{validatorRewardAddr}, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{delegatorRewardAddr}, + }, + delegationFee, + ) + if err != nil { + log.Fatalf("failed to issue add permissionless validator transaction: %s\n", err) + } + log.Printf("added new primary network validator %s with %s in %s\n", nodeID, addValidatorTxID, time.Since(addValidatorStartTime)) +} diff --git a/wallet/subnet/primary/examples/create-chain/main.go b/wallet/subnet/primary/examples/create-chain/main.go new file mode 100644 index 000000000000..bf9768e13cac --- /dev/null +++ b/wallet/subnet/primary/examples/create-chain/main.go @@ -0,0 +1,63 @@ +// Copyright (C) 2019-2022, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package main + +import ( + "context" + "encoding/hex" + "log" + "time" + + "github.com/ava-labs/avalanchego/genesis" + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary" +) + +func main() { + key := genesis.EWOQKey + uri := primary.LocalAPIURI + kc := secp256k1fx.NewKeychain(key) + subnetIDStr := "29uVeLPJB1eQJkzRemU8g8wZDw5uJRqpab5U2mX9euieVwiEbL" + genesisHex := "00000000000000000000000000017b5490493f8a2fff444ac8b54e27b3339d7c60dcffffffffffffffff" + vmID := ids.ID{'x', 's', 'v', 'm'} + name := "let there" + + subnetID, err := ids.FromString(subnetIDStr) + if err != nil { + log.Fatalf("failed to parse subnet ID: %s\n", err) + } + + genesisBytes, err := hex.DecodeString(genesisHex) + if err != nil { + log.Fatalf("failed to parse genesis bytes: %s\n", err) + } + + ctx := context.Background() + + // NewWalletFromURI fetches the available UTXOs owned by [kc] on the network + // that [uri] is hosting. + walletSyncStartTime := time.Now() + wallet, err := primary.NewWalletWithTxs(ctx, uri, kc, subnetID) + if err != nil { + log.Fatalf("failed to initialize wallet: %s\n", err) + } + log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime)) + + // Get the P-chain wallet + pWallet := wallet.P() + + createChainStartTime := time.Now() + createChainTxID, err := pWallet.IssueCreateChainTx( + subnetID, + genesisBytes, + vmID, + nil, + name, + ) + if err != nil { + log.Fatalf("failed to issue create chain transaction: %s\n", err) + } + log.Printf("created new chain %s in %s\n", createChainTxID, time.Since(createChainStartTime)) +} diff --git a/wallet/subnet/primary/examples/create-subnet/main.go b/wallet/subnet/primary/examples/create-subnet/main.go new file mode 100644 index 000000000000..5c4f6ad254e7 --- /dev/null +++ b/wallet/subnet/primary/examples/create-subnet/main.go @@ -0,0 +1,51 @@ +// Copyright (C) 2019-2022, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package main + +import ( + "context" + "log" + "time" + + "github.com/ava-labs/avalanchego/genesis" + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary" +) + +func main() { + key := genesis.EWOQKey + uri := primary.LocalAPIURI + kc := secp256k1fx.NewKeychain(key) + subnetOwner := key.Address() + + ctx := context.Background() + + // NewWalletFromURI fetches the available UTXOs owned by [kc] on the network + // that [uri] is hosting. + walletSyncStartTime := time.Now() + wallet, err := primary.NewWalletFromURI(ctx, uri, kc) + if err != nil { + log.Fatalf("failed to initialize wallet: %s\n", err) + } + log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime)) + + // Get the P-chain wallet + pWallet := wallet.P() + + // Pull out useful constants to use when issuing transactions. + owner := &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + subnetOwner, + }, + } + + createSubnetStartTime := time.Now() + createSubnetTxID, err := pWallet.IssueCreateSubnetTx(owner) + if err != nil { + log.Fatalf("failed to issue create subnet transaction: %s\n", err) + } + log.Printf("created new subnet %s in %s\n", createSubnetTxID, time.Since(createSubnetStartTime)) +}