-
Notifications
You must be signed in to change notification settings - Fork 51
Wallet Gateway
The remote wallet gateway has a backend (nodejs+express) and a user management frontend (web components). The frontend, aka User UI, is opened as a separate browser popup window when used with a 3rd-party dApp.
The User UI and dApp UI, once connected, send window message events to each other to share session state, provide user interaction updates, and so on.
The origin handshake is used for the initial interaction between the dApp UI and the WG UI. This establishes each others' origins to each other and enables more secure .postMessage communication, since events are now explicitly addressed by origin, rather than open to any listening origin (*).
The stateManager referenced in the diagram is a client-side component that wraps around localStorage/sessionStorage utilities for persistence.
sequenceDiagram
autonumber
participant D as Dapp UI<br/>(Browser)
participant WG as WG UI<br/>(Browser)
participant SM as WG UI<br/>(stateManager)
Note over D,WG: (note: Dapp UI and WG UI run on separate origins)
D->>WG: Opens WG UI popup
par
loop broadcast dapp origin
D-->>WG: postMessage sends: `SPLICE_WALLET_BROADCAST_ORIGIN`
end
and
WG->>WG: addEventListener('message')
end
WG->>SM: store `event.data.origin` as `currentOrigin` in sessionStorage
Note over WG: send back an acknowledgement
WG-->>D: postMessage sends: `SPLICE_WALLET_BROADCAST_ORIGIN_ACK`
D->>D: clearInterval on broadcast loop
This diagram demonstrates the login flow through the Wallet Gateway UI. The WG UI is accessed in one of two ways: directly in a browser window, or as a popup triggered by a dApp. In the case of the latter, a successful authentication results in a message emitted to the parent dApp. For illustrative purposes, this diagram only shows the case of a login using an OAuth 2.0 IdP.
sequenceDiagram
autonumber
actor U as User
participant D as Dapp UI<br/>(Browser)
participant WG as WG UI<br/>(Browser)
participant SM as WG UI<br/>(stateManager)
participant WGB as WG Backend
participant A as OAuth IdP
Note over D,SM: Establish origin handshake (see above)
WG->>SM: Check auth status (get accessToken)
alt new session (accessToken is undefined)
WG->>SM: persist intended page for post-auth
WG->>WG: redirect to /login
WG->>WGB: call listNetworks
U->>WG: selects a network
U->>WG: clicks "connect" on login page
WG->>A: redirect to authorization endpoint
A->>WG: redirect to /callback
WG->>A: call token endpoint
WG->>SM: store token and expiry
WG->>WGB: call addSession
WGB-->>D: SSE send: 'statusChanged'
WGB-->>D: SSE send: 'connected'
WG->>SM: store sessionId by origin
WG-->>D: postMessage send: SPLICE_WALLET_IDP_AUTH_SUCCESS
WG->>SM: get original intended page and redirect to it
else existing session
WG->>WGB: call listSessions
opt no server session
WG->>SM: call clearAuthState, redirect to /login
end
WG->>SM: reset token expiry date
WG-->>D: postMessage send: SPLICE_WALLET_IDP_AUTH_SUCCESS
else token expired
WG->>SM: clearAuthState for origin
Note over WG: (SPLICE_WALLET_LOGOUT event is _NOT_ emitted here: we should consider doing so)
end
WG-->>D: postMessage sends: `SPLICE_WALLET_IDP_AUTH_SUCCESS`
From the dApp side, this flow shows what happens when a user clicks "connect" (aka calling .connect() on the dApp SDK)
sequenceDiagram
autonumber
actor U as User
participant D as Dapp UI<br/>(Browser)
participant P as Wallet Picker
participant WG as WG UI<br/>(Browser)
participant WGB as WG Backend
U->>D: Clicks "connect"
D->>P: Opens wallet discovery/picker
U->>P: Select wallet
P-->>D: postMessage send: SPLICE_WALLET_PICKER_RESULT
D->>WGB: calls `connect` (dapp API)
alt unauthenticated
WGB->>D: sends `/login` userUrl
else existing session
WGB-->>D: SSE send: 'statusChanged'
WGB-->>D: SSE send: 'connected'
end
D->>WG: open WG in popup
Note over D,WG: Executes login flow (see above)
If a user clicks "disconnect" (aka dapp-sdk .disconnect()), then...
sequenceDiagram
autonumber
actor U as User
participant D as Dapp UI<br/>(Browser)
participant P as Wallet Picker
participant WG as WG UI<br/>(Browser)
participant WGB as WG Backend
U->>D: Click disconnect
D->>WGB: dapp API: call 'disconnect'
WGB->>WGB: remove session
WGB-->>D: SSE send: 'statusChanged'
If a user clicks "Logout" from inside the WG popup, then...
sequenceDiagram
autonumber
actor U as User
participant D as Dapp UI<br/>(Browser)
participant WG as WG UI<br/>(Browser)
participant SM as WG UI<br/>(stateManager)
participant WGB as WG Backend
U->>WG: Click Logout button in popup
WG->>WGB: call 'removeSession'
par
WGB-->>D: SSE send: 'statusChanged'
WGB-->>D: SSE send: 'logout'
WG->>SM: clearAuthState
WG-->>D: postMessage send: SPLICE_WALLET_LOGOUT
end