diff --git a/cmd/clef/README.md b/cmd/clef/README.md index 036e71b286..956957f3d1 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/intapi_changelog.md b/cmd/clef/intapi_changelog.md index db3353bb7d..26d859973f 100644 --- a/cmd/clef/intapi_changelog.md +++ b/cmd/clef/intapi_changelog.md @@ -1,5 +1,22 @@ ### Changelog for internal API (ui-api) +### 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/signer/core/api.go b/signer/core/api.go index 837b7266c3..f0dfb8c703 100644 --- a/signer/core/api.go +++ b/signer/core/api.go @@ -68,10 +68,6 @@ type UIClientAPI interface { ApproveTx(request *SignTxRequest) (SignTxResponse, error) // ApproveSignData prompt the user for confirmation to request to sign data ApproveSignData(request *SignDataRequest) (SignDataResponse, error) - // ApproveExport prompt the user for confirmation to export encrypted Account json - ApproveExport(request *ExportRequest) (ExportResponse, error) - // ApproveImport prompt the user for confirmation to import Account json - ApproveImport(request *ImportRequest) (ImportResponse, error) // ApproveListing prompt the user for confirmation to list accounts // the list of accounts to list can be modified by the UI ApproveListing(request *ListRequest) (ListResponse, error) @@ -189,24 +185,6 @@ type ( Approved bool `json:"approved"` Password string `json:"password"` } - // ExportRequest info about query to export accounts - ExportRequest struct { - Address common.Address `json:"address"` - Meta Metadata `json:"meta"` - } - // ExportResponse response to export-request - ExportResponse struct { - Approved bool `json:"approved"` - } - // ImportRequest info about request to import an Account - ImportRequest struct { - Meta Metadata `json:"meta"` - } - ImportResponse struct { - Approved bool `json:"approved"` - OldPassword string `json:"old_password"` - NewPassword string `json:"new_password"` - } SignDataRequest struct { ContentType string `json:"content_type"` Address common.MixedcaseAddress `json:"address"` diff --git a/signer/core/api_test.go b/signer/core/api_test.go index bf4e91eb95..2b9b2f5f9d 100644 --- a/signer/core/api_test.go +++ b/signer/core/api_test.go @@ -77,18 +77,6 @@ func (ui *HeadlessUI) ApproveSignData(request *SignDataRequest) (SignDataRespons return SignDataResponse{false, ""}, nil } -func (ui *HeadlessUI) ApproveExport(request *ExportRequest) (ExportResponse, error) { - return ExportResponse{<-ui.controller == "Y"}, nil - -} - -func (ui *HeadlessUI) ApproveImport(request *ImportRequest) (ImportResponse, error) { - if "Y" == <-ui.controller { - return ImportResponse{true, <-ui.controller, <-ui.controller}, nil - } - return ImportResponse{false, "", ""}, nil -} - func (ui *HeadlessUI) ApproveListing(request *ListRequest) (ListResponse, error) { switch <-ui.controller { case "A": diff --git a/signer/core/cliui.go b/signer/core/cliui.go index a6c0bdb162..109fdd9a19 100644 --- a/signer/core/cliui.go +++ b/signer/core/cliui.go @@ -183,37 +183,6 @@ func (ui *CommandlineUI) ApproveSignData(request *SignDataRequest) (SignDataResp return SignDataResponse{true, ui.readPassword()}, nil } -// ApproveExport prompt the user for confirmation to export encrypted Account json -func (ui *CommandlineUI) ApproveExport(request *ExportRequest) (ExportResponse, error) { - ui.mu.Lock() - defer ui.mu.Unlock() - - fmt.Printf("-------- Export Account request--------------\n") - fmt.Printf("A request has been made to export the (encrypted) keyfile\n") - fmt.Printf("Approving this operation means that the caller obtains the (encrypted) contents\n") - fmt.Printf("\n") - fmt.Printf("Account: %x\n", request.Address) - //fmt.Printf("keyfile: \n%v\n", request.file) - fmt.Printf("-------------------------------------------\n") - showMetadata(request.Meta) - return ExportResponse{ui.confirm()}, nil -} - -// ApproveImport prompt the user for confirmation to import Account json -func (ui *CommandlineUI) ApproveImport(request *ImportRequest) (ImportResponse, error) { - ui.mu.Lock() - defer ui.mu.Unlock() - - fmt.Printf("-------- Import Account request--------------\n") - fmt.Printf("A request has been made to import an encrypted keyfile\n") - fmt.Printf("-------------------------------------------\n") - showMetadata(request.Meta) - if !ui.confirm() { - return ImportResponse{false, "", ""}, nil - } - return ImportResponse{true, ui.readPasswordText("Old password"), ui.readPasswordText("New password")}, nil -} - // ApproveListing prompt the user for confirmation to list accounts // the list of accounts to list can be modified by the UI func (ui *CommandlineUI) ApproveListing(request *ListRequest) (ListResponse, error) { diff --git a/signer/core/stdioui.go b/signer/core/stdioui.go index cb25bc2d00..0edb72def9 100644 --- a/signer/core/stdioui.go +++ b/signer/core/stdioui.go @@ -65,71 +65,59 @@ func (ui *StdIOUI) notify(serviceMethod string, args interface{}) error { func (ui *StdIOUI) ApproveTx(request *SignTxRequest) (SignTxResponse, error) { var result SignTxResponse - err := ui.dispatch("ApproveTx", request, &result) + err := ui.dispatch("ui_approveTx", request, &result) return result, err } func (ui *StdIOUI) ApproveSignData(request *SignDataRequest) (SignDataResponse, error) { var result SignDataResponse - err := ui.dispatch("ApproveSignData", request, &result) - return result, err -} - -func (ui *StdIOUI) ApproveExport(request *ExportRequest) (ExportResponse, error) { - var result ExportResponse - err := ui.dispatch("ApproveExport", request, &result) - return result, err -} - -func (ui *StdIOUI) ApproveImport(request *ImportRequest) (ImportResponse, error) { - var result ImportResponse - err := ui.dispatch("ApproveImport", request, &result) + err := ui.dispatch("ui_approveSignData", request, &result) return result, err } func (ui *StdIOUI) ApproveListing(request *ListRequest) (ListResponse, error) { var result ListResponse - err := ui.dispatch("ApproveListing", request, &result) + err := ui.dispatch("ui_approveListing", request, &result) return result, err } func (ui *StdIOUI) ApproveNewAccount(request *NewAccountRequest) (NewAccountResponse, error) { var result NewAccountResponse - err := ui.dispatch("ApproveNewAccount", request, &result) + err := ui.dispatch("ui_approveNewAccount", request, &result) return result, err } func (ui *StdIOUI) ShowError(message string) { - err := ui.notify("ShowError", &Message{message}) + err := ui.notify("ui_showError", &Message{message}) if err != nil { - log.Info("Error calling 'ShowError'", "exc", err.Error(), "msg", message) + log.Info("Error calling 'ui_showError'", "exc", err.Error(), "msg", message) } } func (ui *StdIOUI) ShowInfo(message string) { - err := ui.notify("ShowInfo", Message{message}) + err := ui.notify("ui_showInfo", Message{message}) if err != nil { - log.Info("Error calling 'ShowInfo'", "exc", err.Error(), "msg", message) + log.Info("Error calling 'ui_showInfo'", "exc", err.Error(), "msg", message) } } func (ui *StdIOUI) OnApprovedTx(tx ethapi.SignTransactionResult) { - err := ui.notify("OnApprovedTx", tx) + err := ui.notify("ui_onApprovedTx", tx) if err != nil { - log.Info("Error calling 'OnApprovedTx'", "exc", err.Error(), "tx", tx) + log.Info("Error calling 'ui_onApprovedTx'", "exc", err.Error(), "tx", tx) } } func (ui *StdIOUI) OnSignerStartup(info StartupInfo) { - err := ui.notify("OnSignerStartup", info) + err := ui.notify("ui_onSignerStartup", info) if err != nil { - log.Info("Error calling 'OnSignerStartup'", "exc", err.Error(), "info", info) + log.Info("Error calling 'ui_onSignerStartup'", "exc", err.Error(), "info", info) } } func (ui *StdIOUI) OnInputRequired(info UserInputRequest) (UserInputResponse, error) { var result UserInputResponse - err := ui.dispatch("OnInputRequired", info, &result) + err := ui.dispatch("ui_onInputRequired", info, &result) if err != nil { - log.Info("Error calling 'OnInputRequired'", "exc", err.Error(), "info", info) + log.Info("Error calling 'ui_onInputRequired'", "exc", err.Error(), "info", info) } return result, err } diff --git a/signer/rules/rules.go b/signer/rules/rules.go index 1f81e21bd0..7ddf718034 100644 --- a/signer/rules/rules.go +++ b/signer/rules/rules.go @@ -178,25 +178,6 @@ func (r *rulesetUI) ApproveSignData(request *core.SignDataRequest) (core.SignDat return core.SignDataResponse{Approved: false, Password: ""}, err } -func (r *rulesetUI) ApproveExport(request *core.ExportRequest) (core.ExportResponse, error) { - jsonreq, err := json.Marshal(request) - approved, err := r.checkApproval("ApproveExport", jsonreq, err) - if err != nil { - log.Info("Rule-based approval error, going to manual", "error", err) - return r.next.ApproveExport(request) - } - if approved { - return core.ExportResponse{Approved: true}, nil - } - return core.ExportResponse{Approved: false}, err -} - -func (r *rulesetUI) ApproveImport(request *core.ImportRequest) (core.ImportResponse, error) { - // This cannot be handled by rules, requires setting a password - // dispatch to next - return r.next.ApproveImport(request) -} - // OnInputRequired not handled by rules func (r *rulesetUI) OnInputRequired(info core.UserInputRequest) (core.UserInputResponse, error) { return r.next.OnInputRequired(info) diff --git a/signer/rules/rules_test.go b/signer/rules/rules_test.go index eca4b29a04..6b537d2041 100644 --- a/signer/rules/rules_test.go +++ b/signer/rules/rules_test.go @@ -91,14 +91,6 @@ func (alwaysDenyUI) ApproveSignData(request *core.SignDataRequest) (core.SignDat return core.SignDataResponse{Approved: false, Password: ""}, nil } -func (alwaysDenyUI) ApproveExport(request *core.ExportRequest) (core.ExportResponse, error) { - return core.ExportResponse{Approved: false}, nil -} - -func (alwaysDenyUI) ApproveImport(request *core.ImportRequest) (core.ImportResponse, error) { - return core.ImportResponse{Approved: false, OldPassword: "", NewPassword: ""}, nil -} - func (alwaysDenyUI) ApproveListing(request *core.ListRequest) (core.ListResponse, error) { return core.ListResponse{Accounts: nil}, nil } @@ -225,16 +217,6 @@ func (d *dummyUI) ApproveSignData(request *core.SignDataRequest) (core.SignDataR return core.SignDataResponse{}, core.ErrRequestDenied } -func (d *dummyUI) ApproveExport(request *core.ExportRequest) (core.ExportResponse, error) { - d.calls = append(d.calls, "ApproveExport") - return core.ExportResponse{}, core.ErrRequestDenied -} - -func (d *dummyUI) ApproveImport(request *core.ImportRequest) (core.ImportResponse, error) { - d.calls = append(d.calls, "ApproveImport") - return core.ImportResponse{}, core.ErrRequestDenied -} - func (d *dummyUI) ApproveListing(request *core.ListRequest) (core.ListResponse, error) { d.calls = append(d.calls, "ApproveListing") return core.ListResponse{}, core.ErrRequestDenied @@ -276,17 +258,15 @@ func TestForwarding(t *testing.T) { } r.ApproveSignData(nil) r.ApproveTx(nil) - r.ApproveImport(nil) r.ApproveNewAccount(nil) r.ApproveListing(nil) - r.ApproveExport(nil) r.ShowError("test") r.ShowInfo("test") //This one is not forwarded r.OnApprovedTx(ethapi.SignTransactionResult{}) - expCalls := 8 + expCalls := 6 if len(ui.calls) != expCalls { t.Errorf("Expected %d forwarded calls, got %d: %s", expCalls, len(ui.calls), strings.Join(ui.calls, ",")) @@ -545,16 +525,6 @@ func (d *dontCallMe) ApproveSignData(request *core.SignDataRequest) (core.SignDa return core.SignDataResponse{}, core.ErrRequestDenied } -func (d *dontCallMe) ApproveExport(request *core.ExportRequest) (core.ExportResponse, error) { - d.t.Fatalf("Did not expect next-handler to be called") - return core.ExportResponse{}, core.ErrRequestDenied -} - -func (d *dontCallMe) ApproveImport(request *core.ImportRequest) (core.ImportResponse, error) { - d.t.Fatalf("Did not expect next-handler to be called") - return core.ImportResponse{}, core.ErrRequestDenied -} - func (d *dontCallMe) ApproveListing(request *core.ListRequest) (core.ListResponse, error) { d.t.Fatalf("Did not expect next-handler to be called") return core.ListResponse{}, core.ErrRequestDenied