Skip to content

Commit

Permalink
Merge pull request #67 from spacemeshos/print-address
Browse files Browse the repository at this point in the history
Print spacemesh wallet address
  • Loading branch information
lrettig authored Jul 14, 2023
2 parents 2781143 + 5ce13e8 commit a1e889a
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 4 deletions.
17 changes: 13 additions & 4 deletions cmd/wallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ 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/smcli/common"
Expand All @@ -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.
Expand Down Expand Up @@ -196,29 +200,29 @@ 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",
"name",
"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},
})
}

Expand All @@ -241,6 +245,7 @@ only child keys).`,
if master != nil {
if printPrivate {
t.AppendRow(table.Row{
"N/A",
encoder(master.Public),
privKeyEncoder(master.Private),
master.Path.String(),
Expand All @@ -249,6 +254,7 @@ only child keys).`,
})
} else {
t.AppendRow(table.Row{
"N/A",
encoder(master.Public),
master.Path.String(),
master.DisplayName,
Expand All @@ -262,6 +268,7 @@ only child keys).`,
for _, a := range w.Secrets.Accounts {
if printPrivate {
t.AppendRow(table.Row{
wallet.PubkeyToAddress(a.Public, hrp),
encoder(a.Public),
privKeyEncoder(a.Private),
a.Path.String(),
Expand All @@ -270,6 +277,7 @@ only child keys).`,
})
} else {
t.AppendRow(table.Row{
wallet.PubkeyToAddress(a.Public, hrp),
encoder(a.Public),
a.Path.String(),
a.DisplayName,
Expand All @@ -289,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")
}
12 changes: 12 additions & 0 deletions wallet/wallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ 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"

"github.com/spacemeshos/smcli/common"
Expand Down Expand Up @@ -170,3 +173,12 @@ func accountsFromMaster(masterKeypair *EDKeyPair, masterSeed []byte, n int) (acc
func (w *Wallet) Mnemonic() string {
return w.Secrets.Mnemonic
}

func PubkeyToAddress(pubkey []byte, hrp string) string {
types.SetNetworkHRP(hrp)
key := [ed25519.PublicKeySize]byte{}
copy(key[:], pubkey)
walletArgs := &walletTemplate.SpawnArguments{PublicKey: key}
walletAddress := core.ComputePrincipal(walletTemplate.TemplateAddress, walletArgs)
return walletAddress.String()
}
10 changes: 10 additions & 0 deletions wallet/wallet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"
"testing"

"github.com/spacemeshos/go-spacemesh/common/types"
"github.com/stretchr/testify/require"
"github.com/tyler-smith/go-bip39"
)
Expand Down Expand Up @@ -88,6 +89,15 @@ 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, 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) {
Expand Down

0 comments on commit a1e889a

Please sign in to comment.