Skip to content

Commit

Permalink
Merge pull request oasisprotocol/oasis-sdk#1087
Browse files Browse the repository at this point in the history
  • Loading branch information
matevz committed Sep 16, 2022
2 parents 9ff19cd + b4353d8 commit be3e320
Show file tree
Hide file tree
Showing 12 changed files with 390 additions and 31 deletions.
16 changes: 3 additions & 13 deletions cmd/accounts.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import (
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/helpers"
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/modules/accounts"
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/modules/consensusaccounts"
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/testing"
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/types"
)

Expand Down Expand Up @@ -400,18 +399,7 @@ var (
addrToCheck = addr.String()
}

// Safety check for withdrawals to known accounts that are not supported on the consensus layer.
for name, acc := range cliConfig.Global().Wallet.All {
if acc.Address == addrToCheck && !acc.HasConsensusSigner() {
cobra.CheckErr(fmt.Errorf("account '%s' (%s) will not be able to sign transactions on consensus layer", name, acc.Address))
}
}
for name := range testing.TestAccounts {
testAcc, _ := common.LoadTestAccount(name)
if testAcc.Address().String() == addrToCheck && testAcc.ConsensusSigner() == nil {
cobra.CheckErr(fmt.Errorf("test account '%s' (%s) will not be able to sign transactions on consensus layer", name, testAcc.Address().String()))
}
}
cobra.CheckErr(common.CheckLocalAccountIsConsensusCapable(cfg, addrToCheck))

// Parse amount.
// TODO: This should actually query the ParaTime (or config) to check what the consensus
Expand Down Expand Up @@ -501,6 +489,8 @@ var (
var sigTx, meta interface{}
switch npa.ParaTime {
case nil:
cobra.CheckErr(common.CheckLocalAccountIsConsensusCapable(cfg, toAddr.String()))

// Consensus layer transfer.
amount, err := helpers.ParseConsensusDenomination(npa.Network, amount)
cobra.CheckErr(err)
Expand Down
127 changes: 127 additions & 0 deletions cmd/addressbook.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
package cmd

import (
"fmt"
"sort"

"github.com/spf13/cobra"

"github.com/oasisprotocol/oasis-sdk/cli/config"
"github.com/oasisprotocol/oasis-sdk/cli/table"
)

var (
addressBookCmd = &cobra.Command{
Use: "addressbook",
Short: "Manage addresses in the local address book",
}

abListCmd = &cobra.Command{
Use: "list",
Aliases: []string{"ls"},
Short: "List addresses stored in address book",
Args: cobra.NoArgs,
Run: func(cmd *cobra.Command, args []string) {
cfg := config.Global()
table := table.New()
table.SetHeader([]string{"Name", "Address"})

var output [][]string
for name, acc := range cfg.AddressBook.All {
addrStr := acc.Address
if ethAddr := acc.GetEthAddress(); ethAddr != nil {
addrStr = ethAddr.Hex()
}
output = append(output, []string{
name,
addrStr,
})
}

// Sort output by name.
sort.Slice(output, func(i, j int) bool {
return output[i][0] < output[j][0]
})

table.AppendBulk(output)
table.Render()
},
}

abAddCmd = &cobra.Command{
Use: "add <name> <address>",
Short: "Add an address to address book",
Args: cobra.ExactArgs(2),
Run: func(cmd *cobra.Command, args []string) {
cfg := config.Global()
name := args[0]
address := args[1]

err := cfg.AddressBook.Add(name, address)
cobra.CheckErr(err)

err = cfg.Save()
cobra.CheckErr(err)
},
}

abShowCmd = &cobra.Command{
Use: "show <name>",
Short: "Show address information",
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
name := args[0]
abEntry, ok := config.Global().AddressBook.All[name]
if !ok {
cobra.CheckErr(fmt.Errorf("address named '%s' does not exist in the address book", name))
}

fmt.Printf("Name: %s\n", name)
if abEntry.GetEthAddress() != nil {
fmt.Printf("Ethereum address: %s\n", abEntry.GetEthAddress().Hex())
}
fmt.Printf("Native address: %s\n", abEntry.GetAddress())
},
}

abRmCmd = &cobra.Command{
Use: "rm <name>",
Aliases: []string{"remove"},
Short: "Remove an address from address book",
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
cfg := config.Global()
name := args[0]

err := cfg.AddressBook.Remove(name)
cobra.CheckErr(err)

err = cfg.Save()
cobra.CheckErr(err)
},
}

abRenameCmd = &cobra.Command{
Use: "rename <old> <new>",
Short: "Rename address",
Args: cobra.ExactArgs(2),
Run: func(cmd *cobra.Command, args []string) {
cfg := config.Global()
oldName, newName := args[0], args[1]

err := cfg.AddressBook.Rename(oldName, newName)
cobra.CheckErr(err)

err = cfg.Save()
cobra.CheckErr(err)
},
}
)

func init() {
addressBookCmd.AddCommand(abAddCmd)
addressBookCmd.AddCommand(abListCmd)
addressBookCmd.AddCommand(abRenameCmd)
addressBookCmd.AddCommand(abRmCmd)
addressBookCmd.AddCommand(abShowCmd)
}
34 changes: 33 additions & 1 deletion cmd/common/wallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,43 @@ func LoadTestAccountConfig(name string) (*config.Account, error) {

// ResolveLocalAccountOrAddress resolves a string address into the corresponding account address.
func ResolveLocalAccountOrAddress(net *configSdk.Network, address string) (*types.Address, error) {
// Check, if address is the account name in the wallet.
// Check if address is the account name in the wallet.
if acc, ok := config.Global().Wallet.All[address]; ok {
addr := acc.GetAddress()
return &addr, nil
}

// Check if address is the name of an address book entry.
if entry, ok := config.Global().AddressBook.All[address]; ok {
addr := entry.GetAddress()
return &addr, nil
}

return helpers.ResolveAddress(net, address)
}

// CheckLocalAccountIsConsensusCapable is a safety check for withdrawals or consensus layer
// transfers to potentially known native addresses which key pairs are not compatible with
// consensus or the address is a derivation of a known Ethereum address.
func CheckLocalAccountIsConsensusCapable(cfg *config.Config, address string) error {
for name, acc := range cfg.Wallet.All {
if acc.Address == address && !acc.HasConsensusSigner() {
return fmt.Errorf("destination account '%s' (%s) will not be able to sign transactions on consensus layer", name, acc.Address)
}
}

for name := range testing.TestAccounts {
testAcc, _ := LoadTestAccount(name)
if testAcc.Address().String() == address && testAcc.ConsensusSigner() == nil {
return fmt.Errorf("test account '%s' (%s) will not be able to sign transactions on consensus layer", name, testAcc.Address().String())
}
}

for name, acc := range cfg.AddressBook.All {
if acc.Address == address && acc.GetEthAddress() != nil {
return fmt.Errorf("destination address named '%s' (%s) will not be able to sign transactions on consensus layer", name, acc.GetEthAddress().Hex())
}
}

return nil
}
1 change: 1 addition & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ func init() {
rootCmd.AddCommand(paratimeCmd)
rootCmd.AddCommand(walletCmd)
rootCmd.AddCommand(accountsCmd)
rootCmd.AddCommand(addressBookCmd)
rootCmd.AddCommand(contractsCmd)
rootCmd.AddCommand(inspect.Cmd)
}
28 changes: 18 additions & 10 deletions cmd/wallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import (
"github.com/oasisprotocol/oasis-sdk/cli/table"
"github.com/oasisprotocol/oasis-sdk/cli/wallet"
walletFile "github.com/oasisprotocol/oasis-sdk/cli/wallet/file"
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/helpers"
)

var (
Expand Down Expand Up @@ -88,6 +87,9 @@ var (
err = accCfg.SetConfigFromFlags()
cobra.CheckErr(err)

if _, exists := cfg.AddressBook.All[name]; exists {
cobra.CheckErr(fmt.Errorf("address named '%s' already exists in address book", name))
}
err = cfg.Wallet.Create(name, passphrase, accCfg)
cobra.CheckErr(err)

Expand All @@ -104,7 +106,7 @@ var (
name := args[0]

acc := common.LoadAccount(config.Global(), name)
showPublicWalletInfo(acc)
showPublicWalletInfo(name, acc)
},
}

Expand Down Expand Up @@ -186,7 +188,10 @@ var (
name := args[0]

if _, exists := cfg.Wallet.All[name]; exists {
cobra.CheckErr(fmt.Errorf("account '%s' already exists", name))
cobra.CheckErr(fmt.Errorf("account '%s' already exists in the wallet", name))
}
if _, exists := cfg.AddressBook.All[name]; exists {
cobra.CheckErr(fmt.Errorf("address named '%s' already exists in the address book", name))
}

// NOTE: We only support importing into the file-based wallet for now.
Expand All @@ -201,7 +206,7 @@ var (

var kindRaw string
err = survey.AskOne(&survey.Select{
Message: "Import kind:",
Message: "Kind:",
Options: supportedKinds,
}, &kindRaw)
cobra.CheckErr(err)
Expand Down Expand Up @@ -258,7 +263,7 @@ var (
fmt.Printf("WARNING: Exporting the account will expose secret key material!\n")
acc := common.LoadAccount(config.Global(), name)

showPublicWalletInfo(acc)
showPublicWalletInfo(name, acc)

fmt.Printf("Export:\n")
fmt.Println(acc.UnsafeExport())
Expand Down Expand Up @@ -349,12 +354,15 @@ func (sf *accountEntitySignerFactory) Load(
return sf.signer, nil
}

func showPublicWalletInfo(wallet wallet.Account) {
fmt.Printf("Public Key: %s\n", wallet.Signer().Public())
fmt.Printf("Address: %s\n", wallet.Address())
if wallet.SignatureAddressSpec().Secp256k1Eth != nil {
fmt.Printf("Ethereum address: %s\n", helpers.EthAddressFromPubKey(*wallet.SignatureAddressSpec().Secp256k1Eth))
func showPublicWalletInfo(name string, wallet wallet.Account) {
fmt.Printf("Name: %s\n", name)
if signer := wallet.Signer(); signer != nil {
fmt.Printf("Public Key: %s\n", signer.Public())
}
if ethAddr := wallet.EthAddress(); ethAddr != nil {
fmt.Printf("Ethereum address: %s\n", ethAddr.Hex())
}
fmt.Printf("Native address: %s\n", wallet.Address())
}

func init() {
Expand Down
Loading

0 comments on commit be3e320

Please sign in to comment.