Skip to content

Commit a1e889a

Browse files
authored
Merge pull request #67 from spacemeshos/print-address
Print spacemesh wallet address
2 parents 2781143 + 5ce13e8 commit a1e889a

3 files changed

Lines changed: 35 additions & 4 deletions

File tree

cmd/wallet.go

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"github.com/btcsuite/btcutil/base58"
1313
"github.com/hashicorp/go-secure-stdlib/password"
1414
"github.com/jedib0t/go-pretty/v6/table"
15+
"github.com/spacemeshos/go-spacemesh/common/types"
1516
"github.com/spf13/cobra"
1617

1718
"github.com/spacemeshos/smcli/common"
@@ -36,6 +37,9 @@ var (
3637

3738
// useLedger indicates that the Ledger device should be used.
3839
useLedger bool
40+
41+
// hrp is the human-readable network identifier used in Spacemesh network addresses.
42+
hrp string
3943
)
4044

4145
// walletCmd represents the wallet command.
@@ -196,29 +200,29 @@ only child keys).`,
196200
// full key is 64 bytes which is 128 chars in hex, need to print at least this much
197201
maxWidth = 150
198202
}
199-
// TODO: add spacemesh address format (bech32)
200-
// https://github.com/spacemeshos/smcli/issues/38
201203
if printPrivate {
202204
t.AppendHeader(table.Row{
205+
"address",
203206
"pubkey",
204207
"privkey",
205208
"path",
206209
"name",
207210
"created",
208211
})
209212
t.SetColumnConfigs([]table.ColumnConfig{
210-
{Number: 1, WidthMax: maxWidth, WidthMaxEnforcer: widthEnforcer},
211213
{Number: 2, WidthMax: maxWidth, WidthMaxEnforcer: widthEnforcer},
214+
{Number: 3, WidthMax: maxWidth, WidthMaxEnforcer: widthEnforcer},
212215
})
213216
} else {
214217
t.AppendHeader(table.Row{
218+
"address",
215219
"pubkey",
216220
"path",
217221
"name",
218222
"created",
219223
})
220224
t.SetColumnConfigs([]table.ColumnConfig{
221-
{Number: 1, WidthMax: maxWidth, WidthMaxEnforcer: widthEnforcer},
225+
{Number: 2, WidthMax: maxWidth, WidthMaxEnforcer: widthEnforcer},
222226
})
223227
}
224228

@@ -241,6 +245,7 @@ only child keys).`,
241245
if master != nil {
242246
if printPrivate {
243247
t.AppendRow(table.Row{
248+
"N/A",
244249
encoder(master.Public),
245250
privKeyEncoder(master.Private),
246251
master.Path.String(),
@@ -249,6 +254,7 @@ only child keys).`,
249254
})
250255
} else {
251256
t.AppendRow(table.Row{
257+
"N/A",
252258
encoder(master.Public),
253259
master.Path.String(),
254260
master.DisplayName,
@@ -262,6 +268,7 @@ only child keys).`,
262268
for _, a := range w.Secrets.Accounts {
263269
if printPrivate {
264270
t.AppendRow(table.Row{
271+
wallet.PubkeyToAddress(a.Public, hrp),
265272
encoder(a.Public),
266273
privKeyEncoder(a.Private),
267274
a.Path.String(),
@@ -270,6 +277,7 @@ only child keys).`,
270277
})
271278
} else {
272279
t.AppendRow(table.Row{
280+
wallet.PubkeyToAddress(a.Public, hrp),
273281
encoder(a.Public),
274282
a.Path.String(),
275283
a.DisplayName,
@@ -289,6 +297,7 @@ func init() {
289297
readCmd.Flags().BoolVarP(&printFull, "full", "f", false, "Print full keys (no abbreviation)")
290298
readCmd.Flags().BoolVar(&printBase58, "base58", false, "Print keys in base58 (rather than hex)")
291299
readCmd.Flags().BoolVar(&printParent, "parent", false, "Print parent key (not only child keys)")
300+
readCmd.Flags().StringVar(&hrp, "hrp", types.NetworkHRP(), "Set human-readable address prefix")
292301
readCmd.PersistentFlags().BoolVarP(&debug, "debug", "d", false, "enable debug mode")
293302
createCmd.Flags().BoolVarP(&useLedger, "ledger", "l", false, "Create a wallet using a Ledger device")
294303
}

wallet/wallet.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ import (
77
"fmt"
88
"strings"
99

10+
"github.com/spacemeshos/go-spacemesh/common/types"
11+
"github.com/spacemeshos/go-spacemesh/genvm/core"
12+
walletTemplate "github.com/spacemeshos/go-spacemesh/genvm/templates/wallet"
1013
"github.com/tyler-smith/go-bip39"
1114

1215
"github.com/spacemeshos/smcli/common"
@@ -170,3 +173,12 @@ func accountsFromMaster(masterKeypair *EDKeyPair, masterSeed []byte, n int) (acc
170173
func (w *Wallet) Mnemonic() string {
171174
return w.Secrets.Mnemonic
172175
}
176+
177+
func PubkeyToAddress(pubkey []byte, hrp string) string {
178+
types.SetNetworkHRP(hrp)
179+
key := [ed25519.PublicKeySize]byte{}
180+
copy(key[:], pubkey)
181+
walletArgs := &walletTemplate.SpawnArguments{PublicKey: key}
182+
walletAddress := core.ComputePrincipal(walletTemplate.TemplateAddress, walletArgs)
183+
return walletAddress.String()
184+
}

wallet/wallet_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"fmt"
77
"testing"
88

9+
"github.com/spacemeshos/go-spacemesh/common/types"
910
"github.com/stretchr/testify/require"
1011
"github.com/tyler-smith/go-bip39"
1112
)
@@ -88,6 +89,15 @@ func TestWalletFromGivenMnemonic(t *testing.T) {
8889
// Sanity check that the keypair works with the standard ed25519 library
8990
sig := ed25519.Sign(ed25519.PrivateKey(w.Secrets.Accounts[0].Private), msg)
9091
require.True(t, ed25519.Verify(ed25519.PublicKey(w.Secrets.Accounts[0].Public), msg, sig))
92+
93+
// Test conversion to a Spacemesh wallet address
94+
expAddress := "sm1qqqqqqz9rf583slhn38g6q6a562ctltv9fv5w8q2gdz9k"
95+
address := PubkeyToAddress(w.Secrets.Accounts[0].Public, types.NetworkHRP())
96+
require.Equal(t, expAddress, address)
97+
98+
expAddressTestnet := "stest1qqqqqqz9rf583slhn38g6q6a562ctltv9fv5w8qha56t0"
99+
addressTestnet := PubkeyToAddress(w.Secrets.Accounts[0].Public, "stest")
100+
require.Equal(t, expAddressTestnet, addressTestnet)
91101
}
92102

93103
func TestKeysInWalletMaintainExpectedPath(t *testing.T) {

0 commit comments

Comments
 (0)