Skip to content

Commit 5d3b34d

Browse files
committed
feat(dapp-browser)_: change account from popup
1 parent 1b14149 commit 5d3b34d

File tree

10 files changed

+126
-66
lines changed

10 files changed

+126
-66
lines changed

src/app/core/signals/remote_signals/connector.nim

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ type ConnectorDAppChainIdSwitchedSignal* = ref object of Signal
4242
url*: string
4343
chainId*: string
4444

45+
type ConnectorAccountChangedSignal* = ref object of Signal
46+
url*: string
47+
clientId*: string
48+
sharedAccount*: string
49+
4550
proc fromEvent*(T: type ConnectorSendRequestAccountsSignal, event: JsonNode): ConnectorSendRequestAccountsSignal =
4651
result = ConnectorSendRequestAccountsSignal()
4752
result.signalType = SignalType.ConnectorSendRequestAccounts
@@ -91,4 +96,11 @@ proc fromEvent*(T: type ConnectorDAppChainIdSwitchedSignal, event: JsonNode): Co
9196
result = ConnectorDAppChainIdSwitchedSignal()
9297
result.signalType = SignalType.ConnectorDAppChainIdSwitched
9398
result.url = event["event"]{"url"}.getStr()
94-
result.chainId = event["event"]{"chainId"}.getStr()
99+
result.chainId = event["event"]{"chainId"}.getStr()
100+
101+
proc fromEvent*(T: type ConnectorAccountChangedSignal, event: JsonNode): ConnectorAccountChangedSignal =
102+
result = ConnectorAccountChangedSignal()
103+
result.signalType = SignalType.ConnectorAccountChanged
104+
result.url = event["event"]{"url"}.getStr()
105+
result.clientId = event["event"]{"clientId"}.getStr()
106+
result.sharedAccount = event["event"]{"sharedAccount"}.getStr()

src/app/core/signals/remote_signals/signal_type.nim

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ type SignalType* {.pure.} = enum
7575
ConnectorRevokeDAppPermission = "connector.dAppPermissionRevoked"
7676
ConnectorSign = "connector.Sign"
7777
ConnectorDAppChainIdSwitched = "connector.dAppChainIdSwitched"
78+
ConnectorAccountChanged = "connector.dAppAccountChanged"
7879
LocalMessageBackupDone = "local.message.backup.done"
7980
Unknown
8081

src/app/core/signals/signals_manager.nim

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ QtObject:
143143
of SignalType.ConnectorRevokeDAppPermission: ConnectorRevokeDAppPermissionSignal.fromEvent(jsonSignal)
144144
of SignalType.ConnectorSign: ConnectorSignSignal.fromEvent(jsonSignal)
145145
of SignalType.ConnectorDAppChainIdSwitched: ConnectorDAppChainIdSwitchedSignal.fromEvent(jsonSignal)
146+
of SignalType.ConnectorAccountChanged: ConnectorAccountChangedSignal.fromEvent(jsonSignal)
146147
# networks
147148
of SignalType.NetworksBlockchainHealthChanged: NetworksBlockchainHealthChangedSignal.fromEvent(jsonSignal)
148149
else:

src/app_service/service/connector/service.nim

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,20 @@ QtObject:
223223
except:
224224
error "connectorCallRPC: starting async background task failed", requestId=requestId
225225

226+
proc changeAccount*(self: Service, url: string, clientId: string, newAccount: string): bool =
227+
try:
228+
var args = ChangeAccountArgs(
229+
url: url,
230+
account: newAccount,
231+
clientID: clientId
232+
)
233+
234+
return status_go.changeAccountFinishedRpc(args)
235+
236+
except Exception as e:
237+
error "changeAccount failed", error=e.msg
238+
return false
239+
226240
proc delete*(self: Service) =
227241
self.QObject.delete
228242

src/backend/connector.nim

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ type SignAcceptedArgs* = ref object of RootObj
3131
requestId* {.serializedFieldName("requestId").}: string
3232
signature* {.serializedFieldName("signature").}: string
3333

34+
type ChangeAccountArgs* = ref object of RootObj
35+
url* {.serializedFieldName("url").}: string
36+
account* {.serializedFieldName("account").}: string
37+
clientID* {.serializedFieldName("clientId").}: string
38+
3439
rpc(requestAccountsAccepted, "connector"):
3540
args: RequestAccountsAcceptedArgs
3641

@@ -58,6 +63,9 @@ rpc(signRejected, "connector"):
5863
rpc(callRPC, "connector"):
5964
inputJSON: string
6065

66+
rpc(changeAccount, "connector"):
67+
args: ChangeAccountArgs
68+
6169
proc isSuccessResponse(rpcResponse: RpcResponse[JsonNode]): bool =
6270
return rpcResponse.error.isNil
6371

@@ -84,3 +92,6 @@ proc sendSignRejectedFinishedRpc*(args: RejectedArgs): bool =
8492

8593
proc connectorCallRPC*(inputJSON: string): RpcResponse[JsonNode] {.raises: [Exception].} =
8694
return callRPC(inputJSON)
95+
96+
proc changeAccountFinishedRpc*(args: ChangeAccountArgs): bool =
97+
return isSuccessResponse(changeAccount(args))

ui/app/AppLayouts/Browser/BrowserLayout.qml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,7 @@ StatusSectionLayout {
362362
y: (Math.abs(browserHeader.mapFromGlobal(headerPoint).y) +
363363
browserHeader.anchors.topMargin + Theme.halfPadding)
364364
onSendTriggered: (address) => root.sendToRecipientRequested(address)
365+
onAccountChanged: (newAddress) => connectorBridge.manager.changeAccount(newAddress)
365366
onReload: {
366367
for (let i = 0; i < tabs.count; ++i){
367368
tabs.getTab(i).reload();

ui/app/AppLayouts/Browser/popups/BrowserWalletMenu.qml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ Dialog {
2828
signal sendTriggered(string address)
2929
signal disconnect()
3030
signal reload()
31+
signal accountChanged(string newAddress)
3132

3233
modal: false
3334

@@ -155,6 +156,7 @@ Dialog {
155156

156157
accountSelectorRow.currentAddress = currentAccountAddress
157158
root.browserWalletStore.switchAccountByAddress(currentAccountAddress)
159+
root.accountChanged(currentAccountAddress)
158160
reload()
159161
}
160162
}

ui/app/AppLayouts/Browser/provider/qml/ConnectorBridge.qml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ Item {
6565

6666
const urlStr = url.toString()
6767
connectorManager.dappUrl = urlStr
68-
connectorManager.dappOrigin = urlStr
68+
connectorManager.dappOrigin = Utils.normalizeOrigin(urlStr)
6969
connectorManager.dappName = name || Utils.extractDomainName(urlStr)
7070
connectorManager.dappChainId = 1
7171
}

ui/app/AppLayouts/Browser/provider/qml/ConnectorManager.qml

Lines changed: 72 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -32,30 +32,30 @@ Item {
3232
signal messageEvent(var message)
3333
signal requestCompletedEvent(var payload)
3434

35-
// PUBLIC API - EIP-1193 REQUEST
36-
function request(args) {
37-
if (!args || !args.method) {
38-
console.error("[ConnectorManager] Invalid request")
39-
return JSON.stringify({
40-
error: { code: -32600, message: "Missing method" }
41-
})
42-
}
43-
44-
const method = args.method
45-
const requestId = args.requestId || 0
46-
47-
var rpcRequest = {
48-
"jsonrpc": "2.0",
49-
"id": requestId,
50-
"method": method,
51-
"params": args.params || [],
52-
"url": dappOrigin || dappUrl || "",
53-
"name": dappName || "Unknown dApp",
54-
"clientId": clientId,
55-
"chainId": dappChainId,
56-
"iconUrl": dappIconUrl || ""
57-
}
58-
35+
// PUBLIC API - EIP-1193 REQUEST
36+
function request(args) {
37+
if (!args || !args.method) {
38+
console.error("[ConnectorManager] Invalid request - missing method")
39+
return JSON.stringify({
40+
error: { code: -32600, message: "Missing method" } // EIP-1193: Invalid Request
41+
})
42+
}
43+
44+
const method = args.method
45+
const requestId = args.requestId || 0
46+
47+
var rpcRequest = {
48+
"jsonrpc": "2.0",
49+
"id": requestId,
50+
"method": method,
51+
"params": args.params || [],
52+
"url": dappOrigin || "",
53+
"name": dappName || "Unknown dApp",
54+
"clientId": clientId,
55+
"chainId": dappChainId,
56+
"iconUrl": dappIconUrl || ""
57+
}
58+
5959
// Direct call to Nim connectorCallRPC -> status-go connector/api.go
6060
if (connectorController) {
6161
connectorController.connectorCallRPC(requestId, JSON.stringify(rpcRequest))
@@ -81,13 +81,13 @@ Item {
8181
_hasPermission = newAccounts.length > 0
8282

8383
providerStateChanged()
84-
accountsChangedEvent(accounts)
84+
accuntsChangedEvent(accounts)
8585
console.log("[ConnectorManager] Accounts updated:", JSON.stringify(accounts))
86-
return true
87-
}
88-
89-
function setConnected(isConnected) {
90-
if (connected === isConnected) {
86+
return true
87+
}
88+
89+
function setConnected(isConnected) {
90+
if (connected === isConnected) {
9191
return false
9292
}
9393

@@ -118,27 +118,29 @@ Item {
118118
_initialConnectionDone = false
119119

120120
providerStateChanged()
121-
disconnectEvent({ code: 4900, message: "User disconnected" }) // EIP-1193: Disconnected
122-
accountsChangedEvent([])
123-
console.log("[ConnectorManager] State cleared")
124-
return true
125-
}
126-
127-
// PUBLIC API
128-
function disconnect() {
129-
console.log("[ConnectorManager] Disconnecting dApp")
130-
131-
clearState()
132-
133-
if (connectorController) {
134-
const effectiveUrl = dappOrigin || dappUrl
135-
console.log("[ConnectorManager] Calling backend disconnect for:", effectiveUrl)
136-
connectorController.disconnect(effectiveUrl)
137-
}
138-
}
139-
140-
// HELPER FUNCTIONS
141-
function shouldProcessSignal(event) {
121+
disconnectEvent({ code: 4900, message: "User disconnected" }) // EIP-1193: Disconnected
122+
accountsChangedEvent([])
123+
console.log("[ConnectorManager] State cleared")
124+
return true
125+
}
126+
127+
// PUBLIC API
128+
function disconnect() {
129+
clearState()
130+
131+
if (connectorController) {
132+
connectorController.disconnect(dappOrigin)
133+
}
134+
}
135+
136+
function changeAccount(newAccount) {
137+
if (connectorController) {
138+
connectorController.changeAccount(dappOrigin, clientId, newAccount)
139+
}
140+
}
141+
142+
// HELPER FUNCTIONS
143+
function shouldProcessSignal(event) {
142144
// Filter by origin
143145
if (event.url && Utils.normalizeOrigin(event.url) !== Utils.normalizeOrigin(dappOrigin)) {
144146
console.log("[ConnectorManager] Ignoring signal for other origin:", event.url, "expected:", dappOrigin)
@@ -216,12 +218,23 @@ Item {
216218
const chainIdHex = Utils.chainIdToHex(chainIdDecimal)
217219

218220
providerStateChanged()
219-
chainChangedEvent(chainIdHex)
220-
console.log("[ConnectorManager] Chain switched to:", chainIdHex)
221-
}
222-
} catch (error) {
223-
console.error("[ConnectorManager] Error processing chainIdSwitched signal:", error)
224-
}
225-
}
226-
}
221+
chainChangedEvent(chainIdHex)
222+
console.log("[ConnectorManager] Chain switched to:", chainIdHex)
223+
}
224+
} catch (error) {
225+
console.error("[ConnectorManager] Error processing chainIdSwitched signal:", error)
226+
}
227+
}
228+
229+
function onAccountChanged(payload) {
230+
try {
231+
const data = JSON.parse(payload)
232+
if (!shouldProcessSignal(data)) return
233+
const newAccounts = data.sharedAccount ? [data.sharedAccount] : []
234+
updateAccounts(newAccounts)
235+
} catch (error) {
236+
console.error("[ConnectorManager] Error processing accountChanged signal:", error)
237+
}
238+
}
239+
}
227240
}

ui/app/AppLayouts/Browser/provider/qml/Utils.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,17 @@ function accountsDidChange(oldAccounts, newAccounts) {
1212

1313
function normalizeOrigin(url) {
1414
if (!url) return ""
15-
let normalized = url.toString()
16-
// Remove trailing slash from origin
17-
if (normalized.endsWith("/")) {
18-
normalized = normalized.slice(0, -1)
15+
try {
16+
const urlObj = new URL(url.toString())
17+
// This ensures https://opensea.io/ and https://opensea.io/path both become https://opensea.io
18+
return urlObj.origin
19+
} catch (e) {
20+
let normalized = url.toString()
21+
if (normalized.endsWith("/")) {
22+
normalized = normalized.slice(0, -1)
23+
}
24+
return normalized
1925
}
20-
return normalized
2126
}
2227

2328
// Convert decimal chainId to hex string (e.g., 1 -> "0x1", 137 -> "0x89")

0 commit comments

Comments
 (0)