From 0297cee56bd55e6b20ab3b1f1aaa8e4aa6a2c185 Mon Sep 17 00:00:00 2001 From: Lane Rettig Date: Fri, 14 Jul 2023 06:25:40 -0400 Subject: [PATCH 1/7] Print spacemesh wallet address --- cmd/wallet.go | 12 ++++++++---- wallet/wallet.go | 10 ++++++++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/cmd/wallet.go b/cmd/wallet.go index a19d22b..f93daa4 100644 --- a/cmd/wallet.go +++ b/cmd/wallet.go @@ -196,10 +196,9 @@ only child keys).`, // full key is 64 bytes which is 128 chars in hex, need to print at least this much maxWidth = 150 } - // TODO: add spacemesh address format (bech32) - // https://github.com/spacemeshos/smcli/issues/38 if printPrivate { t.AppendHeader(table.Row{ + "address", "pubkey", "privkey", "path", @@ -207,18 +206,19 @@ only child keys).`, "created", }) t.SetColumnConfigs([]table.ColumnConfig{ - {Number: 1, WidthMax: maxWidth, WidthMaxEnforcer: widthEnforcer}, {Number: 2, WidthMax: maxWidth, WidthMaxEnforcer: widthEnforcer}, + {Number: 3, WidthMax: maxWidth, WidthMaxEnforcer: widthEnforcer}, }) } else { t.AppendHeader(table.Row{ + "address", "pubkey", "path", "name", "created", }) t.SetColumnConfigs([]table.ColumnConfig{ - {Number: 1, WidthMax: maxWidth, WidthMaxEnforcer: widthEnforcer}, + {Number: 2, WidthMax: maxWidth, WidthMaxEnforcer: widthEnforcer}, }) } @@ -241,6 +241,7 @@ only child keys).`, if master != nil { if printPrivate { t.AppendRow(table.Row{ + "N/A", encoder(master.Public), privKeyEncoder(master.Private), master.Path.String(), @@ -249,6 +250,7 @@ only child keys).`, }) } else { t.AppendRow(table.Row{ + "N/A", encoder(master.Public), master.Path.String(), master.DisplayName, @@ -262,6 +264,7 @@ only child keys).`, for _, a := range w.Secrets.Accounts { if printPrivate { t.AppendRow(table.Row{ + wallet.PubkeyToAddress(a.Public), encoder(a.Public), privKeyEncoder(a.Private), a.Path.String(), @@ -270,6 +273,7 @@ only child keys).`, }) } else { t.AppendRow(table.Row{ + wallet.PubkeyToAddress(a.Public), encoder(a.Public), a.Path.String(), a.DisplayName, diff --git a/wallet/wallet.go b/wallet/wallet.go index a91d45a..228b437 100644 --- a/wallet/wallet.go +++ b/wallet/wallet.go @@ -5,6 +5,8 @@ import ( "encoding/hex" "encoding/json" "fmt" + "github.com/spacemeshos/go-spacemesh/genvm/core" + "github.com/spacemeshos/go-spacemesh/genvm/templates/wallet" "strings" "github.com/tyler-smith/go-bip39" @@ -170,3 +172,11 @@ func accountsFromMaster(masterKeypair *EDKeyPair, masterSeed []byte, n int) (acc func (w *Wallet) Mnemonic() string { return w.Secrets.Mnemonic } + +func PubkeyToAddress(pubkey []byte) string { + key := [ed25519.PublicKeySize]byte{} + copy(key[:], pubkey) + walletArgs := &wallet.SpawnArguments{PublicKey: key} + walletAddress := core.ComputePrincipal(wallet.TemplateAddress, walletArgs) + return walletAddress.String() +} From 6486fba1eaa8c9cb2c85d0756848302e4f2f75a1 Mon Sep 17 00:00:00 2001 From: Lane Rettig Date: Fri, 14 Jul 2023 06:28:28 -0400 Subject: [PATCH 2/7] Clearer naming --- wallet/wallet.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wallet/wallet.go b/wallet/wallet.go index 228b437..f3ef741 100644 --- a/wallet/wallet.go +++ b/wallet/wallet.go @@ -6,7 +6,7 @@ import ( "encoding/json" "fmt" "github.com/spacemeshos/go-spacemesh/genvm/core" - "github.com/spacemeshos/go-spacemesh/genvm/templates/wallet" + walletTemplate "github.com/spacemeshos/go-spacemesh/genvm/templates/wallet" "strings" "github.com/tyler-smith/go-bip39" @@ -176,7 +176,7 @@ func (w *Wallet) Mnemonic() string { func PubkeyToAddress(pubkey []byte) string { key := [ed25519.PublicKeySize]byte{} copy(key[:], pubkey) - walletArgs := &wallet.SpawnArguments{PublicKey: key} - walletAddress := core.ComputePrincipal(wallet.TemplateAddress, walletArgs) + walletArgs := &walletTemplate.SpawnArguments{PublicKey: key} + walletAddress := core.ComputePrincipal(walletTemplate.TemplateAddress, walletArgs) return walletAddress.String() } From 26f0f0a25e802353d584c86b587b3470b1b0e31e Mon Sep 17 00:00:00 2001 From: Lane Rettig Date: Fri, 14 Jul 2023 06:43:01 -0400 Subject: [PATCH 3/7] linter --- wallet/wallet.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wallet/wallet.go b/wallet/wallet.go index f3ef741..f950edd 100644 --- a/wallet/wallet.go +++ b/wallet/wallet.go @@ -5,9 +5,10 @@ import ( "encoding/hex" "encoding/json" "fmt" + "strings" + "github.com/spacemeshos/go-spacemesh/genvm/core" walletTemplate "github.com/spacemeshos/go-spacemesh/genvm/templates/wallet" - "strings" "github.com/tyler-smith/go-bip39" From b420b0ee44112c8051b8c43ef3f10fb5ddfd8a13 Mon Sep 17 00:00:00 2001 From: Lane Rettig Date: Fri, 14 Jul 2023 06:46:45 -0400 Subject: [PATCH 4/7] linter --- wallet/wallet.go | 1 - 1 file changed, 1 deletion(-) diff --git a/wallet/wallet.go b/wallet/wallet.go index f950edd..d52b4e1 100644 --- a/wallet/wallet.go +++ b/wallet/wallet.go @@ -9,7 +9,6 @@ import ( "github.com/spacemeshos/go-spacemesh/genvm/core" walletTemplate "github.com/spacemeshos/go-spacemesh/genvm/templates/wallet" - "github.com/tyler-smith/go-bip39" "github.com/spacemeshos/smcli/common" From e068fdd85bbb2d75af0cd306783fe75dcd8e175a Mon Sep 17 00:00:00 2001 From: Lane Rettig Date: Fri, 14 Jul 2023 06:50:28 -0400 Subject: [PATCH 5/7] Add test --- wallet/wallet_test.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/wallet/wallet_test.go b/wallet/wallet_test.go index 5c46a98..d76efc6 100644 --- a/wallet/wallet_test.go +++ b/wallet/wallet_test.go @@ -88,6 +88,11 @@ func TestWalletFromGivenMnemonic(t *testing.T) { // Sanity check that the keypair works with the standard ed25519 library sig := ed25519.Sign(ed25519.PrivateKey(w.Secrets.Accounts[0].Private), msg) require.True(t, ed25519.Verify(ed25519.PublicKey(w.Secrets.Accounts[0].Public), msg, sig)) + + // Test conversion to a Spacemesh wallet address + expAddress := "sm1qqqqqqz9rf583slhn38g6q6a562ctltv9fv5w8q2gdz9k" + address := PubkeyToAddress(w.Secrets.Accounts[0].Public) + require.Equal(t, expAddress, address) } func TestKeysInWalletMaintainExpectedPath(t *testing.T) { From e7a3f24ac4587e095f76f1dfd91bc54391c33687 Mon Sep 17 00:00:00 2001 From: Lane Rettig Date: Fri, 14 Jul 2023 06:57:14 -0400 Subject: [PATCH 6/7] Add HRP support --- cmd/wallet.go | 9 +++++++-- wallet/wallet.go | 4 +++- wallet/wallet_test.go | 7 ++++++- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/cmd/wallet.go b/cmd/wallet.go index f93daa4..7b78b03 100644 --- a/cmd/wallet.go +++ b/cmd/wallet.go @@ -14,6 +14,7 @@ import ( "github.com/jedib0t/go-pretty/v6/table" "github.com/spf13/cobra" + "github.com/spacemeshos/go-spacemesh/common/types" "github.com/spacemeshos/smcli/common" "github.com/spacemeshos/smcli/wallet" ) @@ -36,6 +37,9 @@ var ( // useLedger indicates that the Ledger device should be used. useLedger bool + + // hrp is the human-readable network identifier used in Spacemesh network addresses + hrp string ) // walletCmd represents the wallet command. @@ -264,7 +268,7 @@ only child keys).`, for _, a := range w.Secrets.Accounts { if printPrivate { t.AppendRow(table.Row{ - wallet.PubkeyToAddress(a.Public), + wallet.PubkeyToAddress(a.Public, hrp), encoder(a.Public), privKeyEncoder(a.Private), a.Path.String(), @@ -273,7 +277,7 @@ only child keys).`, }) } else { t.AppendRow(table.Row{ - wallet.PubkeyToAddress(a.Public), + wallet.PubkeyToAddress(a.Public, hrp), encoder(a.Public), a.Path.String(), a.DisplayName, @@ -293,6 +297,7 @@ func init() { readCmd.Flags().BoolVarP(&printFull, "full", "f", false, "Print full keys (no abbreviation)") readCmd.Flags().BoolVar(&printBase58, "base58", false, "Print keys in base58 (rather than hex)") readCmd.Flags().BoolVar(&printParent, "parent", false, "Print parent key (not only child keys)") + readCmd.Flags().StringVar(&hrp, "hrp", types.NetworkHRP(), "Set human-readable address prefix") readCmd.PersistentFlags().BoolVarP(&debug, "debug", "d", false, "enable debug mode") createCmd.Flags().BoolVarP(&useLedger, "ledger", "l", false, "Create a wallet using a Ledger device") } diff --git a/wallet/wallet.go b/wallet/wallet.go index d52b4e1..5849d21 100644 --- a/wallet/wallet.go +++ b/wallet/wallet.go @@ -7,6 +7,7 @@ import ( "fmt" "strings" + "github.com/spacemeshos/go-spacemesh/common/types" "github.com/spacemeshos/go-spacemesh/genvm/core" walletTemplate "github.com/spacemeshos/go-spacemesh/genvm/templates/wallet" "github.com/tyler-smith/go-bip39" @@ -173,7 +174,8 @@ func (w *Wallet) Mnemonic() string { return w.Secrets.Mnemonic } -func PubkeyToAddress(pubkey []byte) string { +func PubkeyToAddress(pubkey []byte, hrp string) string { + types.SetNetworkHRP(hrp) key := [ed25519.PublicKeySize]byte{} copy(key[:], pubkey) walletArgs := &walletTemplate.SpawnArguments{PublicKey: key} diff --git a/wallet/wallet_test.go b/wallet/wallet_test.go index d76efc6..cbff256 100644 --- a/wallet/wallet_test.go +++ b/wallet/wallet_test.go @@ -4,6 +4,7 @@ import ( "crypto/ed25519" "encoding/hex" "fmt" + "github.com/spacemeshos/go-spacemesh/common/types" "testing" "github.com/stretchr/testify/require" @@ -91,8 +92,12 @@ func TestWalletFromGivenMnemonic(t *testing.T) { // Test conversion to a Spacemesh wallet address expAddress := "sm1qqqqqqz9rf583slhn38g6q6a562ctltv9fv5w8q2gdz9k" - address := PubkeyToAddress(w.Secrets.Accounts[0].Public) + address := PubkeyToAddress(w.Secrets.Accounts[0].Public, types.NetworkHRP()) require.Equal(t, expAddress, address) + + expAddressTestnet := "stest1qqqqqqz9rf583slhn38g6q6a562ctltv9fv5w8qha56t0" + addressTestnet := PubkeyToAddress(w.Secrets.Accounts[0].Public, "stest") + require.Equal(t, expAddressTestnet, addressTestnet) } func TestKeysInWalletMaintainExpectedPath(t *testing.T) { From 5ce13e8ba7696302af8e365301d9a8eb07d101c5 Mon Sep 17 00:00:00 2001 From: Lane Rettig Date: Fri, 14 Jul 2023 06:57:46 -0400 Subject: [PATCH 7/7] linter --- cmd/wallet.go | 4 ++-- wallet/wallet_test.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/wallet.go b/cmd/wallet.go index 7b78b03..795e146 100644 --- a/cmd/wallet.go +++ b/cmd/wallet.go @@ -12,9 +12,9 @@ import ( "github.com/btcsuite/btcutil/base58" "github.com/hashicorp/go-secure-stdlib/password" "github.com/jedib0t/go-pretty/v6/table" + "github.com/spacemeshos/go-spacemesh/common/types" "github.com/spf13/cobra" - "github.com/spacemeshos/go-spacemesh/common/types" "github.com/spacemeshos/smcli/common" "github.com/spacemeshos/smcli/wallet" ) @@ -38,7 +38,7 @@ var ( // useLedger indicates that the Ledger device should be used. useLedger bool - // hrp is the human-readable network identifier used in Spacemesh network addresses + // hrp is the human-readable network identifier used in Spacemesh network addresses. hrp string ) diff --git a/wallet/wallet_test.go b/wallet/wallet_test.go index cbff256..663c82a 100644 --- a/wallet/wallet_test.go +++ b/wallet/wallet_test.go @@ -4,9 +4,9 @@ import ( "crypto/ed25519" "encoding/hex" "fmt" - "github.com/spacemeshos/go-spacemesh/common/types" "testing" + "github.com/spacemeshos/go-spacemesh/common/types" "github.com/stretchr/testify/require" "github.com/tyler-smith/go-bip39" )