cmd/clef: add newaccount command (#20782)
* cmd/clef: add newaccount command * cmd/clef: document clef_New, update API versioning * Update cmd/clef/intapi_changelog.md Co-Authored-By: ligi <ligi@ligi.de> * Update signer/core/uiapi.go Co-Authored-By: ligi <ligi@ligi.de> Co-authored-by: ligi <ligi@ligi.de>
This commit is contained in:
parent
8f05cfa122
commit
c56f4fa808
|
@ -10,6 +10,17 @@ TL;DR: Given a version number MAJOR.MINOR.PATCH, increment the:
|
|||
|
||||
Additional labels for pre-release and build metadata are available as extensions to the MAJOR.MINOR.PATCH format.
|
||||
|
||||
### 7.0.1
|
||||
|
||||
Added `clef_New` to the internal API calleable from a UI.
|
||||
|
||||
> `New` creates a new password protected Account. The private key is protected with
|
||||
> the given password. Users are responsible to backup the private key that is stored
|
||||
> in the keystore location that was specified when this API was created.
|
||||
> This method is the same as New on the external API, the difference being that
|
||||
> this implementation does not ask for confirmation, since it's initiated by
|
||||
> the user
|
||||
|
||||
### 7.0.0
|
||||
|
||||
- The `message` field was renamed to `messages` in all data signing request methods to better reflect that it's a list, not a value.
|
||||
|
|
|
@ -187,6 +187,21 @@ The setpw command stores a password for a given address (keyfile).
|
|||
Description: `
|
||||
The delpw command removes a password for a given address (keyfile).
|
||||
`}
|
||||
newAccountCommand = cli.Command{
|
||||
Action: utils.MigrateFlags(newAccount),
|
||||
Name: "newaccount",
|
||||
Usage: "Create a new account",
|
||||
ArgsUsage: "",
|
||||
Flags: []cli.Flag{
|
||||
logLevelFlag,
|
||||
keystoreFlag,
|
||||
utils.LightKDFFlag,
|
||||
},
|
||||
Description: `
|
||||
The newaccount command creates a new keystore-backed account. It is a convenience-method
|
||||
which can be used in lieu of an external UI.`,
|
||||
}
|
||||
|
||||
gendocCommand = cli.Command{
|
||||
Action: GenDoc,
|
||||
Name: "gendoc",
|
||||
|
@ -222,7 +237,12 @@ func init() {
|
|||
advancedMode,
|
||||
}
|
||||
app.Action = signer
|
||||
app.Commands = []cli.Command{initCommand, attestCommand, setCredentialCommand, delCredentialCommand, gendocCommand}
|
||||
app.Commands = []cli.Command{initCommand,
|
||||
attestCommand,
|
||||
setCredentialCommand,
|
||||
delCredentialCommand,
|
||||
newAccountCommand,
|
||||
gendocCommand}
|
||||
cli.CommandHelpTemplate = utils.OriginCommandHelpTemplate
|
||||
}
|
||||
|
||||
|
@ -382,6 +402,31 @@ func removeCredential(ctx *cli.Context) error {
|
|||
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.GlobalString(keystoreFlag.Name)
|
||||
lightKdf = c.GlobalBool(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 {
|
||||
// Set up the logger to print everything
|
||||
logOutput := os.Stdout
|
||||
|
@ -457,7 +502,6 @@ func signer(c *cli.Context) error {
|
|||
api core.ExternalAPI
|
||||
pwStorage storage.Storage = &storage.NoStorage{}
|
||||
)
|
||||
|
||||
configDir := c.GlobalString(configdirFlag.Name)
|
||||
if stretchedKey, err := readMasterKey(c, ui); err != nil {
|
||||
log.Warn("Failed to open master, rules disabled", "err", err)
|
||||
|
|
|
@ -43,7 +43,7 @@ const (
|
|||
// ExternalAPIVersion -- see extapi_changelog.md
|
||||
ExternalAPIVersion = "6.0.0"
|
||||
// InternalAPIVersion -- see intapi_changelog.md
|
||||
InternalAPIVersion = "7.0.0"
|
||||
InternalAPIVersion = "7.0.1"
|
||||
)
|
||||
|
||||
// ExternalAPI defines the external API through which signing requests are made.
|
||||
|
@ -395,8 +395,7 @@ func (api *SignerAPI) List(ctx context.Context) ([]common.Address, error) {
|
|||
// the given password. Users are responsible to backup the private key that is stored
|
||||
// in the keystore location thas was specified when this API was created.
|
||||
func (api *SignerAPI) New(ctx context.Context) (common.Address, error) {
|
||||
be := api.am.Backends(keystore.KeyStoreType)
|
||||
if len(be) == 0 {
|
||||
if be := api.am.Backends(keystore.KeyStoreType); len(be) == 0 {
|
||||
return common.Address{}, errors.New("password based accounts not supported")
|
||||
}
|
||||
if resp, err := api.UI.ApproveNewAccount(&NewAccountRequest{MetadataFromContext(ctx)}); err != nil {
|
||||
|
@ -404,7 +403,16 @@ func (api *SignerAPI) New(ctx context.Context) (common.Address, error) {
|
|||
} else if !resp.Approved {
|
||||
return common.Address{}, ErrRequestDenied
|
||||
}
|
||||
return api.newAccount()
|
||||
}
|
||||
|
||||
// newAccount is the internal method to create a new account. It should be used
|
||||
// _after_ user-approval has been obtained
|
||||
func (api *SignerAPI) newAccount() (common.Address, error) {
|
||||
be := api.am.Backends(keystore.KeyStoreType)
|
||||
if len(be) == 0 {
|
||||
return common.Address{}, errors.New("password based accounts not supported")
|
||||
}
|
||||
// Three retries to get a valid password
|
||||
for i := 0; i < 3; i++ {
|
||||
resp, err := api.UI.OnInputRequired(UserInputRequest{
|
||||
|
|
|
@ -195,6 +195,16 @@ func (api *UIServerAPI) Import(ctx context.Context, keyJSON json.RawMessage, old
|
|||
return be[0].(*keystore.KeyStore).Import(keyJSON, oldPassphrase, newPassphrase)
|
||||
}
|
||||
|
||||
// New creates a new password protected Account. The private key is protected with
|
||||
// the given password. Users are responsible to backup the private key that is stored
|
||||
// in the keystore location that was specified when this API was created.
|
||||
// This method is the same as New on the external API, the difference being that
|
||||
// this implementation does not ask for confirmation, since it's initiated by
|
||||
// the user
|
||||
func (api *UIServerAPI) New(ctx context.Context) (common.Address, error) {
|
||||
return api.extApi.newAccount()
|
||||
}
|
||||
|
||||
// Other methods to be added, not yet implemented are:
|
||||
// - Ruleset interaction: add rules, attest rulefiles
|
||||
// - Store metadata about accounts, e.g. naming of accounts
|
||||
|
|
Loading…
Reference in New Issue