Skip to content
Closed
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
72 changes: 71 additions & 1 deletion api-specs/openrpc-user-api.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,24 @@
"description": "An OpenRPC specification for the user to interact with the wallet kernel."
},
"methods": [
{
"name": "info",
"params": [],
"result": {
"name": "result",
"schema": {
"title": "InfoResult",
"type": "object",
"properties": {
"kernel": {
"$ref": "#/components/schemas/KernelInfo"
}
},
"required": ["kernel"]
}
},
"description": "Returns the current chainId if connected."
},
{
"name": "addNetwork",
"params": [
Expand Down Expand Up @@ -324,6 +342,24 @@
}
}
},
{
"name": "getSession",
"params": [],
"result": {
"name": "result",
"schema": {
"title": "GetSessionResult",
"type": "object",
"properties": {
"session": {
"title": "session",
"$ref": "#/components/schemas/Session"
}
},
"required": ["session"]
}
}
},
{
"name": "addSession",
"description": "Adds a network session.",
Expand Down Expand Up @@ -382,6 +418,35 @@
"type": "null",
"description": "Represents a null value, used in responses where no data is returned."
},
"KernelInfo": {
"title": "KernelInfo",
"type": "object",
"description": "Represents a wallet kernel.",
"properties": {
"id": {
"title": "id",
"type": "string",
"description": "The unique identifier of the wallet kernel."
},
"clientType": {
"title": "clientType",
"type": "string",
"enum": ["browser", "desktop", "mobile", "remote"],
"description": "The type of client that implements the wallet kernel."
},
"rpcUrl": {
"title": "rpcUrl",
"type": "string",
"description": "The RPC URL of the wallet kernel."
},
"uiUrl": {
"title": "uiUrl",
"type": "string",
"description": "The UI URL of the wallet kernel."
}
},
"required": ["id", "clientType"]
},
"Network": {
"title": "Network",
"type": "object",
Expand Down Expand Up @@ -551,6 +616,11 @@
"network": {
"$ref": "#/components/schemas/Network"
},
"userId": {
"title": "userId",
"type": "string",
"description": "The user ID associated with the session."
},
"accessToken": {
"title": "accessToken",
"type": "string",
Expand All @@ -562,7 +632,7 @@
"enum": ["connected", "disconnected"]
}
},
"required": ["network", "status", "accessToken"],
"required": ["network", "status", "userId", "accessToken"],
"additionalProperties": false
}
}
Expand Down
3 changes: 2 additions & 1 deletion clients/remote/src/config/Config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ export const kernelInfoSchema = z.object({
z.literal('mobile'),
z.literal('remote'),
]),
url: z.string().url(),
rpcUrl: z.string().url(),
uiUrl: z.string().url(),
})

export const configSchema = z.object({
Expand Down
59 changes: 2 additions & 57 deletions clients/remote/src/dapp-api/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,7 @@ import { jwtAuth } from '../middleware/jwtAuth.js'
import { AuthService, AuthAware } from 'core-wallet-auth'
import { rpcRateLimit } from '../middleware/rateLimit.js'
import cors from 'cors'
import { createServer } from 'http'
import { Server } from 'socket.io'
import {
NotificationService,
Notifier,
} from '../notification/NotificationService.js'
import { NotificationService } from '../notification/NotificationService.js'
import { KernelInfo } from '../config/Config.js'

const logger = pino({ name: 'main', level: 'debug' })
Expand Down Expand Up @@ -43,55 +38,5 @@ export const dapp = (
})(req, res, next)
)

const server = createServer(app)
const io = new Server(server, {
cors: {
origin: '*',
methods: ['GET', 'POST'],
},
})

io.on('connection', (socket) => {
logger.info('Socket.io client connected')

let notifier: Notifier | undefined = undefined

const onAccountsChanged = (...event: unknown[]) => {
io.emit('accountsChanged', ...event)
}
const onConnected = (...event: unknown[]) => {
io.emit('onConnected', ...event)
}
const onTxChanged = (...event: unknown[]) => {
io.emit('txChanged', ...event)
}

authService
.verifyToken(socket.handshake.auth.token)
.then((authContext) => {
const userId = authContext?.userId

if (!userId) {
return
}

notifier = notificationService.getNotifier(userId)

notifier.on('accountsChanged', onAccountsChanged)
notifier.on('onConnected', onConnected)
notifier.on('txChanged', onTxChanged)
})

socket.on('disconnect', () => {
logger.info('Socket.io client disconnected')

if (notifier) {
notifier.removeListener('accountsChanged', onAccountsChanged)
notifier.removeListener('onConnected', onConnected)
notifier.removeListener('txChanged', onTxChanged)
}
})
})

return server
return app
}
30 changes: 30 additions & 0 deletions clients/remote/src/user-api/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import {
AddSessionResult,
ListSessionsResult,
SetPrimaryWalletParams,
InfoResult,
GetSessionResult,
} from './rpc-gen/typings.js'
import { Store, Wallet, Auth } from 'core-wallet-store'
import { Logger } from 'pino'
Expand Down Expand Up @@ -124,6 +126,9 @@ export const userController = (
) => {
const logger = _logger.child({ component: 'user-controller' })
return buildController({
info: function (): Promise<InfoResult> {
return Promise.resolve({ kernel: kernelInfo })
},
addNetwork: async (network: AddNetworkParams) => {
const ledgerApi = {
baseUrl: network.ledgerApiUrl ?? '',
Expand Down Expand Up @@ -312,6 +317,7 @@ export const userController = (
})

return Promise.resolve({
userId,
accessToken,
status: 'connected',
network: {
Expand All @@ -337,6 +343,7 @@ export const userController = (
return {
sessions: [
{
userId: authContext!.userId,
accessToken: authContext!.accessToken,
status: 'connected',
network: {
Expand All @@ -351,5 +358,28 @@ export const userController = (
],
}
},
getSession: async function (): Promise<GetSessionResult> {
const session = await store.getSession()
if (!session) {
throw new Error('No active session found')
}
const network = await store.getNetwork(session.network)

return {
session: {
userId: authContext!.userId,
accessToken: authContext!.accessToken,
status: 'connected',
network: {
name: network.name,
chainId: network.chainId,
synchronizerId: network.synchronizerId,
description: network.description,
ledgerApi: network.ledgerApi,
auth: network.auth,
},
},
}
},
})
}
6 changes: 6 additions & 0 deletions clients/remote/src/user-api/rpc-gen/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Code generated by rpc-generator DO NOT EDIT!!

import { Info } from './typings.js'
import { AddNetwork } from './typings.js'
import { RemoveNetwork } from './typings.js'
import { CreateWallet } from './typings.js'
Expand All @@ -9,10 +10,12 @@ import { ListWallets } from './typings.js'
import { Sign } from './typings.js'
import { Execute } from './typings.js'
import { ListNetworks } from './typings.js'
import { GetSession } from './typings.js'
import { AddSession } from './typings.js'
import { ListSessions } from './typings.js'

export type Methods = {
info: Info
addNetwork: AddNetwork
removeNetwork: RemoveNetwork
createWallet: CreateWallet
Expand All @@ -22,12 +25,14 @@ export type Methods = {
sign: Sign
execute: Execute
listNetworks: ListNetworks
getSession: GetSession
addSession: AddSession
listSessions: ListSessions
}

function buildController(methods: Methods) {
return {
info: methods.info,
addNetwork: methods.addNetwork,
removeNetwork: methods.removeNetwork,
createWallet: methods.createWallet,
Expand All @@ -37,6 +42,7 @@ function buildController(methods: Methods) {
sign: methods.sign,
execute: methods.execute,
listNetworks: methods.listNetworks,
getSession: methods.getSession,
addSession: methods.addSession,
listSessions: methods.listSessions,
}
Expand Down
Loading
Loading