aboutsummaryrefslogtreecommitdiffstats
path: root/cmd/clef
diff options
context:
space:
mode:
authorMartin Holst Swende <martin@swende.se>2019-03-07 17:56:08 +0800
committerPéter Szilágyi <peterke@gmail.com>2019-03-07 17:56:08 +0800
commit5f94f8c7e7cfc6d037accfad379ce2ab0df6bf47 (patch)
treeac9db4d11def29b0c7fbd638567e05797d929678 /cmd/clef
parenteb199f1fc2fc91e40431c5acce61227a95d476bb (diff)
downloadgo-tangerine-5f94f8c7e7cfc6d037accfad379ce2ab0df6bf47.tar
go-tangerine-5f94f8c7e7cfc6d037accfad379ce2ab0df6bf47.tar.gz
go-tangerine-5f94f8c7e7cfc6d037accfad379ce2ab0df6bf47.tar.bz2
go-tangerine-5f94f8c7e7cfc6d037accfad379ce2ab0df6bf47.tar.lz
go-tangerine-5f94f8c7e7cfc6d037accfad379ce2ab0df6bf47.tar.xz
go-tangerine-5f94f8c7e7cfc6d037accfad379ce2ab0df6bf47.tar.zst
go-tangerine-5f94f8c7e7cfc6d037accfad379ce2ab0df6bf47.zip
signer: change the stdio jsonrpc to use legacy namespace conventions (#19047)
This PR will will break existing UIs, since it changes all calls like ApproveSignTransaction to be on the form ui_approveSignTransaction. This is to make it possible for the UI to reuse the json-rpc library from go-ethereum, which uses this convention. Also, this PR removes some unused structs, after import/export were removed from the external api (so no longer needs internal methods for approval) One more breaking change is introduced, removing passwords from the ApproveSignTxResponse and the likes. This makes the manual interface more like the rulebased interface, and integrates nicely with the credential storage. Thus, the way it worked before, it would be tempting for the UI to implement 'remember password' functionality. The way it is now, it will be easy instead to tell clef to store passwords and use them. If a pw is not found in the credential store, the user is prompted to provide the password.
Diffstat (limited to 'cmd/clef')
-rw-r--r--cmd/clef/README.md56
-rw-r--r--cmd/clef/datatypes.md33
-rw-r--r--cmd/clef/intapi_changelog.md35
-rw-r--r--cmd/clef/main.go226
4 files changed, 209 insertions, 141 deletions
diff --git a/cmd/clef/README.md b/cmd/clef/README.md
index 036e71b28..956957f3d 100644
--- a/cmd/clef/README.md
+++ b/cmd/clef/README.md
@@ -661,7 +661,7 @@ OBS! A slight deviation from `json` standard is in place: every request and resp
Whereas the `json` specification allows for linebreaks, linebreaks __should not__ be used in this communication channel, to make
things simpler for both parties.
-### ApproveTx
+### ApproveTx / `ui_approveTx`
Invoked when there's a transaction for approval.
@@ -673,13 +673,13 @@ Here's a method invocation:
curl -i -H "Content-Type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"account_signTransaction","params":[{"from":"0x694267f14675d7e1b9494fd8d72fefe1755710fa","gas":"0x333","gasPrice":"0x1","nonce":"0x0","to":"0x07a565b7ed7d7a678680a4c162885bedbb695fe0", "value":"0x0", "data":"0x4401a6e40000000000000000000000000000000000000000000000000000000000000012"},"safeSend(address)"],"id":67}' http://localhost:8550/
```
-
+Results in the following invocation on the UI:
```json
{
"jsonrpc": "2.0",
"id": 1,
- "method": "ApproveTx",
+ "method": "ui_approveTx",
"params": [
{
"transaction": {
@@ -724,7 +724,7 @@ curl -i -H "Content-Type: application/json" -X POST --data '{"jsonrpc":"2.0","me
{
"jsonrpc": "2.0",
"id": 1,
- "method": "ApproveTx",
+ "method": "ui_approveTx",
"params": [
{
"transaction": {
@@ -767,7 +767,7 @@ One which has missing `to`, but with no `data`:
{
"jsonrpc": "2.0",
"id": 3,
- "method": "ApproveTx",
+ "method": "ui_approveTx",
"params": [
{
"transaction": {
@@ -796,33 +796,7 @@ One which has missing `to`, but with no `data`:
}
```
-### ApproveExport
-
-Invoked when a request to export an account has been made.
-
-#### Sample call
-
-```json
-
-{
- "jsonrpc": "2.0",
- "id": 7,
- "method": "ApproveExport",
- "params": [
- {
- "address": "0x0000000000000000000000000000000000000000",
- "meta": {
- "remote": "signer binary",
- "local": "main",
- "scheme": "in-proc"
- }
- }
- ]
-}
-
-```
-
-### ApproveListing
+### ApproveListing / `ui_approveListing`
Invoked when a request for account listing has been made.
@@ -833,7 +807,7 @@ Invoked when a request for account listing has been made.
{
"jsonrpc": "2.0",
"id": 5,
- "method": "ApproveListing",
+ "method": "ui_approveListing",
"params": [
{
"accounts": [
@@ -860,7 +834,7 @@ Invoked when a request for account listing has been made.
```
-### ApproveSignData
+### ApproveSignData / `ui_approveSignData`
#### Sample call
@@ -868,7 +842,7 @@ Invoked when a request for account listing has been made.
{
"jsonrpc": "2.0",
"id": 4,
- "method": "ApproveSignData",
+ "method": "ui_approveSignData",
"params": [
{
"address": "0x123409812340981234098123409812deadbeef42",
@@ -886,7 +860,7 @@ Invoked when a request for account listing has been made.
```
-### ShowInfo
+### ShowInfo / `ui_showInfo`
The UI should show the info to the user. Does not expect response.
@@ -896,7 +870,7 @@ The UI should show the info to the user. Does not expect response.
{
"jsonrpc": "2.0",
"id": 9,
- "method": "ShowInfo",
+ "method": "ui_showInfo",
"params": [
{
"text": "Tests completed"
@@ -906,7 +880,7 @@ The UI should show the info to the user. Does not expect response.
```
-### ShowError
+### ShowError / `ui_showError`
The UI should show the info to the user. Does not expect response.
@@ -925,7 +899,7 @@ The UI should show the info to the user. Does not expect response.
```
-### OnApproved
+### OnApprovedTx / `ui_onApprovedTx`
`OnApprovedTx` is called when a transaction has been approved and signed. The call contains the return value that will be sent to the external caller. The return value from this method is ignored - the reason for having this callback is to allow the ruleset to keep track of approved transactions.
@@ -933,7 +907,7 @@ When implementing rate-limited rules, this callback should be used.
TLDR; Use this method to keep track of signed transactions, instead of using the data in `ApproveTx`.
-### OnSignerStartup
+### OnSignerStartup / `ui_onSignerStartup`
This method provide the UI with information about what API version the signer uses (both internal and external) aswell as build-info and external api,
in k/v-form.
@@ -944,7 +918,7 @@ Example call:
{
"jsonrpc": "2.0",
"id": 1,
- "method": "OnSignerStartup",
+ "method": "ui_onSignerStartup",
"params": [
{
"info": {
diff --git a/cmd/clef/datatypes.md b/cmd/clef/datatypes.md
index e345a2bbd..a26c1c937 100644
--- a/cmd/clef/datatypes.md
+++ b/cmd/clef/datatypes.md
@@ -35,8 +35,7 @@ Response to SignDataRequest
Example:
```json
{
- "approved": true,
- "Password": "apassword"
+ "approved": true
}
```
### SignDataResponse - deny
@@ -46,8 +45,7 @@ Response to SignDataRequest
Example:
```json
{
- "approved": false,
- "Password": ""
+ "approved": false
}
```
### SignTxRequest
@@ -89,9 +87,9 @@ Example:
}
}
```
-### SignDataResponse - approve
+### SignTxResponse - approve
-Response to SignDataRequest. This response needs to contain the `transaction`, because the UI is free to make modifications to the transaction.
+Response to request to sign a transaction. This response needs to contain the `transaction`, because the UI is free to make modifications to the transaction.
Example:
```json
@@ -105,19 +103,26 @@ Example:
"nonce": "0x4",
"data": "0x04030201"
},
- "approved": true,
- "password": "apassword"
+ "approved": true
}
```
-### SignDataResponse - deny
+### SignTxResponse - deny
-Response to SignDataRequest. When denying a request, there's no need to provide the transaction in return
+Response to SignTxRequest. When denying a request, there's no need to provide the transaction in return
Example:
```json
{
- "approved": false,
- "Password": ""
+ "transaction": {
+ "from": "0x",
+ "to": null,
+ "gas": "0x0",
+ "gasPrice": "0x0",
+ "value": "0x0",
+ "nonce": "0x0",
+ "data": null
+ },
+ "approved": false
}
```
### OnApproved - SignTransactionResult
@@ -164,7 +169,7 @@ Example:
```
### UserInputResponse
-Response to SignDataRequest
+Response to UserInputRequest
Example:
```json
@@ -198,7 +203,7 @@ Example:
}
}
```
-### UserInputResponse
+### ListResponse
Response to list request. The response contains a list of all addresses to show to the caller. Note: the UI is free to respond with any address the caller, regardless of whether it exists or not
diff --git a/cmd/clef/intapi_changelog.md b/cmd/clef/intapi_changelog.md
index db3353bb7..b7d4937cd 100644
--- a/cmd/clef/intapi_changelog.md
+++ b/cmd/clef/intapi_changelog.md
@@ -1,5 +1,40 @@
### Changelog for internal API (ui-api)
+### 6.0.0
+
+Removed `password` from responses to operations which require them. This is for two reasons,
+
+- Consistency between how rulesets operate and how manual processing works. A rule can `Approve` but require the actual password to be stored in the clef storage.
+With this change, the same stored password can be used even if rulesets are not enabled, but storage is.
+- It also removes the usability-shortcut that a UI might otherwise want to implement; remembering passwords. Since we now will not require the
+password on every `Approve`, there's no need for the UI to cache it locally.
+ - In a future update, we'll likely add `clef_storePassword` to the internal API, so the user can store it via his UI (currently only CLI works).
+
+Affected datatypes:
+- `SignTxResponse`
+- `SignDataResponse`
+- `NewAccountResponse`
+
+If `clef` requires a password, the `OnInputRequired` will be used to collect it.
+
+
+### 5.0.0
+
+Changed the namespace format to adhere to the legacy ethereum format: `name_methodName`. Changes:
+
+* `ApproveTx` -> `ui_approveTx`
+* `ApproveSignData` -> `ui_approveSignData`
+* `ApproveExport` -> `removed`
+* `ApproveImport` -> `removed`
+* `ApproveListing` -> `ui_approveListing`
+* `ApproveNewAccount` -> `ui_approveNewAccount`
+* `ShowError` -> `ui_showError`
+* `ShowInfo` -> `ui_showInfo`
+* `OnApprovedTx` -> `ui_onApprovedTx`
+* `OnSignerStartup` -> `ui_onSignerStartup`
+* `OnInputRequired` -> `ui_onInputRequired`
+
+
### 4.0.0
* Bidirectional communication implemented, so the UI can query `clef` via the stdin/stdout RPC channel. Methods implemented are:
diff --git a/cmd/clef/main.go b/cmd/clef/main.go
index 088701eee..a90031245 100644
--- a/cmd/clef/main.go
+++ b/cmd/clef/main.go
@@ -119,7 +119,7 @@ var (
ruleFlag = cli.StringFlag{
Name: "rules",
Usage: "Enable rule-engine",
- Value: "rules.json",
+ Value: "",
}
stdiouiFlag = cli.BoolFlag{
Name: "stdio-ui",
@@ -371,17 +371,14 @@ func signer(c *cli.Context) error {
log.Info("Loaded 4byte db", "signatures", db.Size(), "file", fourByteDb, "local", fourByteLocal)
var (
- api core.ExternalAPI
+ api core.ExternalAPI
+ pwStorage storage.Storage = &storage.NoStorage{}
)
configDir := c.GlobalString(configdirFlag.Name)
if stretchedKey, err := readMasterKey(c, ui); err != nil {
log.Info("No master seed provided, rules disabled", "error", err)
} else {
-
- if err != nil {
- utils.Fatalf(err.Error())
- }
vaultLocation := filepath.Join(configDir, common.Bytes2Hex(crypto.Keccak256([]byte("vault"), stretchedKey)[:10]))
// Generate domain specific keys
@@ -390,30 +387,31 @@ func signer(c *cli.Context) error {
confkey := crypto.Keccak256([]byte("config"), stretchedKey)
// Initialize the encrypted storages
- pwStorage := storage.NewAESEncryptedStorage(filepath.Join(vaultLocation, "credentials.json"), pwkey)
+ pwStorage = storage.NewAESEncryptedStorage(filepath.Join(vaultLocation, "credentials.json"), pwkey)
jsStorage := storage.NewAESEncryptedStorage(filepath.Join(vaultLocation, "jsstorage.json"), jskey)
configStorage := storage.NewAESEncryptedStorage(filepath.Join(vaultLocation, "config.json"), confkey)
//Do we have a rule-file?
- ruleJS, err := ioutil.ReadFile(c.GlobalString(ruleFlag.Name))
- if err != nil {
- log.Info("Could not load rulefile, rules not enabled", "file", "rulefile")
- } else {
- hasher := sha256.New()
- hasher.Write(ruleJS)
- shasum := hasher.Sum(nil)
- storedShasum := configStorage.Get("ruleset_sha256")
- if storedShasum != hex.EncodeToString(shasum) {
- log.Info("Could not validate ruleset hash, rules not enabled", "got", hex.EncodeToString(shasum), "expected", storedShasum)
+ if ruleFile := c.GlobalString(ruleFlag.Name); ruleFile != "" {
+ ruleJS, err := ioutil.ReadFile(c.GlobalString(ruleFile))
+ if err != nil {
+ log.Info("Could not load rulefile, rules not enabled", "file", "rulefile")
} else {
- // Initialize rules
- ruleEngine, err := rules.NewRuleEvaluator(ui, jsStorage, pwStorage)
- if err != nil {
- utils.Fatalf(err.Error())
+ shasum := sha256.Sum256(ruleJS)
+ foundShaSum := hex.EncodeToString(shasum[:])
+ storedShasum := configStorage.Get("ruleset_sha256")
+ if storedShasum != foundShaSum {
+ log.Info("Could not validate ruleset hash, rules not enabled", "got", foundShaSum, "expected", storedShasum)
+ } else {
+ // Initialize rules
+ ruleEngine, err := rules.NewRuleEvaluator(ui, jsStorage)
+ if err != nil {
+ utils.Fatalf(err.Error())
+ }
+ ruleEngine.Init(string(ruleJS))
+ ui = ruleEngine
+ log.Info("Rule engine configured", "file", c.String(ruleFlag.Name))
}
- ruleEngine.Init(string(ruleJS))
- ui = ruleEngine
- log.Info("Rule engine configured", "file", c.String(ruleFlag.Name))
}
}
}
@@ -427,7 +425,7 @@ func signer(c *cli.Context) error {
log.Info("Starting signer", "chainid", chainId, "keystore", ksLoc,
"light-kdf", lightKdf, "advanced", advanced)
am := core.StartClefAccountManager(ksLoc, nousb, lightKdf)
- apiImpl := core.NewSignerAPI(am, chainId, nousb, ui, db, advanced)
+ apiImpl := core.NewSignerAPI(am, chainId, nousb, ui, db, advanced, pwStorage)
// Establish the bidirectional communication, by creating a new UI backend and registering
// it with the UI.
@@ -640,68 +638,124 @@ func testExternalUI(api *core.SignerAPI) {
ctx := context.WithValue(context.Background(), "remote", "clef binary")
ctx = context.WithValue(ctx, "scheme", "in-proc")
ctx = context.WithValue(ctx, "local", "main")
-
errs := make([]string, 0)
- api.UI.ShowInfo("Testing 'ShowInfo'")
- api.UI.ShowError("Testing 'ShowError'")
+ a := common.HexToAddress("0xdeadbeef000000000000000000000000deadbeef")
- checkErr := func(method string, err error) {
- if err != nil && err != core.ErrRequestDenied {
- errs = append(errs, fmt.Sprintf("%v: %v", method, err.Error()))
+ queryUser := func(q string) string {
+ resp, err := api.UI.OnInputRequired(core.UserInputRequest{
+ Title: "Testing",
+ Prompt: q,
+ })
+ if err != nil {
+ errs = append(errs, err.Error())
}
+ return resp.Text
}
- var err error
-
- cliqueHeader := types.Header{
- common.HexToHash("0000H45H"),
- common.HexToHash("0000H45H"),
- common.HexToAddress("0000H45H"),
- common.HexToHash("0000H00H"),
- common.HexToHash("0000H45H"),
- common.HexToHash("0000H45H"),
- types.Bloom{},
- big.NewInt(1337),
- big.NewInt(1337),
- 1338,
- 1338,
- big.NewInt(1338),
- []byte("Extra data Extra data Extra data Extra data Extra data Extra data Extra data Extra data"),
- common.HexToHash("0x0000H45H"),
- types.BlockNonce{},
- }
- cliqueRlp, err := rlp.EncodeToBytes(cliqueHeader)
- if err != nil {
- utils.Fatalf("Should not error: %v", err)
+ expectResponse := func(testcase, question, expect string) {
+ if got := queryUser(question); got != expect {
+ errs = append(errs, fmt.Sprintf("%s: got %v, expected %v", testcase, got, expect))
+ }
}
- addr, err := common.NewMixedcaseAddressFromString("0x0011223344556677889900112233445566778899")
- if err != nil {
- utils.Fatalf("Should not error: %v", err)
- }
- _, err = api.SignData(ctx, "application/clique", *addr, cliqueRlp)
- checkErr("SignData", err)
-
- _, err = api.SignTransaction(ctx, core.SendTxArgs{From: common.MixedcaseAddress{}}, nil)
- checkErr("SignTransaction", err)
- _, err = api.SignData(ctx, "text/plain", common.MixedcaseAddress{}, common.Hex2Bytes("01020304"))
- checkErr("SignData", err)
- //_, err = api.SignTypedData(ctx, common.MixedcaseAddress{}, core.TypedData{})
- //checkErr("SignTypedData", err)
- _, err = api.List(ctx)
- checkErr("List", err)
- _, err = api.New(ctx)
- checkErr("New", err)
-
- api.UI.ShowInfo("Tests completed")
-
- if len(errs) > 0 {
- log.Error("Got errors")
- for _, e := range errs {
- log.Error(e)
+ expectApprove := func(testcase string, err error) {
+ if err == nil || err == accounts.ErrUnknownAccount {
+ return
+ }
+ errs = append(errs, fmt.Sprintf("%v: expected no error, got %v", testcase, err.Error()))
+ }
+ expectDeny := func(testcase string, err error) {
+ if err == nil || err != core.ErrRequestDenied {
+ errs = append(errs, fmt.Sprintf("%v: expected ErrRequestDenied, got %v", testcase, err))
}
- } else {
- log.Info("No errors")
}
+
+ // Test display of info and error
+ {
+ api.UI.ShowInfo("If you see this message, enter 'yes' to next question")
+ expectResponse("showinfo", "Did you see the message? [yes/no]", "yes")
+ api.UI.ShowError("If you see this message, enter 'yes' to the next question")
+ expectResponse("showerror", "Did you see the message? [yes/no]", "yes")
+ }
+ { // Sign data test - clique header
+ api.UI.ShowInfo("Please approve the next request for signing a clique header")
+ cliqueHeader := types.Header{
+ common.HexToHash("0000H45H"),
+ common.HexToHash("0000H45H"),
+ common.HexToAddress("0000H45H"),
+ common.HexToHash("0000H00H"),
+ common.HexToHash("0000H45H"),
+ common.HexToHash("0000H45H"),
+ types.Bloom{},
+ big.NewInt(1337),
+ big.NewInt(1337),
+ 1338,
+ 1338,
+ big.NewInt(1338),
+ []byte("Extra data Extra data Extra data Extra data Extra data Extra data Extra data Extra data"),
+ common.HexToHash("0x0000H45H"),
+ types.BlockNonce{},
+ }
+ cliqueRlp, err := rlp.EncodeToBytes(cliqueHeader)
+ if err != nil {
+ utils.Fatalf("Should not error: %v", err)
+ }
+ addr, _ := common.NewMixedcaseAddressFromString("0x0011223344556677889900112233445566778899")
+ _, err = api.SignData(ctx, accounts.MimetypeClique, *addr, hexutil.Encode(cliqueRlp))
+ expectApprove("signdata - clique header", err)
+ }
+ { // Sign data test - plain text
+ api.UI.ShowInfo("Please approve the next request for signing text")
+ addr, _ := common.NewMixedcaseAddressFromString("0x0011223344556677889900112233445566778899")
+ _, err := api.SignData(ctx, accounts.MimetypeTextPlain, *addr, hexutil.Encode([]byte("hello world")))
+ expectApprove("signdata - text", err)
+ }
+ { // Sign data test - plain text reject
+ api.UI.ShowInfo("Please deny the next request for signing text")
+ addr, _ := common.NewMixedcaseAddressFromString("0x0011223344556677889900112233445566778899")
+ _, err := api.SignData(ctx, accounts.MimetypeTextPlain, *addr, hexutil.Encode([]byte("hello world")))
+ expectDeny("signdata - text", err)
+ }
+ { // Sign transaction
+
+ api.UI.ShowInfo("Please reject next transaction")
+ data := hexutil.Bytes([]byte{})
+ to := common.NewMixedcaseAddress(a)
+ tx := core.SendTxArgs{
+ Data: &data,
+ Nonce: 0x1,
+ Value: hexutil.Big(*big.NewInt(6)),
+ From: common.NewMixedcaseAddress(a),
+ To: &to,
+ GasPrice: hexutil.Big(*big.NewInt(5)),
+ Gas: 1000,
+ Input: nil,
+ }
+ _, err := api.SignTransaction(ctx, tx, nil)
+ expectDeny("signtransaction [1]", err)
+ expectResponse("signtransaction [2]", "Did you see any warnings for the last transaction? (yes/no)", "no")
+ }
+ { // Listing
+ api.UI.ShowInfo("Please reject listing-request")
+ _, err := api.List(ctx)
+ expectDeny("list", err)
+ }
+ { // Import
+ api.UI.ShowInfo("Please reject new account-request")
+ _, err := api.New(ctx)
+ expectDeny("newaccount", err)
+ }
+ { // Metadata
+ api.UI.ShowInfo("Please check if you see the Origin in next listing (approve or deny)")
+ api.List(context.WithValue(ctx, "Origin", "origin.com"))
+ expectResponse("metadata - origin", "Did you see origin (origin.com)? [yes/no] ", "yes")
+ }
+
+ for _, e := range errs {
+ log.Error(e)
+ }
+ result := fmt.Sprintf("Tests completed. %d errors:\n%s\n", len(errs), strings.Join(errs, "\n"))
+ api.UI.ShowInfo(result)
+
}
// getPassPhrase retrieves the password associated with clef, either fetched
@@ -798,7 +852,7 @@ func GenDoc(ctx *cli.Context) {
}
{ // Sign plain text response
add("SignDataResponse - approve", "Response to SignDataRequest",
- &core.SignDataResponse{Password: "apassword", Approved: true})
+ &core.SignDataResponse{Approved: true})
add("SignDataResponse - deny", "Response to SignDataRequest",
&core.SignDataResponse{})
}
@@ -833,9 +887,9 @@ func GenDoc(ctx *cli.Context) {
}
{ // Sign tx response
data := hexutil.Bytes([]byte{0x04, 0x03, 0x02, 0x01})
- add("SignDataResponse - approve", "Response to SignDataRequest. This response needs to contain the `transaction`"+
+ add("SignTxResponse - approve", "Response to request to sign a transaction. This response needs to contain the `transaction`"+
", because the UI is free to make modifications to the transaction.",
- &core.SignTxResponse{Password: "apassword", Approved: true,
+ &core.SignTxResponse{Approved: true,
Transaction: core.SendTxArgs{
Data: &data,
Nonce: 0x4,
@@ -846,9 +900,9 @@ func GenDoc(ctx *cli.Context) {
Gas: 1000,
Input: nil,
}})
- add("SignDataResponse - deny", "Response to SignDataRequest. When denying a request, there's no need to "+
+ add("SignTxResponse - deny", "Response to SignTxRequest. When denying a request, there's no need to "+
"provide the transaction in return",
- &core.SignDataResponse{})
+ &core.SignTxResponse{})
}
{ // WHen a signed tx is ready to go out
desc := "SignTransactionResult is used in the call `clef` -> `OnApprovedTx(result)`" +
@@ -874,7 +928,7 @@ func GenDoc(ctx *cli.Context) {
{ // User input
add("UserInputRequest", "Sent when clef needs the user to provide data. If 'password' is true, the input field should be treated accordingly (echo-free)",
&core.UserInputRequest{IsPassword: true, Title: "The title here", Prompt: "The question to ask the user"})
- add("UserInputResponse", "Response to SignDataRequest",
+ add("UserInputResponse", "Response to UserInputRequest",
&core.UserInputResponse{Text: "The textual response from user"})
}
{ // List request
@@ -888,7 +942,7 @@ func GenDoc(ctx *cli.Context) {
{b, accounts.URL{Scheme: "keystore", Path: "/path/to/keyfile/b"}}},
})
- add("UserInputResponse", "Response to list request. The response contains a list of all addresses to show to the caller. "+
+ add("ListResponse", "Response to list request. The response contains a list of all addresses to show to the caller. "+
"Note: the UI is free to respond with any address the caller, regardless of whether it exists or not",
&core.ListResponse{
Accounts: []accounts.Account{