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
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 =
result = ConnectorSendRequestAccountsSignal()
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.name = event["event"]{"name"}.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"
ConnectorGrantDAppPermission = "connector.dAppPermissionGranted"
ConnectorRevokeDAppPermission = "connector.dAppPermissionRevoked"
ConnectorPersonalSign = "connector.personalSign"
Unknown
proc event*(self:SignalType):string =

View File

@ -140,10 +140,12 @@ QtObject:
of SignalType.LocalPairing: LocalPairingSignal.fromEvent(jsonSignal)
of SignalType.CommunityTokenTransactionStatusChanged: CommunityTokenTransactionStatusChangedSignal.fromEvent(jsonSignal)
of SignalType.CommunityTokenAction: CommunityTokenActionSignal.fromEvent(jsonSignal)
# connector
of SignalType.ConnectorSendRequestAccounts: ConnectorSendRequestAccountsSignal.fromEvent(jsonSignal)
of SignalType.ConnectorSendTransaction: ConnectorSendTransactionSignal.fromEvent(jsonSignal)
of SignalType.ConnectorGrantDAppPermission: ConnectorGrantDAppPermissionSignal.fromEvent(jsonSignal)
of SignalType.ConnectorRevokeDAppPermission: ConnectorRevokeDAppPermissionSignal.fromEvent(jsonSignal)
of SignalType.ConnectorPersonalSign: ConnectorPersonalSignSignal.fromEvent(jsonSignal)
else: Signal()
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_GRANT_DAPP_PERMISSION* = "ConnectorGrantDAppPermission"
const SIGNAL_CONNECTOR_REVOKE_DAPP_PERMISSION* = "ConnectorRevokeDAppPermission"
const SIGNAL_CONNECTOR_PERSONAL_SIGN* = "ConnectorPersonalSign"
logScope:
topics = "connector-controller"
@ -30,12 +31,15 @@ QtObject:
proc connected*(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 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 newController*(service: connector_service.Service, events: EventEmitter): Controller =
new(result, delete)
@ -69,7 +73,7 @@ QtObject:
"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):
let params = ConnectorGrantDAppPermissionSignal(e)
@ -93,6 +97,18 @@ QtObject:
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
proc parseSingleUInt(chainIDsString: string): uint =
@ -129,3 +145,12 @@ 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 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_GRANT_DAPP_PERMISSION* = "ConnectorGrantDAppPermission"
const SIGNAL_CONNECTOR_REVOKE_DAPP_PERMISSION* = "ConnectorRevokeDAppPermission"
const SIGNAL_CONNECTOR_EVENT_CONNECTOR_PERSONAL_SIGN* = "ConnectorPersonalSign"
# Enum with events
type Event* = enum
@ -83,6 +84,18 @@ QtObject:
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) =
self.eventHandler = handler
@ -150,4 +163,19 @@ QtObject:
return if jsonArray != "null": jsonArray else: "[]"
except Exception as e:
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
dAppUrl* {.serializedFieldName("dAppUrl").}: string
type PersonalSignAcceptedArgs* = ref object of RootObj
requestId* {.serializedFieldName("requestId").}: string
signature* {.serializedFieldName("signature").}: string
rpc(requestAccountsAccepted, "connector"):
args: RequestAccountsAcceptedArgs
@ -41,6 +45,12 @@ rpc(recallDAppPermission, "connector"):
rpc(getPermittedDAppsList, "connector"):
discard
rpc(personalSignAccepted, "connector"):
args: PersonalSignAcceptedArgs
rpc(personalSignRejected, "connector"):
args: RejectedArgs
proc isSuccessResponse(rpcResponse: RpcResponse[JsonNode]): bool =
return rpcResponse.error.isNil
@ -57,4 +67,10 @@ proc sendTransactionRejectedFinishedRpc*(args: RejectedArgs): bool =
return isSuccessResponse(sendTransactionRejected(args))
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
enabled: root.enabled
function onSignRequested(requestId, dappInfoString) {
function onSendTransaction(requestId, dappInfoString) {
try {
var dappInfo = JSON.parse(dappInfoString)
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)
} 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)
}
}
@ -87,6 +110,24 @@ WalletConnectSDKBase {
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) {
@ -116,11 +157,37 @@ WalletConnectSDKBase {
}
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) {
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) {
@ -182,7 +249,34 @@ WalletConnectSDKBase {
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 {
id: requestId,
topic,
@ -191,17 +285,24 @@ WalletConnectSDKBase {
request: {
method: SessionRequest.methods.sendTransaction.name,
params: [
{
from: txArgs.from,
to: txArgs.to,
value: txArgs.value,
gasLimit: txArgs.gas,
gasPrice: txArgs.gasPrice,
maxFeePerGas: txArgs.maxFeePerGas,
maxPriorityFeePerGas: txArgs.maxPriorityFeePerGas,
nonce: txArgs.nonce,
data: txArgs.data
}
paramsObj
]
}
}
}
}
function buildSignRequest(requestId, topic, chainId, challenge, address) {
return {
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) {
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
}

View File

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