Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(BC): Implementing the personal_sign #16751

Open
wants to merge 1 commit into
base: feat/wallet-connect-service
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions src/app/core/signals/remote_signals/connector.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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()
1 change: 1 addition & 0 deletions src/app/core/signals/remote_signals/signal_type.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down
2 changes: 2 additions & 0 deletions src/app/core/signals/signals_manager.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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
29 changes: 27 additions & 2 deletions src/app/modules/shared_modules/connector/controller.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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)
Expand Down Expand Up @@ -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)
Expand All @@ -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 =
Expand Down Expand Up @@ -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)
30 changes: 29 additions & 1 deletion src/app_service/service/connector/service.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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: ")
18 changes: 17 additions & 1 deletion src/backend/connector.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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

Expand All @@ -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))
133 changes: 117 additions & 16 deletions ui/app/AppLayouts/Wallet/services/dapps/DappsConnectorSDK.qml
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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,
Expand All @@ -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
]
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down
Loading