fix(BC): Implementing the personal_sign

This commit is contained in:
Alex Jbanca 2024-11-11 18:22:45 +02:00
parent 00fb1ff60a
commit ca0456ecae
No known key found for this signature in database
GPG Key ID: 6004079575C21C5D
10 changed files with 239 additions and 25 deletions

View File

@ -29,6 +29,14 @@ type ConnectorRevokeDAppPermissionSignal* = ref object of Signal
name*: string name*: string
iconUrl*: string iconUrl*: string
type ConnectorPersonalSignSignal* = ref object of Signal
url*: string
name*: string
iconUrl*: string
requestId*: string
challenge*: string
address*: string
proc fromEvent*(T: type ConnectorSendRequestAccountsSignal, event: JsonNode): ConnectorSendRequestAccountsSignal = proc fromEvent*(T: type ConnectorSendRequestAccountsSignal, event: JsonNode): ConnectorSendRequestAccountsSignal =
result = ConnectorSendRequestAccountsSignal() result = ConnectorSendRequestAccountsSignal()
result.url = event["event"]{"url"}.getStr() result.url = event["event"]{"url"}.getStr()
@ -58,3 +66,12 @@ proc fromEvent*(T: type ConnectorRevokeDAppPermissionSignal, event: JsonNode): C
result.url = event["event"]{"url"}.getStr() result.url = event["event"]{"url"}.getStr()
result.name = event["event"]{"name"}.getStr() result.name = event["event"]{"name"}.getStr()
result.iconUrl = event["event"]{"iconUrl"}.getStr() result.iconUrl = event["event"]{"iconUrl"}.getStr()
proc fromEvent*(T: type ConnectorPersonalSignSignal, event: JsonNode): ConnectorPersonalSignSignal =
result = ConnectorPersonalSignSignal()
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()

View File

@ -74,6 +74,7 @@ type SignalType* {.pure.} = enum
ConnectorSendTransaction = "connector.sendTransaction" ConnectorSendTransaction = "connector.sendTransaction"
ConnectorGrantDAppPermission = "connector.dAppPermissionGranted" ConnectorGrantDAppPermission = "connector.dAppPermissionGranted"
ConnectorRevokeDAppPermission = "connector.dAppPermissionRevoked" ConnectorRevokeDAppPermission = "connector.dAppPermissionRevoked"
ConnectorPersonalSign = "connector.personalSign"
Unknown Unknown
proc event*(self:SignalType):string = proc event*(self:SignalType):string =

View File

@ -140,10 +140,12 @@ QtObject:
of SignalType.LocalPairing: LocalPairingSignal.fromEvent(jsonSignal) of SignalType.LocalPairing: LocalPairingSignal.fromEvent(jsonSignal)
of SignalType.CommunityTokenTransactionStatusChanged: CommunityTokenTransactionStatusChangedSignal.fromEvent(jsonSignal) of SignalType.CommunityTokenTransactionStatusChanged: CommunityTokenTransactionStatusChangedSignal.fromEvent(jsonSignal)
of SignalType.CommunityTokenAction: CommunityTokenActionSignal.fromEvent(jsonSignal) of SignalType.CommunityTokenAction: CommunityTokenActionSignal.fromEvent(jsonSignal)
# connector
of SignalType.ConnectorSendRequestAccounts: ConnectorSendRequestAccountsSignal.fromEvent(jsonSignal) of SignalType.ConnectorSendRequestAccounts: ConnectorSendRequestAccountsSignal.fromEvent(jsonSignal)
of SignalType.ConnectorSendTransaction: ConnectorSendTransactionSignal.fromEvent(jsonSignal) of SignalType.ConnectorSendTransaction: ConnectorSendTransactionSignal.fromEvent(jsonSignal)
of SignalType.ConnectorGrantDAppPermission: ConnectorGrantDAppPermissionSignal.fromEvent(jsonSignal) of SignalType.ConnectorGrantDAppPermission: ConnectorGrantDAppPermissionSignal.fromEvent(jsonSignal)
of SignalType.ConnectorRevokeDAppPermission: ConnectorRevokeDAppPermissionSignal.fromEvent(jsonSignal) of SignalType.ConnectorRevokeDAppPermission: ConnectorRevokeDAppPermissionSignal.fromEvent(jsonSignal)
of SignalType.ConnectorPersonalSign: ConnectorPersonalSignSignal.fromEvent(jsonSignal)
else: Signal() else: Signal()
result.signalType = signalType result.signalType = signalType

View File

@ -13,6 +13,7 @@ const SIGNAL_CONNECTOR_SEND_REQUEST_ACCOUNTS* = "ConnectorSendRequestAccounts"
const SIGNAL_CONNECTOR_EVENT_CONNECTOR_SEND_TRANSACTION* = "ConnectorSendTransaction" const SIGNAL_CONNECTOR_EVENT_CONNECTOR_SEND_TRANSACTION* = "ConnectorSendTransaction"
const SIGNAL_CONNECTOR_GRANT_DAPP_PERMISSION* = "ConnectorGrantDAppPermission" const SIGNAL_CONNECTOR_GRANT_DAPP_PERMISSION* = "ConnectorGrantDAppPermission"
const SIGNAL_CONNECTOR_REVOKE_DAPP_PERMISSION* = "ConnectorRevokeDAppPermission" const SIGNAL_CONNECTOR_REVOKE_DAPP_PERMISSION* = "ConnectorRevokeDAppPermission"
const SIGNAL_CONNECTOR_PERSONAL_SIGN* = "ConnectorPersonalSign"
logScope: logScope:
topics = "connector-controller" topics = "connector-controller"
@ -30,12 +31,15 @@ QtObject:
proc connected*(self: Controller, payload: string) {.signal.} proc connected*(self: Controller, payload: string) {.signal.}
proc disconnected*(self: Controller, payload: string) {.signal.} proc disconnected*(self: Controller, payload: string) {.signal.}
proc signRequested*(self: Controller, requestId: string, payload: string) {.signal.} proc sendTransaction*(self: Controller, requestId: string, payload: string) {.signal.}
proc personalSign(self: Controller, requestId: string, payload: string) {.signal.}
proc approveConnectResponse*(self: Controller, payload: string, error: bool) {.signal.} proc approveConnectResponse*(self: Controller, payload: string, error: bool) {.signal.}
proc rejectConnectResponse*(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 approveTransactionResponse*(self: Controller, topic: string, requestId: string, error: bool) {.signal.}
proc rejectTransactionResponse*(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 newController*(service: connector_service.Service, events: EventEmitter): Controller = proc newController*(service: connector_service.Service, events: EventEmitter): Controller =
new(result, delete) new(result, delete)
@ -69,7 +73,7 @@ QtObject:
"txArgs": params.txArgs, "txArgs": params.txArgs,
} }
controller.signRequested(params.requestId, dappInfo.toJson()) controller.sendTransaction(params.requestId, dappInfo.toJson())
result.events.on(SIGNAL_CONNECTOR_GRANT_DAPP_PERMISSION) do(e: Args): result.events.on(SIGNAL_CONNECTOR_GRANT_DAPP_PERMISSION) do(e: Args):
let params = ConnectorGrantDAppPermissionSignal(e) let params = ConnectorGrantDAppPermissionSignal(e)
@ -93,6 +97,18 @@ QtObject:
controller.disconnected(dappInfo.toJson()) controller.disconnected(dappInfo.toJson())
result.events.on(SIGNAL_CONNECTOR_PERSONAL_SIGN) do(e: Args):
let params = ConnectorPersonalSignSignal(e)
let dappInfo = %*{
"icon": params.iconUrl,
"name": params.name,
"url": params.url,
"challenge": params.challenge,
"address": params.address,
}
controller.personalSign(params.requestId, dappInfo.toJson())
result.QObject.setup result.QObject.setup
proc parseSingleUInt(chainIDsString: string): uint = proc parseSingleUInt(chainIDsString: string): uint =
@ -129,3 +145,12 @@ QtObject:
proc getDApps*(self: Controller): string {.slot.} = proc getDApps*(self: Controller): string {.slot.} =
return self.service.getDApps() 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 rejectPersonalSigning*(self: Controller, sessionTopic: string, requestId: string): bool {.slot.} =
result = self.service.rejectPersonalSigning(requestId)
self.rejectPersonalSignResponse(sessionTopic, requestId, not result)

View File

@ -16,6 +16,7 @@ const SIGNAL_CONNECTOR_SEND_REQUEST_ACCOUNTS* = "ConnectorSendRequestAccounts"
const SIGNAL_CONNECTOR_EVENT_CONNECTOR_SEND_TRANSACTION* = "ConnectorSendTransaction" const SIGNAL_CONNECTOR_EVENT_CONNECTOR_SEND_TRANSACTION* = "ConnectorSendTransaction"
const SIGNAL_CONNECTOR_GRANT_DAPP_PERMISSION* = "ConnectorGrantDAppPermission" const SIGNAL_CONNECTOR_GRANT_DAPP_PERMISSION* = "ConnectorGrantDAppPermission"
const SIGNAL_CONNECTOR_REVOKE_DAPP_PERMISSION* = "ConnectorRevokeDAppPermission" const SIGNAL_CONNECTOR_REVOKE_DAPP_PERMISSION* = "ConnectorRevokeDAppPermission"
const SIGNAL_CONNECTOR_EVENT_CONNECTOR_PERSONAL_SIGN* = "ConnectorPersonalSign"
# Enum with events # Enum with events
type Event* = enum type Event* = enum
@ -83,6 +84,18 @@ QtObject:
self.events.emit(SIGNAL_CONNECTOR_REVOKE_DAPP_PERMISSION, data) self.events.emit(SIGNAL_CONNECTOR_REVOKE_DAPP_PERMISSION, data)
) )
self.events.on(SignalType.ConnectorPersonalSign.event, proc(e: Args) =
if self.eventHandler == nil:
return
var data = ConnectorPersonalSignSignal(e)
if not data.requestId.len() == 0:
error "ConnectorPersonalSignSignal failed, requestId is empty"
return
self.events.emit(SIGNAL_CONNECTOR_EVENT_CONNECTOR_PERSONAL_SIGN, data)
)
proc registerEventsHandler*(self: Service, handler: EventHandlerFn) = proc registerEventsHandler*(self: Service, handler: EventHandlerFn) =
self.eventHandler = handler self.eventHandler = handler
@ -151,3 +164,18 @@ QtObject:
except Exception as e: except Exception as e:
error "getDApps failed: ", err=e.msg error "getDApps failed: ", err=e.msg
return "[]" return "[]"
proc approvePersonalSignRequest*(self: Service, requestId: string, signature: string): bool =
try:
var args = PersonalSignAcceptedArgs()
args.requestId = requestId
args.signature = signature
return status_go.sendPersonalSignAcceptedFinishedRpc(args)
except Exception as e:
error "sendPersonalSigAcceptedFinishedRpc failed: ", err=e.msg
return false
proc rejectPersonalSigning*(self: Service, requestId: string): bool =
rejectRequest(self, requestId, status_go.sendPersonalSignRejectedFinishedRpc, "sendPersonalSignRejectedFinishedRpc failed: ")

View File

@ -23,6 +23,10 @@ type RejectedArgs* = ref object of RootObj
type RecallDAppPermissionArgs* = ref object of RootObj type RecallDAppPermissionArgs* = ref object of RootObj
dAppUrl* {.serializedFieldName("dAppUrl").}: string dAppUrl* {.serializedFieldName("dAppUrl").}: string
type PersonalSignAcceptedArgs* = ref object of RootObj
requestId* {.serializedFieldName("requestId").}: string
signature* {.serializedFieldName("signature").}: string
rpc(requestAccountsAccepted, "connector"): rpc(requestAccountsAccepted, "connector"):
args: RequestAccountsAcceptedArgs args: RequestAccountsAcceptedArgs
@ -41,6 +45,12 @@ rpc(recallDAppPermission, "connector"):
rpc(getPermittedDAppsList, "connector"): rpc(getPermittedDAppsList, "connector"):
discard discard
rpc(personalSignAccepted, "connector"):
args: PersonalSignAcceptedArgs
rpc(personalSignRejected, "connector"):
args: RejectedArgs
proc isSuccessResponse(rpcResponse: RpcResponse[JsonNode]): bool = proc isSuccessResponse(rpcResponse: RpcResponse[JsonNode]): bool =
return rpcResponse.error.isNil return rpcResponse.error.isNil
@ -58,3 +68,9 @@ proc sendTransactionRejectedFinishedRpc*(args: RejectedArgs): bool =
proc recallDAppPermissionFinishedRpc*(dAppUrl: string): bool = proc recallDAppPermissionFinishedRpc*(dAppUrl: string): bool =
return isSuccessResponse(recallDAppPermission(dAppUrl)) return isSuccessResponse(recallDAppPermission(dAppUrl))
proc sendPersonalSignAcceptedFinishedRpc*(args: PersonalSignAcceptedArgs): bool =
return isSuccessResponse(personalSignAccepted(args))
proc sendPersonalSignRejectedFinishedRpc*(args: RejectedArgs): bool =
return isSuccessResponse(personalSignRejected(args))

View File

@ -38,14 +38,37 @@ WalletConnectSDKBase {
target: root.store target: root.store
enabled: root.enabled enabled: root.enabled
function onSignRequested(requestId, dappInfoString) { function onSendTransaction(requestId, dappInfoString) {
try { try {
var dappInfo = JSON.parse(dappInfoString) var dappInfo = JSON.parse(dappInfoString)
var txArgsParams = JSON.parse(dappInfo.txArgs) var txArgsParams = JSON.parse(dappInfo.txArgs)
let event = d.buildSessionRequest(requestId, dappInfo.url, dappInfo.chainId, SessionRequest.methods.sendTransaction.name, txArgsParams) let event = d.buildTransactionRequest(requestId, dappInfo.url, dappInfo.chainId, txArgsParams)
d.sessionRequests.set(requestId, event)
root.sessionRequestEvent(event) root.sessionRequestEvent(event)
} catch (e) { } catch (e) {
d.sessionRequests.delete(requestId)
root.store.rejectTransaction("", requestId, "Failed to parse dappInfo for session request")
console.error("Failed to parse dappInfo for session request", e)
}
}
function onPersonalSign(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")
return
}
const event = d.buildSignRequest(requestId, dappInfo.url, mainNet.chainId, dappInfo.challenge, dappInfo.address)
d.sessionRequests.set(requestId, event)
root.sessionRequestEvent(event)
} catch (e) {
d.sessionRequests.delete(requestId)
root.store.rejectPersonalSign("", requestId)
console.error("Failed to parse dappInfo for session request", e) console.error("Failed to parse dappInfo for session request", e)
} }
} }
@ -87,6 +110,24 @@ WalletConnectSDKBase {
console.error("Failed to reject transaction response", e) console.error("Failed to reject transaction response", e)
} }
} }
function onApprovePersonalSignResponse(topic, requestId, error) {
try {
const errorStr = error ? "Faled to approve personal sign" : ""
root.sessionRequestUserAnswerResult(topic, requestId, true, errorStr)
} catch (e) {
console.error("Failed to approve personal sign response", e)
}
}
function onRejectPersonalSignResponse(topic, requestId, error) {
try {
const errorStr = error ? "Faled to reject personal sign" : ""
root.sessionRequestUserAnswerResult(topic, requestId, false, errorStr)
} catch (e) {
console.error("Failed to reject personal sign response", e)
}
}
} }
approveSession: function(requestId, account, selectedChains) { approveSession: function(requestId, account, selectedChains) {
@ -116,11 +157,37 @@ WalletConnectSDKBase {
} }
acceptSessionRequest: function(topic, requestId, signature) { acceptSessionRequest: function(topic, requestId, signature) {
root.store.approveTransaction(topic, requestId, signature) if (!d.sessionRequests.has(requestId)) {
root.sessionRequestUserAnswerResult(topic, requestId, false, "Unknown request method")
console.error("Session request not found")
return
}
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 {
root.sessionRequestUserAnswerResult(topic, requestId, false, "Unknown request method")
console.error("Unknown request method", event.params.request.method)
}
} }
rejectSessionRequest: function(topic, requestId, error) { rejectSessionRequest: function(topic, requestId, error) {
root.store.rejectTransaction(topic, requestId, error) if (!d.sessionRequests.has(requestId)) {
root.sessionRequestUserAnswerResult(topic, requestId, false, "Unknown request method")
console.error("Session request not found")
return
}
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 {
root.sessionRequestUserAnswerResult(topic, requestId, false, "Unknown request method")
console.error("Unknown request method", event.params.request.method)
}
} }
disconnectSession: function(topic) { disconnectSession: function(topic) {
@ -182,7 +249,34 @@ WalletConnectSDKBase {
return sessionTemplate(dappUrl, dappName, dappIcon, proposalId, eipAccount, eipChains) return sessionTemplate(dappUrl, dappName, dappIcon, proposalId, eipAccount, eipChains)
} }
function buildSessionRequest(requestId, topic, chainId, method, txArgs) { function buildTransactionRequest(requestId, topic, chainId, txArgs) {
var paramsObj = {}
if (txArgs.gasPrice) {
paramsObj.gasPrice = txArgs.gasPrice
}
if (txArgs.gas) {
paramsObj.gasLimit = txArgs.gas
}
if (txArgs.maxFeePerGas) {
paramsObj.maxFeePerGas = txArgs.maxFeePerGas
}
if (txArgs.maxPriorityFeePerGas) {
paramsObj.maxPriorityFeePerGas = txArgs.maxPriorityFeePerGas
}
if (txArgs.nonce) {
paramsObj.nonce = txArgs.nonce
}
if (!!txArgs.data && txArgs.data !== "0x") {
paramsObj.data = txArgs.data
}
if (txArgs.to) {
paramsObj.to = txArgs.to
}
if (txArgs.from) {
paramsObj.from = txArgs.from
}
paramsObj.value = txArgs.value
return { return {
id: requestId, id: requestId,
topic, topic,
@ -191,17 +285,24 @@ WalletConnectSDKBase {
request: { request: {
method: SessionRequest.methods.sendTransaction.name, method: SessionRequest.methods.sendTransaction.name,
params: [ params: [
{ paramsObj
from: txArgs.from, ]
to: txArgs.to, }
value: txArgs.value, }
gasLimit: txArgs.gas, }
gasPrice: txArgs.gasPrice, }
maxFeePerGas: txArgs.maxFeePerGas,
maxPriorityFeePerGas: txArgs.maxPriorityFeePerGas, function buildSignRequest(requestId, topic, chainId, challenge, address) {
nonce: txArgs.nonce, return {
data: txArgs.data id: requestId,
} topic,
params: {
chainId: `eip155:${chainId}`,
request: {
method: SessionRequest.methods.personalSign.name,
params: [
challenge,
address
] ]
} }
} }

View File

@ -169,7 +169,8 @@ SQUtils.QObject {
if (error) { if (error) {
root.signCompleted(topic, id, accept, error) root.signCompleted(topic, id, accept, error)
console.error(`Error accepting session request for topic: ${topic}, id: ${id}, accept: ${accept}, error: ${error}`) const action = accept ? "accepting" : "rejecting"
console.error(`Error ${action} session request for topic: ${topic}, id: ${id}, accept: ${accept}, error: ${error}`)
return return
} }

View File

@ -9,7 +9,8 @@ SQUtils.QObject {
// Signals driven by the dApp // Signals driven by the dApp
signal connectRequested(string requestId, string dappJson) signal connectRequested(string requestId, string dappJson)
signal signRequested(string requestId, string requestJson) signal sendTransaction(string requestId, string requestJson)
signal personalSign(string requestId, string dappJson)
signal connected(string dappJson) signal connected(string dappJson)
signal disconnected(string dappJson) signal disconnected(string dappJson)
@ -20,6 +21,8 @@ SQUtils.QObject {
signal approveTransactionResponse(string topic, string requestId, bool error) signal approveTransactionResponse(string topic, string requestId, bool error)
signal rejectTransactionResponse(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)
function approveConnection(id, account, chainId) { function approveConnection(id, account, chainId) {
return controller.approveConnection(id, account, chainId) return controller.approveConnection(id, account, chainId)
@ -45,6 +48,14 @@ SQUtils.QObject {
return controller.getDApps() return controller.getDApps()
} }
function approvePersonalSign(topic, requestId, signature) {
return controller.approvePersonalSigning(topic, requestId, signature)
}
function rejectPersonalSign(topic, requestId) {
return controller.rejectPersonalSigning(topic, requestId)
}
Connections { Connections {
target: controller target: controller
@ -52,8 +63,12 @@ SQUtils.QObject {
root.connectRequested(requestId, dappJson) root.connectRequested(requestId, dappJson)
} }
function onSignRequested(requestId, requestJson) { function onSendTransaction(requestId, requestJson) {
root.signRequested(requestId, requestJson) root.sendTransaction(requestId, requestJson)
}
function onPersonalSign(requestId, dappJson) {
root.personalSign(requestId, dappJson)
} }
function onConnected(dappJson) { function onConnected(dappJson) {
@ -79,5 +94,13 @@ SQUtils.QObject {
function onRejectTransactionResponse(topic, requestId, error) { function onRejectTransactionResponse(topic, requestId, error) {
root.rejectTransactionResponse(topic, requestId, error) root.rejectTransactionResponse(topic, requestId, error)
} }
function onApprovePersonalSignResponse(topic, requestId, error) {
root.approvePersonalSignResponse(topic, requestId, error)
}
function onRejectPersonalSignResponse(topic, requestId, error) {
root.rejectPersonalSignResponse(topic, requestId, error)
}
} }
} }

2
vendor/status-go vendored

@ -1 +1 @@
Subproject commit ba2baec26fac64fe074b485639e95a7b11e81ae5 Subproject commit 43f355a391ae2ccf304c9b71a1a6af35a3ddb67e