feat(BC): Implement eth_signTypedData_v4 in BrowserConnect
This commit renames the personalSign to Sign in nim and status-go to enable `eth_signTypedData_v4` signing. The sing request coming from the status-go API contains the signing method to be used by the client. Currently we're supporting personal sign and signTypedData_v4. The only difference between these two signing methods is the order of challenge and address in the `params` array. This is handled in the SappsConnectorSDK::buildSignRequest
This commit is contained in:
parent
5992054f0d
commit
b555d19a1a
|
@ -29,13 +29,14 @@ type ConnectorRevokeDAppPermissionSignal* = ref object of Signal
|
|||
name*: string
|
||||
iconUrl*: string
|
||||
|
||||
type ConnectorPersonalSignSignal* = ref object of Signal
|
||||
type ConnectorSignSignal* = ref object of Signal
|
||||
url*: string
|
||||
name*: string
|
||||
iconUrl*: string
|
||||
requestId*: string
|
||||
challenge*: string
|
||||
address*: string
|
||||
signMethod*: string
|
||||
|
||||
proc fromEvent*(T: type ConnectorSendRequestAccountsSignal, event: JsonNode): ConnectorSendRequestAccountsSignal =
|
||||
result = ConnectorSendRequestAccountsSignal()
|
||||
|
@ -67,11 +68,12 @@ proc fromEvent*(T: type ConnectorRevokeDAppPermissionSignal, event: JsonNode): C
|
|||
result.name = event["event"]{"name"}.getStr()
|
||||
result.iconUrl = event["event"]{"iconUrl"}.getStr()
|
||||
|
||||
proc fromEvent*(T: type ConnectorPersonalSignSignal, event: JsonNode): ConnectorPersonalSignSignal =
|
||||
result = ConnectorPersonalSignSignal()
|
||||
proc fromEvent*(T: type ConnectorSignSignal, event: JsonNode): ConnectorSignSignal =
|
||||
result = ConnectorSignSignal()
|
||||
result.url = event["event"]{"url"}.getStr()
|
||||
result.name = event["event"]{"name"}.getStr()
|
||||
result.iconUrl = event["event"]{"iconUrl"}.getStr()
|
||||
result.requestId = event["event"]{"requestId"}.getStr()
|
||||
result.challenge = event["event"]{"challenge"}.getStr()
|
||||
result.address = event["event"]{"address"}.getStr()
|
||||
result.signMethod = event["event"]{"method"}.getStr()
|
|
@ -74,7 +74,7 @@ type SignalType* {.pure.} = enum
|
|||
ConnectorSendTransaction = "connector.sendTransaction"
|
||||
ConnectorGrantDAppPermission = "connector.dAppPermissionGranted"
|
||||
ConnectorRevokeDAppPermission = "connector.dAppPermissionRevoked"
|
||||
ConnectorPersonalSign = "connector.personalSign"
|
||||
ConnectorSign = "connector.Sign"
|
||||
Unknown
|
||||
|
||||
proc event*(self:SignalType):string =
|
||||
|
|
|
@ -145,7 +145,7 @@ QtObject:
|
|||
of SignalType.ConnectorSendTransaction: ConnectorSendTransactionSignal.fromEvent(jsonSignal)
|
||||
of SignalType.ConnectorGrantDAppPermission: ConnectorGrantDAppPermissionSignal.fromEvent(jsonSignal)
|
||||
of SignalType.ConnectorRevokeDAppPermission: ConnectorRevokeDAppPermissionSignal.fromEvent(jsonSignal)
|
||||
of SignalType.ConnectorPersonalSign: ConnectorPersonalSignSignal.fromEvent(jsonSignal)
|
||||
of SignalType.ConnectorSign: ConnectorSignSignal.fromEvent(jsonSignal)
|
||||
else: Signal()
|
||||
|
||||
result.signalType = signalType
|
||||
|
|
|
@ -13,7 +13,7 @@ const SIGNAL_CONNECTOR_SEND_REQUEST_ACCOUNTS* = "ConnectorSendRequestAccounts"
|
|||
const SIGNAL_CONNECTOR_EVENT_CONNECTOR_SEND_TRANSACTION* = "ConnectorSendTransaction"
|
||||
const SIGNAL_CONNECTOR_GRANT_DAPP_PERMISSION* = "ConnectorGrantDAppPermission"
|
||||
const SIGNAL_CONNECTOR_REVOKE_DAPP_PERMISSION* = "ConnectorRevokeDAppPermission"
|
||||
const SIGNAL_CONNECTOR_PERSONAL_SIGN* = "ConnectorPersonalSign"
|
||||
const SIGNAL_CONNECTOR_SIGN* = "ConnectorSign"
|
||||
|
||||
logScope:
|
||||
topics = "connector-controller"
|
||||
|
@ -32,14 +32,14 @@ QtObject:
|
|||
proc disconnected*(self: Controller, payload: string) {.signal.}
|
||||
|
||||
proc sendTransaction*(self: Controller, requestId: string, payload: string) {.signal.}
|
||||
proc personalSign(self: Controller, requestId: string, payload: string) {.signal.}
|
||||
proc sign(self: Controller, requestId: string, payload: string) {.signal.}
|
||||
proc approveConnectResponse*(self: Controller, payload: string, error: bool) {.signal.}
|
||||
proc rejectConnectResponse*(self: Controller, payload: string, error: bool) {.signal.}
|
||||
|
||||
proc approveTransactionResponse*(self: Controller, topic: string, requestId: string, error: bool) {.signal.}
|
||||
proc rejectTransactionResponse*(self: Controller, topic: string, requestId: string, error: bool) {.signal.}
|
||||
proc approvePersonalSignResponse*(self: Controller, topic: string, requestId: string, error: bool) {.signal.}
|
||||
proc rejectPersonalSignResponse*(self: Controller, topic: string, requestId: string, error: bool) {.signal.}
|
||||
proc approveSignResponse*(self: Controller, topic: string, requestId: string, error: bool) {.signal.}
|
||||
proc rejectSignResponse*(self: Controller, topic: string, requestId: string, error: bool) {.signal.}
|
||||
|
||||
proc newController*(service: connector_service.Service, events: EventEmitter): Controller =
|
||||
new(result, delete)
|
||||
|
@ -97,17 +97,18 @@ QtObject:
|
|||
|
||||
controller.disconnected(dappInfo.toJson())
|
||||
|
||||
result.events.on(SIGNAL_CONNECTOR_PERSONAL_SIGN) do(e: Args):
|
||||
let params = ConnectorPersonalSignSignal(e)
|
||||
result.events.on(SIGNAL_CONNECTOR_SIGN) do(e: Args):
|
||||
let params = ConnectorSignSignal(e)
|
||||
let dappInfo = %*{
|
||||
"icon": params.iconUrl,
|
||||
"name": params.name,
|
||||
"url": params.url,
|
||||
"challenge": params.challenge,
|
||||
"address": params.address,
|
||||
"method": params.signMethod,
|
||||
}
|
||||
|
||||
controller.personalSign(params.requestId, dappInfo.toJson())
|
||||
controller.sign(params.requestId, dappInfo.toJson())
|
||||
|
||||
result.QObject.setup
|
||||
|
||||
|
@ -146,11 +147,11 @@ QtObject:
|
|||
proc getDApps*(self: Controller): string {.slot.} =
|
||||
return self.service.getDApps()
|
||||
|
||||
proc approvePersonalSigning*(self: Controller, sessionTopic: string, requestId: string, signature: string): bool {.slot.} =
|
||||
result = self.service.approvePersonalSignRequest(requestId, signature)
|
||||
self.approvePersonalSignResponse(sessionTopic, requestId, not result)
|
||||
proc approveSigning*(self: Controller, sessionTopic: string, requestId: string, signature: string): bool {.slot.} =
|
||||
result = self.service.approveSignRequest(requestId, signature)
|
||||
self.approveSignResponse(sessionTopic, requestId, not result)
|
||||
|
||||
|
||||
proc rejectPersonalSigning*(self: Controller, sessionTopic: string, requestId: string): bool {.slot.} =
|
||||
result = self.service.rejectPersonalSigning(requestId)
|
||||
self.rejectPersonalSignResponse(sessionTopic, requestId, not result)
|
||||
proc rejectSigning*(self: Controller, sessionTopic: string, requestId: string): bool {.slot.} =
|
||||
result = self.service.rejectSigning(requestId)
|
||||
self.rejectSignResponse(sessionTopic, requestId, not result)
|
|
@ -16,7 +16,7 @@ const SIGNAL_CONNECTOR_SEND_REQUEST_ACCOUNTS* = "ConnectorSendRequestAccounts"
|
|||
const SIGNAL_CONNECTOR_EVENT_CONNECTOR_SEND_TRANSACTION* = "ConnectorSendTransaction"
|
||||
const SIGNAL_CONNECTOR_GRANT_DAPP_PERMISSION* = "ConnectorGrantDAppPermission"
|
||||
const SIGNAL_CONNECTOR_REVOKE_DAPP_PERMISSION* = "ConnectorRevokeDAppPermission"
|
||||
const SIGNAL_CONNECTOR_EVENT_CONNECTOR_PERSONAL_SIGN* = "ConnectorPersonalSign"
|
||||
const SIGNAL_CONNECTOR_EVENT_CONNECTOR_SIGN* = "ConnectorSign"
|
||||
|
||||
# Enum with events
|
||||
type Event* = enum
|
||||
|
@ -84,17 +84,17 @@ QtObject:
|
|||
|
||||
self.events.emit(SIGNAL_CONNECTOR_REVOKE_DAPP_PERMISSION, data)
|
||||
)
|
||||
self.events.on(SignalType.ConnectorPersonalSign.event, proc(e: Args) =
|
||||
self.events.on(SignalType.ConnectorSign.event, proc(e: Args) =
|
||||
if self.eventHandler == nil:
|
||||
return
|
||||
|
||||
var data = ConnectorPersonalSignSignal(e)
|
||||
var data = ConnectorSignSignal(e)
|
||||
|
||||
if not data.requestId.len() == 0:
|
||||
error "ConnectorPersonalSignSignal failed, requestId is empty"
|
||||
error "ConnectorSignSignal failed, requestId is empty"
|
||||
return
|
||||
|
||||
self.events.emit(SIGNAL_CONNECTOR_EVENT_CONNECTOR_PERSONAL_SIGN, data)
|
||||
self.events.emit(SIGNAL_CONNECTOR_EVENT_CONNECTOR_SIGN, data)
|
||||
)
|
||||
|
||||
proc registerEventsHandler*(self: Service, handler: EventHandlerFn) =
|
||||
|
@ -165,17 +165,17 @@ QtObject:
|
|||
error "getDApps failed: ", err=e.msg
|
||||
return "[]"
|
||||
|
||||
proc approvePersonalSignRequest*(self: Service, requestId: string, signature: string): bool =
|
||||
proc approveSignRequest*(self: Service, requestId: string, signature: string): bool =
|
||||
try:
|
||||
var args = PersonalSignAcceptedArgs()
|
||||
var args = SignAcceptedArgs()
|
||||
args.requestId = requestId
|
||||
args.signature = signature
|
||||
|
||||
return status_go.sendPersonalSignAcceptedFinishedRpc(args)
|
||||
return status_go.sendSignAcceptedFinishedRpc(args)
|
||||
|
||||
except Exception as e:
|
||||
error "sendPersonalSigAcceptedFinishedRpc failed: ", err=e.msg
|
||||
error "sendSigAcceptedFinishedRpc failed: ", err=e.msg
|
||||
return false
|
||||
|
||||
proc rejectPersonalSigning*(self: Service, requestId: string): bool =
|
||||
rejectRequest(self, requestId, status_go.sendPersonalSignRejectedFinishedRpc, "sendPersonalSignRejectedFinishedRpc failed: ")
|
||||
proc rejectSigning*(self: Service, requestId: string): bool =
|
||||
rejectRequest(self, requestId, status_go.sendSignRejectedFinishedRpc, "sendSignRejectedFinishedRpc failed: ")
|
|
@ -23,7 +23,7 @@ type RejectedArgs* = ref object of RootObj
|
|||
type RecallDAppPermissionArgs* = ref object of RootObj
|
||||
dAppUrl* {.serializedFieldName("dAppUrl").}: string
|
||||
|
||||
type PersonalSignAcceptedArgs* = ref object of RootObj
|
||||
type SignAcceptedArgs* = ref object of RootObj
|
||||
requestId* {.serializedFieldName("requestId").}: string
|
||||
signature* {.serializedFieldName("signature").}: string
|
||||
|
||||
|
@ -45,10 +45,10 @@ rpc(recallDAppPermission, "connector"):
|
|||
rpc(getPermittedDAppsList, "connector"):
|
||||
discard
|
||||
|
||||
rpc(personalSignAccepted, "connector"):
|
||||
args: PersonalSignAcceptedArgs
|
||||
rpc(signAccepted, "connector"):
|
||||
args: SignAcceptedArgs
|
||||
|
||||
rpc(personalSignRejected, "connector"):
|
||||
rpc(signRejected, "connector"):
|
||||
args: RejectedArgs
|
||||
|
||||
proc isSuccessResponse(rpcResponse: RpcResponse[JsonNode]): bool =
|
||||
|
@ -69,8 +69,8 @@ proc sendTransactionRejectedFinishedRpc*(args: RejectedArgs): bool =
|
|||
proc recallDAppPermissionFinishedRpc*(dAppUrl: string): bool =
|
||||
return isSuccessResponse(recallDAppPermission(dAppUrl))
|
||||
|
||||
proc sendPersonalSignAcceptedFinishedRpc*(args: PersonalSignAcceptedArgs): bool =
|
||||
return isSuccessResponse(personalSignAccepted(args))
|
||||
proc sendSignAcceptedFinishedRpc*(args: SignAcceptedArgs): bool =
|
||||
return isSuccessResponse(signAccepted(args))
|
||||
|
||||
proc sendPersonalSignRejectedFinishedRpc*(args: RejectedArgs): bool =
|
||||
return isSuccessResponse(personalSignRejected(args))
|
||||
proc sendSignRejectedFinishedRpc*(args: RejectedArgs): bool =
|
||||
return isSuccessResponse(signRejected(args))
|
|
@ -378,7 +378,8 @@ Item {
|
|||
accountsModel: dappModule.accountsModel
|
||||
store: SharedStores.BrowserConnectStore {
|
||||
signal connectRequested(string requestId, string dappJson)
|
||||
signal signRequested(string requestId, string requestJson)
|
||||
signal sendTransaction(string requestId, string requestJson)
|
||||
signal sign(string requestId, string dappJson)
|
||||
|
||||
signal connected(string dappJson)
|
||||
signal disconnected(string dappJson)
|
||||
|
@ -389,6 +390,8 @@ Item {
|
|||
|
||||
signal approveTransactionResponse(string topic, string requestId, bool error)
|
||||
signal rejectTransactionResponse(string topic, string requestId, bool error)
|
||||
signal approveSignResponse(string topic, string requestId, bool error)
|
||||
signal rejectSignResponse(string topic, string requestId, bool error)
|
||||
}
|
||||
}
|
||||
store: SharedStores.DAppsStore {
|
||||
|
|
|
@ -53,22 +53,22 @@ WalletConnectSDKBase {
|
|||
}
|
||||
}
|
||||
|
||||
function onPersonalSign(requestId, dappInfoString) {
|
||||
function onSign(requestId, dappInfoString) {
|
||||
try {
|
||||
const dappInfo = JSON.parse(dappInfoString)
|
||||
const mainNet = SQUtils.ModelUtils.getByKey(root.networksModel, "layer", 1)
|
||||
if (!mainNet) {
|
||||
root.store.rejectPersonalSign(requestId)
|
||||
console.error("Mainnet not found - personal sign failed")
|
||||
root.store.rejectSign(requestId)
|
||||
console.error("Mainnet not found - sign failed")
|
||||
return
|
||||
}
|
||||
|
||||
const event = d.buildSignRequest(requestId, dappInfo.url, mainNet.chainId, dappInfo.challenge, dappInfo.address)
|
||||
const event = d.buildSignRequest(requestId, dappInfo.url, mainNet.chainId, dappInfo.challenge, dappInfo.address, dappInfo.method)
|
||||
d.sessionRequests.set(requestId, event)
|
||||
root.sessionRequestEvent(event)
|
||||
} catch (e) {
|
||||
d.sessionRequests.delete(requestId)
|
||||
root.store.rejectPersonalSign("", requestId)
|
||||
root.store.rejectSign("", requestId)
|
||||
console.error("Failed to parse dappInfo for session request", e)
|
||||
}
|
||||
}
|
||||
|
@ -111,21 +111,21 @@ WalletConnectSDKBase {
|
|||
}
|
||||
}
|
||||
|
||||
function onApprovePersonalSignResponse(topic, requestId, error) {
|
||||
function onApproveSignResponse(topic, requestId, error) {
|
||||
try {
|
||||
const errorStr = error ? "Faled to approve personal sign" : ""
|
||||
const errorStr = error ? "Faled to approve sign" : ""
|
||||
root.sessionRequestUserAnswerResult(topic, requestId, true, errorStr)
|
||||
} catch (e) {
|
||||
console.error("Failed to approve personal sign response", e)
|
||||
console.error("Failed to approve sign response", e)
|
||||
}
|
||||
}
|
||||
|
||||
function onRejectPersonalSignResponse(topic, requestId, error) {
|
||||
function onRejectSignResponse(topic, requestId, error) {
|
||||
try {
|
||||
const errorStr = error ? "Faled to reject personal sign" : ""
|
||||
const errorStr = error ? "Faled to reject sign" : ""
|
||||
root.sessionRequestUserAnswerResult(topic, requestId, false, errorStr)
|
||||
} catch (e) {
|
||||
console.error("Failed to reject personal sign response", e)
|
||||
console.error("Failed to reject sign response", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -165,8 +165,9 @@ WalletConnectSDKBase {
|
|||
const event = d.sessionRequests.get(requestId)
|
||||
if (event.params.request.method === SessionRequest.methods.sendTransaction.name) {
|
||||
root.store.approveTransaction(topic, requestId, signature)
|
||||
} else if (event.params.request.method === SessionRequest.methods.personalSign.name) {
|
||||
root.store.approvePersonalSign(topic, requestId, signature)
|
||||
} else if (event.params.request.method === SessionRequest.methods.personalSign.name ||
|
||||
event.params.request.method === SessionRequest.methods.signTypedData_v4.name) {
|
||||
root.store.approveSign(topic, requestId, signature)
|
||||
} else {
|
||||
root.sessionRequestUserAnswerResult(topic, requestId, false, "Unknown request method")
|
||||
console.error("Unknown request method", event.params.request.method)
|
||||
|
@ -182,8 +183,9 @@ WalletConnectSDKBase {
|
|||
const event = d.sessionRequests.get(requestId)
|
||||
if (event.params.request.method === SessionRequest.methods.sendTransaction.name) {
|
||||
root.store.rejectTransaction(topic, requestId, error)
|
||||
} else if (event.params.request.method === SessionRequest.methods.personalSign.name) {
|
||||
root.store.rejectPersonalSign(topic, requestId)
|
||||
} else if (event.params.request.method === SessionRequest.methods.personalSign.name ||
|
||||
event.params.request.method === SessionRequest.methods.signTypedData_v4.name) {
|
||||
root.store.rejectSign(topic, requestId)
|
||||
} else {
|
||||
root.sessionRequestUserAnswerResult(topic, requestId, false, "Unknown request method")
|
||||
console.error("Unknown request method", event.params.request.method)
|
||||
|
@ -292,18 +294,25 @@ WalletConnectSDKBase {
|
|||
}
|
||||
}
|
||||
|
||||
function buildSignRequest(requestId, topic, chainId, challenge, address) {
|
||||
function buildSignRequest(requestId, topic, chainId, challenge, address, method) {
|
||||
let params = []
|
||||
if (method == SessionRequest.methods.personalSign.name) {
|
||||
params = [challenge, address]
|
||||
} else if (method == SessionRequest.methods.signTypedData_v4.name) {
|
||||
params = [address, challenge]
|
||||
} else {
|
||||
console.error("Unknown sign method", method)
|
||||
return
|
||||
}
|
||||
|
||||
return {
|
||||
id: requestId,
|
||||
topic,
|
||||
params: {
|
||||
chainId: `eip155:${chainId}`,
|
||||
request: {
|
||||
method: SessionRequest.methods.personalSign.name,
|
||||
params: [
|
||||
challenge,
|
||||
address
|
||||
]
|
||||
method,
|
||||
params
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ SQUtils.QObject {
|
|||
// Signals driven by the dApp
|
||||
signal connectRequested(string requestId, string dappJson)
|
||||
signal sendTransaction(string requestId, string requestJson)
|
||||
signal personalSign(string requestId, string dappJson)
|
||||
signal sign(string requestId, string dappJson)
|
||||
|
||||
signal connected(string dappJson)
|
||||
signal disconnected(string dappJson)
|
||||
|
@ -21,8 +21,8 @@ SQUtils.QObject {
|
|||
|
||||
signal approveTransactionResponse(string topic, string requestId, bool error)
|
||||
signal rejectTransactionResponse(string topic, string requestId, bool error)
|
||||
signal approvePersonalSignResponse(string topic, string requestId, bool error)
|
||||
signal rejectPersonalSignResponse(string topic, string requestId, bool error)
|
||||
signal approveSignResponse(string topic, string requestId, bool error)
|
||||
signal rejectSignResponse(string topic, string requestId, bool error)
|
||||
|
||||
function approveConnection(id, account, chainId) {
|
||||
return controller.approveConnection(id, account, chainId)
|
||||
|
@ -48,12 +48,12 @@ SQUtils.QObject {
|
|||
return controller.getDApps()
|
||||
}
|
||||
|
||||
function approvePersonalSign(topic, requestId, signature) {
|
||||
return controller.approvePersonalSigning(topic, requestId, signature)
|
||||
function approveSign(topic, requestId, signature) {
|
||||
return controller.approveSigning(topic, requestId, signature)
|
||||
}
|
||||
|
||||
function rejectPersonalSign(topic, requestId) {
|
||||
return controller.rejectPersonalSigning(topic, requestId)
|
||||
function rejectSign(topic, requestId) {
|
||||
return controller.rejectSigning(topic, requestId)
|
||||
}
|
||||
|
||||
Connections {
|
||||
|
@ -67,8 +67,8 @@ SQUtils.QObject {
|
|||
root.sendTransaction(requestId, requestJson)
|
||||
}
|
||||
|
||||
function onPersonalSign(requestId, dappJson) {
|
||||
root.personalSign(requestId, dappJson)
|
||||
function onSign(requestId, dappJson) {
|
||||
root.sign(requestId, dappJson)
|
||||
}
|
||||
|
||||
function onConnected(dappJson) {
|
||||
|
@ -95,12 +95,12 @@ SQUtils.QObject {
|
|||
root.rejectTransactionResponse(topic, requestId, error)
|
||||
}
|
||||
|
||||
function onApprovePersonalSignResponse(topic, requestId, error) {
|
||||
root.approvePersonalSignResponse(topic, requestId, error)
|
||||
function onApproveSignResponse(topic, requestId, error) {
|
||||
root.approveSignResponse(topic, requestId, error)
|
||||
}
|
||||
|
||||
function onRejectPersonalSignResponse(topic, requestId, error) {
|
||||
root.rejectPersonalSignResponse(topic, requestId, error)
|
||||
function onRejectSignResponse(topic, requestId, error) {
|
||||
root.rejectSignResponse(topic, requestId, error)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1 +1 @@
|
|||
Subproject commit ed36d60540f4cc96101ca47bacdf841e38e40bfd
|
||||
Subproject commit c5dede93b082532af770c47ed43f726af09a2576
|
Loading…
Reference in New Issue