-
Notifications
You must be signed in to change notification settings - Fork 215
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #6603 from spacemeshos/athena-test-client
athena devnet testing client
- Loading branch information
Showing
13 changed files
with
619 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
*.hex |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package api | ||
|
||
import ( | ||
"fmt" | ||
|
||
"google.golang.org/grpc" | ||
"google.golang.org/grpc/credentials/insecure" | ||
) | ||
|
||
func connect(address string) (*grpc.ClientConn, error) { | ||
conn, err := grpc.NewClient( | ||
address, | ||
grpc.WithTransportCredentials(insecure.NewCredentials()), | ||
) | ||
if err != nil { | ||
return nil, fmt.Errorf("connecting to %s: %w", address, err) | ||
} | ||
return conn, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package api | ||
|
||
import ( | ||
"context" | ||
|
||
spacemeshv2alpha1 "github.com/spacemeshos/api/release/go/spacemesh/v2alpha1" | ||
|
||
"github.com/spacemeshos/go-spacemesh/common/types" | ||
) | ||
|
||
func AccountInfo(apiAddress string, accountAddress types.Address) (*spacemeshv2alpha1.Account, error) { | ||
conn, err := connect(apiAddress) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
req := spacemeshv2alpha1.AccountRequest{ | ||
Addresses: []string{accountAddress.String()}, | ||
Limit: 1, | ||
} | ||
|
||
resp, err := spacemeshv2alpha1.NewAccountServiceClient(conn).List(context.Background(), &req) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return resp.Accounts[0], nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package api | ||
|
||
import ( | ||
"context" | ||
"encoding/hex" | ||
"fmt" | ||
|
||
spacemeshv2alpha1 "github.com/spacemeshos/api/release/go/spacemesh/v2alpha1" | ||
"go.uber.org/zap" | ||
) | ||
|
||
func Submit(address string, tx []byte, logger *zap.Logger) error { | ||
conn, err := connect(address) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
req := spacemeshv2alpha1.SubmitTransactionRequest{ | ||
Transaction: tx, | ||
} | ||
|
||
resp, err := spacemeshv2alpha1.NewTransactionServiceClient(conn).SubmitTransaction(context.Background(), &req) | ||
if err != nil { | ||
return fmt.Errorf("submitting TX: %w", err) | ||
} | ||
logger.Info("submitted", zap.String("ID", hex.EncodeToString(resp.TxId))) | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package cmd | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
|
||
"github.com/spf13/cobra" | ||
|
||
"github.com/spacemeshos/go-spacemesh/common/types" | ||
"github.com/spacemeshos/go-spacemesh/vm/cmd/client/api" | ||
) | ||
|
||
var accountAddress string | ||
|
||
var accountInfoCmd = &cobra.Command{ | ||
Use: "accountInfo", | ||
Short: "A brief description of your command", | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
if accountAddress == "" { | ||
return errors.New("please provide account address to check with --account") | ||
} | ||
accountAddress, err := types.StringToAddress(accountAddress) | ||
if err != nil { | ||
return fmt.Errorf("cannot parse recipient address %q: %w", to, err) | ||
} | ||
account, err := api.AccountInfo(address, accountAddress) | ||
if err != nil { | ||
return err | ||
} | ||
fmt.Printf("template : %s\n", account.Template) | ||
fmt.Printf("current state : %s\n", account.Current.String()) | ||
fmt.Printf("projected state: %s\n", account.Projected.String()) | ||
|
||
return nil | ||
}, | ||
} | ||
|
||
func init() { | ||
rootCmd.AddCommand(accountInfoCmd) | ||
accountInfoCmd.Flags().StringVar(&accountAddress, "account", "", "account address to check") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package cmd | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/spf13/cobra" | ||
|
||
"github.com/spacemeshos/go-spacemesh/signing" | ||
"github.com/spacemeshos/go-spacemesh/vm/sdk/wallet" | ||
) | ||
|
||
var coinbaseCmd = &cobra.Command{ | ||
Use: "coinbase", | ||
Short: "print coinbase for the chosen key (assuming the singlesig wallet template)", | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
key, err := getKey(0) | ||
if err != nil { | ||
return err | ||
} | ||
address := wallet.Address(signing.Public(key)) | ||
|
||
fmt.Printf("coinbase: %s\n", address.String()) | ||
return nil | ||
}, | ||
} | ||
|
||
func init() { | ||
rootCmd.AddCommand(coinbaseCmd) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
package cmd | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"math" | ||
"os" | ||
|
||
"github.com/spf13/cobra" | ||
"go.uber.org/zap" | ||
|
||
"github.com/spacemeshos/go-spacemesh/common/types" | ||
"github.com/spacemeshos/go-spacemesh/signing" | ||
"github.com/spacemeshos/go-spacemesh/vm/cmd/client/api" | ||
"github.com/spacemeshos/go-spacemesh/vm/core" | ||
"github.com/spacemeshos/go-spacemesh/vm/sdk/wallet" | ||
) | ||
|
||
var path string | ||
|
||
// deployCmd represents the deploy command. | ||
var deployCmd = &cobra.Command{ | ||
Use: "deploy", | ||
Short: "A brief description of your command", | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
if nonce == math.MaxUint64 { | ||
return errors.New("provide nonce counter with --nonce") | ||
} | ||
key, err := getKey(0) | ||
if err != nil { | ||
return err | ||
} | ||
return deploy(key, nonce, path) | ||
}, | ||
} | ||
|
||
func init() { | ||
rootCmd.AddCommand(deployCmd) | ||
deployCmd.Flags().StringVar(&path, "path", "", "path to contract template to deploy") | ||
} | ||
|
||
func deploy(principal signing.PrivateKey, nonce uint64, path string) error { | ||
logger, err := zap.NewDevelopment() | ||
if err != nil { | ||
return err | ||
} | ||
principialPubkey := signing.Public(principal) | ||
principialAddress := wallet.Address(principialPubkey) | ||
|
||
blob, err := os.ReadFile(path) | ||
if err != nil { | ||
return fmt.Errorf("reading contract from %s: %w", path, err) | ||
} | ||
tx, err := wallet.Deploy(principal, nonce, blob) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
logger.Info("deploying contract", | ||
zap.Stringer("ID", types.NewRawTx(tx).ID), | ||
zap.Stringer("principal", principialAddress), | ||
zap.Stringer("template address", core.TemplateAddress(blob)), | ||
) | ||
|
||
if draft { | ||
logger.Info("not submitting TX in draft mode") | ||
return nil | ||
} | ||
return api.Submit(address, tx, logger) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package cmd | ||
|
||
import ( | ||
"log" | ||
|
||
"github.com/spf13/cobra" | ||
|
||
"github.com/spacemeshos/go-spacemesh/signing" | ||
) | ||
|
||
var file string | ||
|
||
var generateKeyCmd = &cobra.Command{ | ||
Use: "generateKey", | ||
Short: "Generate a keypair for signing transacations", | ||
Run: func(cmd *cobra.Command, args []string) { | ||
_, err := signing.NewEdSigner(signing.ToFile(file)) | ||
if err != nil { | ||
log.Fatalf("failed to create keys: %s", err.Error()) | ||
} | ||
}, | ||
} | ||
|
||
func init() { | ||
rootCmd.AddCommand(generateKeyCmd) | ||
|
||
generateKeyCmd.Flags().StringVar(&file, "file", "key.hex", "file to save the keys in") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package cmd | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"math" | ||
"os" | ||
|
||
"github.com/spf13/cobra" | ||
|
||
"github.com/spacemeshos/go-spacemesh/signing" | ||
) | ||
|
||
var ( | ||
draft bool | ||
nonce uint64 | ||
address string | ||
keyFiles []string | ||
keys = make(map[int]signing.PrivateKey) | ||
) | ||
|
||
func getKey(i int) (signing.PrivateKey, error) { | ||
if k, ok := keys[i]; ok { | ||
return k, nil | ||
} | ||
if len(keyFiles) < i { | ||
return nil, errors.New("key file was not provided") | ||
} | ||
signer, err := signing.NewEdSigner(signing.FromFile(keyFiles[i])) | ||
if err != nil { | ||
return nil, fmt.Errorf("reading the key: %s", err) | ||
} | ||
keys[i] = signer.PrivateKey() | ||
return signer.PrivateKey(), nil | ||
} | ||
|
||
var rootCmd = &cobra.Command{ | ||
Use: "client", | ||
Short: "application to interact with transactions on an Athena network", | ||
} | ||
|
||
// Execute adds all child commands to the root command and sets flags appropriately. | ||
// This is called by main.main(). It only needs to happen once to the rootCmd. | ||
func Execute() { | ||
err := rootCmd.Execute() | ||
if err != nil { | ||
os.Exit(1) | ||
} | ||
} | ||
|
||
func init() { | ||
rootCmd.PersistentFlags().BoolVar(&draft, "draft", false, "prepare and print but do not submit the TX") | ||
rootCmd.PersistentFlags().Uint64Var(&nonce, "nonce", math.MaxUint64, "Nonce for the spawn transaction") | ||
rootCmd.PersistentFlags(). | ||
StringVar(&address, "address", "localhost:9092", "Address of the node to submit the TX to") | ||
rootCmd.PersistentFlags(). | ||
StringSliceVarP(&keyFiles, "principal-key", "p", []string{"key.hex"}, "path to file with the principal key") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package cmd | ||
|
||
import ( | ||
"errors" | ||
"math" | ||
|
||
"github.com/spf13/cobra" | ||
"go.uber.org/zap" | ||
|
||
"github.com/spacemeshos/go-spacemesh/common/types" | ||
"github.com/spacemeshos/go-spacemesh/signing" | ||
"github.com/spacemeshos/go-spacemesh/vm/cmd/client/api" | ||
"github.com/spacemeshos/go-spacemesh/vm/sdk/wallet" | ||
) | ||
|
||
// spawnCmd represents the spawn command. | ||
var spawnCmd = &cobra.Command{ | ||
Use: "spawn", | ||
Short: "spawn a wallet account", | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
if nonce == math.MaxUint64 { | ||
return errors.New("provide nonce counter with --nonce") | ||
} | ||
key, err := getKey(0) | ||
if err != nil { | ||
return err | ||
} | ||
return spawn(address, key, nonce) | ||
}, | ||
} | ||
|
||
func init() { | ||
rootCmd.AddCommand(spawnCmd) | ||
} | ||
|
||
func spawn(address string, privKey signing.PrivateKey, nonce uint64) error { | ||
logger, err := zap.NewDevelopment() | ||
if err != nil { | ||
return err | ||
} | ||
principialPubkey := signing.Public(privKey) | ||
principalAddress := wallet.Address(principialPubkey) | ||
tx, err := wallet.Spawn(privKey, nonce) | ||
if err != nil { | ||
return err | ||
} | ||
logger.Info( | ||
"spawning account", | ||
zap.Stringer("address", principalAddress), | ||
zap.Stringer("id", types.NewRawTx(tx).ID), | ||
) | ||
|
||
if draft { | ||
logger.Info("not submitting TX in draft mode") | ||
return nil | ||
} | ||
return api.Submit(address, tx, logger) | ||
} |
Oops, something went wrong.