cmd/clef: add list-accounts
and list-wallets
to CLI (#26080)
This commit adds support for two new commands to clef, making it possible to list accounts / wallets from the command-line-interface. Co-authored-by: Martin Holst Swende <martin@swende.se>
This commit is contained in:
parent
05037eaffc
commit
f3a005f176
125
cmd/clef/main.go
125
cmd/clef/main.go
@ -203,9 +203,8 @@ The delpw command removes a password for a given address (keyfile).
|
|||||||
},
|
},
|
||||||
Description: `
|
Description: `
|
||||||
The newaccount command creates a new keystore-backed account. It is a convenience-method
|
The newaccount command creates a new keystore-backed account. It is a convenience-method
|
||||||
which can be used in lieu of an external UI.`,
|
which can be used in lieu of an external UI.
|
||||||
}
|
`}
|
||||||
|
|
||||||
gendocCommand = &cli.Command{
|
gendocCommand = &cli.Command{
|
||||||
Action: GenDoc,
|
Action: GenDoc,
|
||||||
Name: "gendoc",
|
Name: "gendoc",
|
||||||
@ -213,6 +212,32 @@ which can be used in lieu of an external UI.`,
|
|||||||
Description: `
|
Description: `
|
||||||
The gendoc generates example structures of the json-rpc communication types.
|
The gendoc generates example structures of the json-rpc communication types.
|
||||||
`}
|
`}
|
||||||
|
listAccountsCommand = &cli.Command{
|
||||||
|
Action: listAccounts,
|
||||||
|
Name: "list-accounts",
|
||||||
|
Usage: "List accounts in the keystore",
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
logLevelFlag,
|
||||||
|
keystoreFlag,
|
||||||
|
utils.LightKDFFlag,
|
||||||
|
acceptFlag,
|
||||||
|
},
|
||||||
|
Description: `
|
||||||
|
Lists the accounts in the keystore.
|
||||||
|
`}
|
||||||
|
listWalletsCommand = &cli.Command{
|
||||||
|
Action: listWallets,
|
||||||
|
Name: "list-wallets",
|
||||||
|
Usage: "List wallets known to Clef",
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
logLevelFlag,
|
||||||
|
keystoreFlag,
|
||||||
|
utils.LightKDFFlag,
|
||||||
|
acceptFlag,
|
||||||
|
},
|
||||||
|
Description: `
|
||||||
|
Lists the wallets known to Clef.
|
||||||
|
`}
|
||||||
)
|
)
|
||||||
|
|
||||||
var app = flags.NewApp("Manage Ethereum account operations")
|
var app = flags.NewApp("Manage Ethereum account operations")
|
||||||
@ -249,6 +274,8 @@ func init() {
|
|||||||
delCredentialCommand,
|
delCredentialCommand,
|
||||||
newAccountCommand,
|
newAccountCommand,
|
||||||
gendocCommand,
|
gendocCommand,
|
||||||
|
listAccountsCommand,
|
||||||
|
listWalletsCommand,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -351,6 +378,22 @@ func attestFile(ctx *cli.Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func initInternalApi(c *cli.Context) (*core.UIServerAPI, error) {
|
||||||
|
if err := initialize(c); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var (
|
||||||
|
ui = core.NewCommandlineUI()
|
||||||
|
pwStorage storage.Storage = &storage.NoStorage{}
|
||||||
|
ksLoc = c.String(keystoreFlag.Name)
|
||||||
|
lightKdf = c.Bool(utils.LightKDFFlag.Name)
|
||||||
|
)
|
||||||
|
am := core.StartClefAccountManager(ksLoc, true, lightKdf, "")
|
||||||
|
api := core.NewSignerAPI(am, 0, true, ui, nil, false, pwStorage)
|
||||||
|
internalApi := core.NewUIServerAPI(api)
|
||||||
|
return internalApi, nil
|
||||||
|
}
|
||||||
|
|
||||||
func setCredential(ctx *cli.Context) error {
|
func setCredential(ctx *cli.Context) error {
|
||||||
if ctx.NArg() < 1 {
|
if ctx.NArg() < 1 {
|
||||||
utils.Fatalf("This command requires an address to be passed as an argument")
|
utils.Fatalf("This command requires an address to be passed as an argument")
|
||||||
@ -409,31 +452,6 @@ func removeCredential(ctx *cli.Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func newAccount(c *cli.Context) error {
|
|
||||||
if err := initialize(c); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// The newaccount is meant for users using the CLI, since 'real' external
|
|
||||||
// UIs can use the UI-api instead. So we'll just use the native CLI UI here.
|
|
||||||
var (
|
|
||||||
ui = core.NewCommandlineUI()
|
|
||||||
pwStorage storage.Storage = &storage.NoStorage{}
|
|
||||||
ksLoc = c.String(keystoreFlag.Name)
|
|
||||||
lightKdf = c.Bool(utils.LightKDFFlag.Name)
|
|
||||||
)
|
|
||||||
log.Info("Starting clef", "keystore", ksLoc, "light-kdf", lightKdf)
|
|
||||||
am := core.StartClefAccountManager(ksLoc, true, lightKdf, "")
|
|
||||||
// This gives is us access to the external API
|
|
||||||
apiImpl := core.NewSignerAPI(am, 0, true, ui, nil, false, pwStorage)
|
|
||||||
// This gives us access to the internal API
|
|
||||||
internalApi := core.NewUIServerAPI(apiImpl)
|
|
||||||
addr, err := internalApi.New(context.Background())
|
|
||||||
if err == nil {
|
|
||||||
fmt.Printf("Generated account %v\n", addr.String())
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func initialize(c *cli.Context) error {
|
func initialize(c *cli.Context) error {
|
||||||
// Set up the logger to print everything
|
// Set up the logger to print everything
|
||||||
logOutput := os.Stdout
|
logOutput := os.Stdout
|
||||||
@ -459,6 +477,57 @@ func initialize(c *cli.Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newAccount(c *cli.Context) error {
|
||||||
|
internalApi, err := initInternalApi(c)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
addr, err := internalApi.New(context.Background())
|
||||||
|
if err == nil {
|
||||||
|
fmt.Printf("Generated account %v\n", addr.String())
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func listAccounts(c *cli.Context) error {
|
||||||
|
internalApi, err := initInternalApi(c)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
accs, err := internalApi.ListAccounts(context.Background())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(accs) == 0 {
|
||||||
|
fmt.Println("\nThe keystore is empty.")
|
||||||
|
}
|
||||||
|
fmt.Println()
|
||||||
|
for _, account := range accs {
|
||||||
|
fmt.Printf("%v (%v)\n", account.Address, account.URL)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func listWallets(c *cli.Context) error {
|
||||||
|
internalApi, err := initInternalApi(c)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
wallets := internalApi.ListWallets()
|
||||||
|
if len(wallets) == 0 {
|
||||||
|
fmt.Println("\nThere are no wallets.")
|
||||||
|
}
|
||||||
|
fmt.Println()
|
||||||
|
for i, wallet := range wallets {
|
||||||
|
fmt.Printf("- Wallet %d at %v (%v %v)\n", i, wallet.URL, wallet.Status, wallet.Failure)
|
||||||
|
for j, acc := range wallet.Accounts {
|
||||||
|
fmt.Printf(" -Account %d: %v (%v)\n", j, acc.Address, acc.URL)
|
||||||
|
}
|
||||||
|
fmt.Println()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// ipcEndpoint resolves an IPC endpoint based on a configured value, taking into
|
// ipcEndpoint resolves an IPC endpoint based on a configured value, taking into
|
||||||
// account the set data folders as well as the designated platform we're currently
|
// account the set data folders as well as the designated platform we're currently
|
||||||
// running on.
|
// running on.
|
||||||
|
Loading…
Reference in New Issue
Block a user