github.com/status-im/status-go@v1.1.0/services/personal/api.go (about) 1 package personal 2 3 import ( 4 "context" 5 "errors" 6 "strings" 7 "time" 8 9 "github.com/ethereum/go-ethereum/common" 10 "github.com/ethereum/go-ethereum/common/hexutil" 11 12 "github.com/status-im/status-go/account" 13 "github.com/status-im/status-go/eth-node/types" 14 "github.com/status-im/status-go/params" 15 "github.com/status-im/status-go/rpc" 16 ) 17 18 var ( 19 // ErrInvalidPersonalSignAccount is returned when the account passed to 20 // personal_sign isn't equal to the currently selected account. 21 ErrInvalidPersonalSignAccount = errors.New("invalid account as only the selected one can generate a signature") 22 ) 23 24 // SignParams required to sign messages 25 type SignParams struct { 26 Data interface{} `json:"data"` 27 Address string `json:"account"` 28 Password string `json:"password"` 29 } 30 31 // RecoverParams are for calling `personal_ecRecover` 32 type RecoverParams struct { 33 Message string `json:"message"` 34 Signature string `json:"signature"` 35 } 36 37 // PublicAPI represents a set of APIs from the `web3.personal` namespace. 38 type PublicAPI struct { 39 rpcClient *rpc.Client 40 rpcTimeout time.Duration 41 } 42 43 // NewAPI creates an instance of the personal API. 44 func NewAPI() *PublicAPI { 45 return &PublicAPI{ 46 rpcTimeout: 300 * time.Second, 47 } 48 } 49 50 // SetRPC sets RPC params (client and timeout) for the API calls. 51 func (api *PublicAPI) SetRPC(rpcClient *rpc.Client, timeout time.Duration) { 52 api.rpcClient = rpcClient 53 api.rpcTimeout = timeout 54 } 55 56 // Recover is an implementation of `personal_ecRecover` or `web3.personal.ecRecover` API 57 func (api *PublicAPI) Recover(rpcParams RecoverParams) (addr types.Address, err error) { 58 ctx, cancel := context.WithTimeout(context.Background(), api.rpcTimeout) 59 defer cancel() 60 var gethAddr common.Address 61 err = api.rpcClient.CallContextIgnoringLocalHandlers( 62 ctx, 63 &gethAddr, 64 api.rpcClient.UpstreamChainID, 65 params.PersonalRecoverMethodName, 66 rpcParams.Message, rpcParams.Signature) 67 addr = types.Address(gethAddr) 68 69 return 70 } 71 72 // Sign is an implementation of `personal_sign` or `web3.personal.sign` API 73 func (api *PublicAPI) Sign(rpcParams SignParams, verifiedAccount *account.SelectedExtKey) (result types.HexBytes, err error) { 74 if !strings.EqualFold(rpcParams.Address, verifiedAccount.Address.Hex()) { 75 err = ErrInvalidPersonalSignAccount 76 return 77 } 78 79 ctx, cancel := context.WithTimeout(context.Background(), api.rpcTimeout) 80 defer cancel() 81 var gethResult hexutil.Bytes 82 err = api.rpcClient.CallContextIgnoringLocalHandlers( 83 ctx, 84 &gethResult, 85 api.rpcClient.UpstreamChainID, 86 params.PersonalSignMethodName, 87 rpcParams.Data, rpcParams.Address, rpcParams.Password) 88 result = types.HexBytes(gethResult) 89 90 return 91 }