diff --git a/api-specs/openrpc-dapp-api.json b/api-specs/openrpc-dapp-api.json index 3ee12b681..e5ffc4199 100644 --- a/api-specs/openrpc-dapp-api.json +++ b/api-specs/openrpc-dapp-api.json @@ -23,19 +23,7 @@ "result": { "name": "result", "schema": { - "title": "ConnectResult", - "type": "object", - "properties": { - "status": { - "$ref": "#/components/schemas/StatusEvent" - }, - "sessionToken": { - "title": "sessionToken", - "type": "string", - "description": "JWT authentication token (if applicable)." - } - }, - "required": ["status", "sessionToken"] + "$ref": "#/components/schemas/StatusEvent" } }, "description": "Ensures ledger connectivity and returns the connected network information along with the user access token. Network ID should follow CAIP-2 and represent the synchronizerId." @@ -529,10 +517,53 @@ "type": "string", "description": "If not connected to a network, the reason why." }, - "networkId": { - "title": "networkId", - "type": "string", - "description": "A CAIP-2 compliant chain ID, e.g. 'canton:da-mainnet'." + "userUrl": { + "$ref": "#/components/schemas/UserUrl" + }, + "network": { + "title": "network", + "type": "object", + "description": "Network information, if connected to a network.", + "properties": { + "networkId": { + "title": "networkId", + "type": "string", + "description": "A CAIP-2 compliant chain ID, e.g. 'canton:da-mainnet'." + }, + "ledgerApi": { + "title": "LedgerApiConfig", + "type": "object", + "description": "Ledger API configuration.", + "properties": { + "baseUrl": { + "title": "baseUrl", + "type": "string", + "format": "uri", + "description": "The base URL of the ledger API." + } + }, + "required": ["baseUrl"] + } + }, + "required": ["networkId"] + }, + "session": { + "title": "session", + "type": "object", + "description": "Session information, if authenticated.", + "properties": { + "accessToken": { + "title": "accessToken", + "type": "string", + "description": "JWT authentication token." + }, + "userId": { + "title": "userId", + "type": "string", + "description": "The user identifier." + } + }, + "required": ["accessToken", "userId"] } }, "required": ["kernel", "isConnected", "isNetworkConnected"] diff --git a/api-specs/openrpc-dapp-remote-api.json b/api-specs/openrpc-dapp-remote-api.json index aecf7a2e8..b7bc620d1 100644 --- a/api-specs/openrpc-dapp-remote-api.json +++ b/api-specs/openrpc-dapp-remote-api.json @@ -23,19 +23,7 @@ "result": { "name": "result", "schema": { - "title": "ConnectResult", - "type": "object", - "properties": { - "status": { - "$ref": "#/components/schemas/StatusEvent" - }, - "sessionToken": { - "title": "sessionToken", - "type": "string", - "description": "JWT authentication token (if applicable)." - } - }, - "required": ["status", "sessionToken"] + "$ref": "#/components/schemas/StatusEvent" } }, "description": "Ensures ledger connectivity and returns the connected network information along with the user access token. NetworkId should follow CAIP-2 and represent the synchronizerId." @@ -166,19 +154,7 @@ "result": { "name": "result", "schema": { - "title": "OnConnectedEvent", - "type": "object", - "properties": { - "status": { - "$ref": "#/components/schemas/StatusEvent" - }, - "sessionToken": { - "title": "sessionToken", - "type": "string", - "description": "JWT authentication token (if applicable)." - } - }, - "required": ["kernel", "status"] + "$ref": "#/components/schemas/StatusEvent" } }, "description": "Informs when the user connects to a network." @@ -558,10 +534,53 @@ "type": "string", "description": "If not connected to a network, the reason why." }, - "networkId": { - "title": "networkId", - "type": "string", - "description": "A CAIP-2 compliant chain ID, e.g. 'canton:da-mainnet'." + "userUrl": { + "$ref": "#/components/schemas/UserUrl" + }, + "network": { + "title": "network", + "type": "object", + "description": "Network information, if connected to a network.", + "properties": { + "networkId": { + "title": "networkId", + "type": "string", + "description": "A CAIP-2 compliant chain ID, e.g. 'canton:da-mainnet'." + }, + "ledgerApi": { + "title": "LedgerApiConfig", + "type": "object", + "description": "Ledger API configuration.", + "properties": { + "baseUrl": { + "title": "baseUrl", + "type": "string", + "format": "uri", + "description": "The base URL of the ledger API." + } + }, + "required": ["baseUrl"] + } + }, + "required": ["networkId"] + }, + "session": { + "title": "session", + "type": "object", + "description": "Session information, if authenticated.", + "properties": { + "accessToken": { + "title": "accessToken", + "type": "string", + "description": "JWT authentication token." + }, + "userId": { + "title": "userId", + "type": "string", + "description": "The user identifier." + } + }, + "required": ["accessToken", "userId"] } }, "required": ["kernel", "isConnected", "isNetworkConnected"] diff --git a/core/rpc-generator/src/components/client.ts b/core/rpc-generator/src/components/client.ts index e1c174ca1..49fba98d8 100644 --- a/core/rpc-generator/src/components/client.ts +++ b/core/rpc-generator/src/components/client.ts @@ -64,6 +64,33 @@ export const stripAnyOfTypes = (content: string): string => { const versionMap = new Map() +// Derives the repository directory path from the destination path relative to repo root +const getRepositoryDirectory = (destPath: string): string | null => { + let currentPath = destPath + const maxDepth = 10 + for (let i = 0; i < maxDepth; i++) { + const packageJsonPath = path.join(currentPath, 'package.json') + try { + if (fs.existsSync(packageJsonPath)) { + const pkgContent = fs.readFileSync(packageJsonPath, 'utf-8') + const pkg = JSON.parse(pkgContent) + if (pkg.workspaces || pkg.name === 'splice-wallet-kernel') { + const relativePath = path.relative(currentPath, destPath) + return relativePath.replace(/\\/g, '/') // Normalize to forward slashes + } + } + } catch { + // Continue searching + } + const parentPath = path.dirname(currentPath) + if (parentPath === currentPath) { + break + } + currentPath = parentPath + } + return null +} + const hooks: IHooks = { afterCopyStatic: [ async (dest, frm, component): Promise => { @@ -96,13 +123,24 @@ const hooks: IHooks = { const packagePath = path.join(dest, 'package.json') const fileContents = await readFile(packagePath) const pkg = JSON.parse(fileContents.toString()) - const updatedPkg = JSON.stringify({ + const updatedPkgObj: Record = { ...pkg, name: component.name, version: versionMap.get(component.name) ?? openrpcDocument.info.version, - }) + } + + const repositoryDirectory = getRepositoryDirectory(dest) + if (repositoryDirectory) { + updatedPkgObj.repository = { + type: 'git', + url: 'git+https://github.com/hyperledger-labs/splice-wallet-kernel.git', + directory: repositoryDirectory, + } + } + // else - fallback to repository field in template + const updatedPkg = JSON.stringify(updatedPkgObj) execSync(`yarn prettier --write ${dest}/src/**/*`) return await writeFile(packagePath, updatedPkg) } diff --git a/core/rpc-generator/templates/client/typescript/_package.json b/core/rpc-generator/templates/client/typescript/_package.json index bb73e0291..7e379e9e4 100644 --- a/core/rpc-generator/templates/client/typescript/_package.json +++ b/core/rpc-generator/templates/client/typescript/_package.json @@ -3,7 +3,6 @@ "version": "0.0.0", "type": "module", "description": "TypeScript client generated by OpenRPC", - "repository": "github:hyperledger-labs/splice-wallet-kernel", "license": "Apache-2.0", "main": "dist/index.cjs", "module": "dist/index.js", @@ -42,5 +41,6 @@ "tsup": "^8.5.1", "typedoc": "^0.28.14", "typescript": "^5.9.3" - } + }, + "repository": "github:hyperledger-labs/splice-wallet-kernel" } diff --git a/core/splice-provider/src/SpliceProviderHttp.ts b/core/splice-provider/src/SpliceProviderHttp.ts index 4364b1d45..7cd2fa855 100644 --- a/core/splice-provider/src/SpliceProviderHttp.ts +++ b/core/splice-provider/src/SpliceProviderHttp.ts @@ -76,10 +76,7 @@ export class SpliceProviderHttp extends SpliceProviderBase { // dappApi.OnConnectedEvent are mapped manually to avoid dependency. this.request({ method: 'status' }) .then((status) => { - this.emit('onConnected', { - status: status, - sessionToken: this.sessionToken, - }) + this.emit('onConnected', status) }) .catch((err) => { console.error( diff --git a/core/wallet-dapp-remote-rpc-client/src/index.ts b/core/wallet-dapp-remote-rpc-client/src/index.ts index a7d878d91..08db76f2f 100644 --- a/core/wallet-dapp-remote-rpc-client/src/index.ts +++ b/core/wallet-dapp-remote-rpc-client/src/index.ts @@ -134,26 +134,65 @@ export type IsNetworkConnected = boolean * */ export type NetworkReason = string +/** + * + * A URL that points to a user interface. + * + */ +export type UserUrl = string /** * * The network ID the wallet corresponds to. * */ export type NetworkId = string -export interface StatusEvent { - kernel: KernelInfo - isConnected: IsConnected - isNetworkConnected: IsNetworkConnected - networkReason?: NetworkReason - networkId?: NetworkId +/** + * + * The base URL of the ledger API. + * + */ +export type BaseUrl = string +/** + * + * Ledger API configuration. + * + */ +export interface LedgerApiConfig { + baseUrl: BaseUrl [k: string]: any } /** * - * JWT authentication token (if applicable). + * Network information, if connected to a network. * */ -export type SessionToken = string +export interface Network { + networkId: NetworkId + ledgerApi?: LedgerApiConfig + [k: string]: any +} +/** + * + * JWT authentication token. + * + */ +export type AccessToken = string +/** + * + * The user identifier. + * + */ +export type UserId = string +/** + * + * Session information, if authenticated. + * + */ +export interface Session { + accessToken: AccessToken + userId: UserId + [k: string]: any +} export type Dar = string export type Dars = Dar[] /** @@ -178,12 +217,6 @@ export interface JsPrepareSubmissionResponse { preparedTransactionHash?: PreparedTransactionHash [k: string]: any } -/** - * - * A URL that points to a user interface. - * - */ -export type UserUrl = string export type Response = string /** * @@ -393,9 +426,14 @@ export interface LedgerApiParams { body?: Body [k: string]: any } -export interface ConnectResult { - status: StatusEvent - sessionToken: SessionToken +export interface StatusEvent { + kernel: KernelInfo + isConnected: IsConnected + isNetworkConnected: IsNetworkConnected + networkReason?: NetworkReason + userUrl?: UserUrl + network?: Network + session?: Session [k: string]: any } /** @@ -422,11 +460,6 @@ export interface LedgerApiResult { response: Response [k: string]: any } -export interface OnConnectedEvent { - status: StatusEvent - sessionToken?: SessionToken - [k: string]: any -} /** * * Event emitted when the user's accounts change. @@ -456,7 +489,7 @@ export type TxChangedEvent = */ export type Status = () => Promise -export type Connect = () => Promise +export type Connect = () => Promise export type Disconnect = () => Promise export type DarsAvailable = () => Promise export type PrepareReturn = ( @@ -466,7 +499,7 @@ export type PrepareExecute = ( params: PrepareExecuteParams ) => Promise export type LedgerApi = (params: LedgerApiParams) => Promise -export type OnConnected = () => Promise +export type OnConnected = () => Promise export type OnStatusChanged = () => Promise export type OnAccountsChanged = () => Promise export type RequestAccounts = () => Promise diff --git a/core/wallet-dapp-remote-rpc-client/src/openrpc.json b/core/wallet-dapp-remote-rpc-client/src/openrpc.json index aecf7a2e8..b7bc620d1 100644 --- a/core/wallet-dapp-remote-rpc-client/src/openrpc.json +++ b/core/wallet-dapp-remote-rpc-client/src/openrpc.json @@ -23,19 +23,7 @@ "result": { "name": "result", "schema": { - "title": "ConnectResult", - "type": "object", - "properties": { - "status": { - "$ref": "#/components/schemas/StatusEvent" - }, - "sessionToken": { - "title": "sessionToken", - "type": "string", - "description": "JWT authentication token (if applicable)." - } - }, - "required": ["status", "sessionToken"] + "$ref": "#/components/schemas/StatusEvent" } }, "description": "Ensures ledger connectivity and returns the connected network information along with the user access token. NetworkId should follow CAIP-2 and represent the synchronizerId." @@ -166,19 +154,7 @@ "result": { "name": "result", "schema": { - "title": "OnConnectedEvent", - "type": "object", - "properties": { - "status": { - "$ref": "#/components/schemas/StatusEvent" - }, - "sessionToken": { - "title": "sessionToken", - "type": "string", - "description": "JWT authentication token (if applicable)." - } - }, - "required": ["kernel", "status"] + "$ref": "#/components/schemas/StatusEvent" } }, "description": "Informs when the user connects to a network." @@ -558,10 +534,53 @@ "type": "string", "description": "If not connected to a network, the reason why." }, - "networkId": { - "title": "networkId", - "type": "string", - "description": "A CAIP-2 compliant chain ID, e.g. 'canton:da-mainnet'." + "userUrl": { + "$ref": "#/components/schemas/UserUrl" + }, + "network": { + "title": "network", + "type": "object", + "description": "Network information, if connected to a network.", + "properties": { + "networkId": { + "title": "networkId", + "type": "string", + "description": "A CAIP-2 compliant chain ID, e.g. 'canton:da-mainnet'." + }, + "ledgerApi": { + "title": "LedgerApiConfig", + "type": "object", + "description": "Ledger API configuration.", + "properties": { + "baseUrl": { + "title": "baseUrl", + "type": "string", + "format": "uri", + "description": "The base URL of the ledger API." + } + }, + "required": ["baseUrl"] + } + }, + "required": ["networkId"] + }, + "session": { + "title": "session", + "type": "object", + "description": "Session information, if authenticated.", + "properties": { + "accessToken": { + "title": "accessToken", + "type": "string", + "description": "JWT authentication token." + }, + "userId": { + "title": "userId", + "type": "string", + "description": "The user identifier." + } + }, + "required": ["accessToken", "userId"] } }, "required": ["kernel", "isConnected", "isNetworkConnected"] diff --git a/core/wallet-dapp-rpc-client/src/index.ts b/core/wallet-dapp-rpc-client/src/index.ts index 1de3feb32..5542a3485 100644 --- a/core/wallet-dapp-rpc-client/src/index.ts +++ b/core/wallet-dapp-rpc-client/src/index.ts @@ -147,20 +147,53 @@ export type NetworkReason = string * */ export type NetworkId = string -export interface StatusEvent { - kernel: KernelInfo - isConnected: IsConnected - isNetworkConnected: IsNetworkConnected - networkReason?: NetworkReason - networkId?: NetworkId +/** + * + * The base URL of the ledger API. + * + */ +export type BaseUrl = string +/** + * + * Ledger API configuration. + * + */ +export interface LedgerApiConfig { + baseUrl: BaseUrl + [k: string]: any +} +/** + * + * Network information, if connected to a network. + * + */ +export interface Network { + networkId: NetworkId + ledgerApi?: LedgerApiConfig [k: string]: any } /** * - * JWT authentication token (if applicable). + * JWT authentication token. + * + */ +export type AccessToken = string +/** + * + * The user identifier. + * + */ +export type UserId = string +/** + * + * Session information, if authenticated. * */ -export type SessionToken = string +export interface Session { + accessToken: AccessToken + userId: UserId + [k: string]: any +} export type Dar = string export type Dars = Dar[] /** @@ -394,9 +427,14 @@ export interface LedgerApiParams { body?: Body [k: string]: any } -export interface ConnectResult { - status: StatusEvent - sessionToken: SessionToken +export interface StatusEvent { + kernel: KernelInfo + isConnected: IsConnected + isNetworkConnected: IsNetworkConnected + networkReason?: NetworkReason + userUrl?: UserUrl + network?: Network + session?: Session [k: string]: any } /** @@ -452,7 +490,7 @@ export type TxChangedEvent = */ export type Status = () => Promise -export type Connect = () => Promise +export type Connect = () => Promise export type Disconnect = () => Promise export type DarsAvailable = () => Promise export type PrepareReturn = ( diff --git a/core/wallet-dapp-rpc-client/src/openrpc.json b/core/wallet-dapp-rpc-client/src/openrpc.json index 3ee12b681..e5ffc4199 100644 --- a/core/wallet-dapp-rpc-client/src/openrpc.json +++ b/core/wallet-dapp-rpc-client/src/openrpc.json @@ -23,19 +23,7 @@ "result": { "name": "result", "schema": { - "title": "ConnectResult", - "type": "object", - "properties": { - "status": { - "$ref": "#/components/schemas/StatusEvent" - }, - "sessionToken": { - "title": "sessionToken", - "type": "string", - "description": "JWT authentication token (if applicable)." - } - }, - "required": ["status", "sessionToken"] + "$ref": "#/components/schemas/StatusEvent" } }, "description": "Ensures ledger connectivity and returns the connected network information along with the user access token. Network ID should follow CAIP-2 and represent the synchronizerId." @@ -529,10 +517,53 @@ "type": "string", "description": "If not connected to a network, the reason why." }, - "networkId": { - "title": "networkId", - "type": "string", - "description": "A CAIP-2 compliant chain ID, e.g. 'canton:da-mainnet'." + "userUrl": { + "$ref": "#/components/schemas/UserUrl" + }, + "network": { + "title": "network", + "type": "object", + "description": "Network information, if connected to a network.", + "properties": { + "networkId": { + "title": "networkId", + "type": "string", + "description": "A CAIP-2 compliant chain ID, e.g. 'canton:da-mainnet'." + }, + "ledgerApi": { + "title": "LedgerApiConfig", + "type": "object", + "description": "Ledger API configuration.", + "properties": { + "baseUrl": { + "title": "baseUrl", + "type": "string", + "format": "uri", + "description": "The base URL of the ledger API." + } + }, + "required": ["baseUrl"] + } + }, + "required": ["networkId"] + }, + "session": { + "title": "session", + "type": "object", + "description": "Session information, if authenticated.", + "properties": { + "accessToken": { + "title": "accessToken", + "type": "string", + "description": "JWT authentication token." + }, + "userId": { + "title": "userId", + "type": "string", + "description": "The user identifier." + } + }, + "required": ["accessToken", "userId"] } }, "required": ["kernel", "isConnected", "isNetworkConnected"] diff --git a/examples/ping/src/App.tsx b/examples/ping/src/App.tsx index b47e24aa2..560e722d5 100644 --- a/examples/ping/src/App.tsx +++ b/examples/ping/src/App.tsx @@ -155,7 +155,7 @@ function App() { console.log('Connecting to Wallet Gateway...') setLoading(true) sdk.connect() - .then(({ status }) => { + .then((status) => { setLoading(false) setStatus(status) setErrorMsg('') @@ -224,10 +224,26 @@ function App() {
connected:{' '} {status.isConnected ? '🟢' : '🔴'} - {status.networkId && ( + {status.network && (
- network: {status.networkId} + network ID:{' '} + {status.network.networkId} + {status.network.ledgerApi && ( + <> +
+ ledger API:{' '} + + {status.network.ledgerApi.baseUrl} + + + )} +
+ )} + {status.session && ( + +
+ user ID: {status.session.userId}
)} {ledgerApiVersion && ( diff --git a/sdk/dapp-sdk/src/dapp-api/rpc-gen/typings.ts b/sdk/dapp-sdk/src/dapp-api/rpc-gen/typings.ts index f3c0985ba..546e1e4d8 100644 --- a/sdk/dapp-sdk/src/dapp-api/rpc-gen/typings.ts +++ b/sdk/dapp-sdk/src/dapp-api/rpc-gen/typings.ts @@ -147,20 +147,53 @@ export type NetworkReason = string * */ export type NetworkId = string -export interface StatusEvent { - kernel: KernelInfo - isConnected: IsConnected - isNetworkConnected: IsNetworkConnected - networkReason?: NetworkReason - networkId?: NetworkId +/** + * + * The base URL of the ledger API. + * + */ +export type BaseUrl = string +/** + * + * Ledger API configuration. + * + */ +export interface LedgerApiConfig { + baseUrl: BaseUrl + [k: string]: any +} +/** + * + * Network information, if connected to a network. + * + */ +export interface Network { + networkId: NetworkId + ledgerApi?: LedgerApiConfig [k: string]: any } /** * - * JWT authentication token (if applicable). + * JWT authentication token. + * + */ +export type AccessToken = string +/** + * + * The user identifier. + * + */ +export type UserId = string +/** + * + * Session information, if authenticated. * */ -export type SessionToken = string +export interface Session { + accessToken: AccessToken + userId: UserId + [k: string]: any +} export type Dar = string export type Dars = Dar[] /** @@ -394,9 +427,14 @@ export interface LedgerApiParams { body?: Body [k: string]: any } -export interface ConnectResult { - status: StatusEvent - sessionToken: SessionToken +export interface StatusEvent { + kernel: KernelInfo + isConnected: IsConnected + isNetworkConnected: IsNetworkConnected + networkReason?: NetworkReason + userUrl?: UserUrl + network?: Network + session?: Session [k: string]: any } /** @@ -452,7 +490,7 @@ export type TxChangedEvent = */ export type Status = () => Promise -export type Connect = () => Promise +export type Connect = () => Promise export type Disconnect = () => Promise export type DarsAvailable = () => Promise export type PrepareReturn = ( diff --git a/sdk/dapp-sdk/src/provider.ts b/sdk/dapp-sdk/src/provider.ts index 37c0762b3..0471ac8a4 100644 --- a/sdk/dapp-sdk/src/provider.ts +++ b/sdk/dapp-sdk/src/provider.ts @@ -157,27 +157,22 @@ const withTimeout = ( export const dappController = (provider: SpliceProvider) => buildController({ connect: async () => { - const response = - await provider.request({ - method: 'connect', - }) + const response = await provider.request({ + method: 'connect', + }) - if (!response.status.isConnected) - openKernelUserUI('remote', response.status.userUrl) + if (!response.isConnected) + openKernelUserUI('remote', response.userUrl ?? '') - const promise = new Promise( + const promise = new Promise( (resolve, reject) => { // 5 minutes timeout const timeout = withTimeout(reject, 5 * 60 * 1000) - provider.on( + provider.on( 'onConnected', (event) => { clearTimeout(timeout) - const result: dappAPI.ConnectResult = { - sessionToken: event.sessionToken ?? '', - status: event.status, - } - resolve(result) + resolve(event) } ) } @@ -207,8 +202,7 @@ export const dappController = (provider: SpliceProvider) => params, }) - if (!response.isConnected) - openKernelUserUI('remote', response.userUrl) + if (response.userUrl) openKernelUserUI('remote', response.userUrl) const promise = new Promise( (resolve, reject) => { diff --git a/sdk/dapp-sdk/src/provider/index.ts b/sdk/dapp-sdk/src/provider/index.ts index 343bcbabe..ad350a027 100644 --- a/sdk/dapp-sdk/src/provider/index.ts +++ b/sdk/dapp-sdk/src/provider/index.ts @@ -8,7 +8,10 @@ import * as storage from '../storage' export const injectProvider = (discovery: DiscoverResult) => { return injectSpliceProvider( - new Provider(discovery, storage.getKernelSession()?.sessionToken) + new Provider( + discovery, + storage.getKernelSession()?.session?.accessToken + ) ) } diff --git a/sdk/dapp-sdk/src/provider/request.ts b/sdk/dapp-sdk/src/provider/request.ts index 039a09931..de991233b 100644 --- a/sdk/dapp-sdk/src/provider/request.ts +++ b/sdk/dapp-sdk/src/provider/request.ts @@ -11,7 +11,7 @@ import gateways from '../gateways.json' import { removeKernelDiscovery, removeKernelSession } from '../storage' import { closeKernelUserUI } from '../provider.js' -export async function connect(): Promise { +export async function connect(): Promise { const config: GatewaysConfig[] = gateways return discover(config) .then(async (result) => { @@ -20,11 +20,11 @@ export async function connect(): Promise { storage.removeKernelSession() const provider = injectProvider(result) - const response = await provider.request({ + const response = await provider.request({ method: 'connect', }) - if (!response.status.isConnected) { + if (!response.isConnected) { // TODO: error dialog console.error('SDK: Not connected', response) // openKernelUserUI(result.walletType, response.userUrl) diff --git a/sdk/dapp-sdk/src/storage.ts b/sdk/dapp-sdk/src/storage.ts index 08563ba59..357367d2d 100644 --- a/sdk/dapp-sdk/src/storage.ts +++ b/sdk/dapp-sdk/src/storage.ts @@ -32,11 +32,11 @@ export const removeKernelDiscovery = (): void => { localStorage.removeItem(LOCAL_STORAGE.KERNEL_DISCOVERY) } -export const getKernelSession = (): dappAPI.ConnectResult | undefined => { +export const getKernelSession = (): dappAPI.StatusEvent | undefined => { const session = localStorage.getItem(LOCAL_STORAGE.KERNEL_SESSION) if (session) { try { - return JSON.parse(session) as dappAPI.ConnectResult + return JSON.parse(session) as dappAPI.StatusEvent } catch (e) { console.error('Failed to parse stored kernel session:', e) } @@ -44,7 +44,7 @@ export const getKernelSession = (): dappAPI.ConnectResult | undefined => { return undefined } -export const setKernelSession = (session: dappAPI.ConnectResult): void => { +export const setKernelSession = (session: dappAPI.StatusEvent): void => { localStorage.setItem(LOCAL_STORAGE.KERNEL_SESSION, JSON.stringify(session)) } diff --git a/wallet-gateway/extension/src/dapp-api/controller.ts b/wallet-gateway/extension/src/dapp-api/controller.ts index 74deec4d7..92d9af96a 100644 --- a/wallet-gateway/extension/src/dapp-api/controller.ts +++ b/wallet-gateway/extension/src/dapp-api/controller.ts @@ -25,15 +25,21 @@ export const dappController = (store?: Store) => buildController({ connect: async () => Promise.resolve({ - status: { - kernel: kernelInfo, - isConnected: false, - isNetworkConnected: false, - networkReason: 'Unauthenticated', + kernel: kernelInfo, + isConnected: false, + isNetworkConnected: false, + networkReason: 'Unauthenticated', + userUrl: Browser.runtime.getURL('pages/user.html'), + network: { networkId: 'default-network-id', - userUrl: Browser.runtime.getURL('pages/user.html'), + ledgerApi: { + baseUrl: 'http://default-ledger-api', + }, + }, + session: { + accessToken: 'default-access-token', + userId: 'default-user-id', }, - sessionToken: 'default-session-token', }), disconnect: async () => Promise.resolve(null), darsAvailable: async () => Promise.resolve({ dars: ['default-dar'] }), diff --git a/wallet-gateway/extension/src/dapp-api/rpc-gen/typings.ts b/wallet-gateway/extension/src/dapp-api/rpc-gen/typings.ts index f3c0985ba..546e1e4d8 100644 --- a/wallet-gateway/extension/src/dapp-api/rpc-gen/typings.ts +++ b/wallet-gateway/extension/src/dapp-api/rpc-gen/typings.ts @@ -147,20 +147,53 @@ export type NetworkReason = string * */ export type NetworkId = string -export interface StatusEvent { - kernel: KernelInfo - isConnected: IsConnected - isNetworkConnected: IsNetworkConnected - networkReason?: NetworkReason - networkId?: NetworkId +/** + * + * The base URL of the ledger API. + * + */ +export type BaseUrl = string +/** + * + * Ledger API configuration. + * + */ +export interface LedgerApiConfig { + baseUrl: BaseUrl + [k: string]: any +} +/** + * + * Network information, if connected to a network. + * + */ +export interface Network { + networkId: NetworkId + ledgerApi?: LedgerApiConfig [k: string]: any } /** * - * JWT authentication token (if applicable). + * JWT authentication token. + * + */ +export type AccessToken = string +/** + * + * The user identifier. + * + */ +export type UserId = string +/** + * + * Session information, if authenticated. * */ -export type SessionToken = string +export interface Session { + accessToken: AccessToken + userId: UserId + [k: string]: any +} export type Dar = string export type Dars = Dar[] /** @@ -394,9 +427,14 @@ export interface LedgerApiParams { body?: Body [k: string]: any } -export interface ConnectResult { - status: StatusEvent - sessionToken: SessionToken +export interface StatusEvent { + kernel: KernelInfo + isConnected: IsConnected + isNetworkConnected: IsNetworkConnected + networkReason?: NetworkReason + userUrl?: UserUrl + network?: Network + session?: Session [k: string]: any } /** @@ -452,7 +490,7 @@ export type TxChangedEvent = */ export type Status = () => Promise -export type Connect = () => Promise +export type Connect = () => Promise export type Disconnect = () => Promise export type DarsAvailable = () => Promise export type PrepareReturn = ( diff --git a/wallet-gateway/remote/src/dapp-api/controller.ts b/wallet-gateway/remote/src/dapp-api/controller.ts index da283aa39..2c8b9ac8e 100644 --- a/wallet-gateway/remote/src/dapp-api/controller.ts +++ b/wallet-gateway/remote/src/dapp-api/controller.ts @@ -37,14 +37,11 @@ export const dappController = ( connect: async () => { if (!context || !(await store.getSession())) { return { - sessionToken: '', - status: { - kernel: kernelInfo, - isConnected: false, - isNetworkConnected: false, - networkReason: 'Unauthenticated', - userUrl: `${userUrl}/login/`, - }, + kernel: kernelInfo, + isConnected: false, + isNetworkConnected: false, + networkReason: 'Unauthenticated', + userUrl: `${userUrl}/login/`, } } @@ -57,13 +54,20 @@ export const dappController = ( }) const status = await networkStatus(ledgerClient) return { - sessionToken: context.accessToken, - status: { - kernel: kernelInfo, - isConnected: true, - isNetworkConnected: status.isConnected, - networkReason: status.reason ? status.reason : 'OK', - userUrl: `${userUrl}/login/`, + kernel: kernelInfo, + isConnected: true, + isNetworkConnected: status.isConnected, + networkReason: status.reason ? status.reason : 'OK', + userUrl: `${userUrl}/login/`, + network: { + networkId: network.id, + ledgerApi: { + baseUrl: network.ledgerApi.baseUrl, + }, + }, + session: { + accessToken: context.accessToken, + userId: context.userId, }, } }, @@ -220,7 +224,16 @@ export const dappController = ( isConnected: true, isNetworkConnected: status.isConnected, networkReason: status.reason ? status.reason : 'OK', - networkId: (await store.getCurrentNetwork()).id, + network: { + networkId: network.id, + ledgerApi: { + baseUrl: network.ledgerApi.baseUrl, + }, + }, + session: { + accessToken: context.accessToken, + userId: context.userId, + }, } }, onConnected: async () => { diff --git a/wallet-gateway/remote/src/dapp-api/rpc-gen/typings.ts b/wallet-gateway/remote/src/dapp-api/rpc-gen/typings.ts index 25cd6c112..8c9616eb7 100644 --- a/wallet-gateway/remote/src/dapp-api/rpc-gen/typings.ts +++ b/wallet-gateway/remote/src/dapp-api/rpc-gen/typings.ts @@ -134,26 +134,65 @@ export type IsNetworkConnected = boolean * */ export type NetworkReason = string +/** + * + * A URL that points to a user interface. + * + */ +export type UserUrl = string /** * * The network ID the wallet corresponds to. * */ export type NetworkId = string -export interface StatusEvent { - kernel: KernelInfo - isConnected: IsConnected - isNetworkConnected: IsNetworkConnected - networkReason?: NetworkReason - networkId?: NetworkId +/** + * + * The base URL of the ledger API. + * + */ +export type BaseUrl = string +/** + * + * Ledger API configuration. + * + */ +export interface LedgerApiConfig { + baseUrl: BaseUrl [k: string]: any } /** * - * JWT authentication token (if applicable). + * Network information, if connected to a network. * */ -export type SessionToken = string +export interface Network { + networkId: NetworkId + ledgerApi?: LedgerApiConfig + [k: string]: any +} +/** + * + * JWT authentication token. + * + */ +export type AccessToken = string +/** + * + * The user identifier. + * + */ +export type UserId = string +/** + * + * Session information, if authenticated. + * + */ +export interface Session { + accessToken: AccessToken + userId: UserId + [k: string]: any +} export type Dar = string export type Dars = Dar[] /** @@ -178,12 +217,6 @@ export interface JsPrepareSubmissionResponse { preparedTransactionHash?: PreparedTransactionHash [k: string]: any } -/** - * - * A URL that points to a user interface. - * - */ -export type UserUrl = string export type Response = string /** * @@ -393,9 +426,14 @@ export interface LedgerApiParams { body?: Body [k: string]: any } -export interface ConnectResult { - status: StatusEvent - sessionToken: SessionToken +export interface StatusEvent { + kernel: KernelInfo + isConnected: IsConnected + isNetworkConnected: IsNetworkConnected + networkReason?: NetworkReason + userUrl?: UserUrl + network?: Network + session?: Session [k: string]: any } /** @@ -422,11 +460,6 @@ export interface LedgerApiResult { response: Response [k: string]: any } -export interface OnConnectedEvent { - status: StatusEvent - sessionToken?: SessionToken - [k: string]: any -} /** * * Event emitted when the user's accounts change. @@ -456,7 +489,7 @@ export type TxChangedEvent = */ export type Status = () => Promise -export type Connect = () => Promise +export type Connect = () => Promise export type Disconnect = () => Promise export type DarsAvailable = () => Promise export type PrepareReturn = ( @@ -466,7 +499,7 @@ export type PrepareExecute = ( params: PrepareExecuteParams ) => Promise export type LedgerApi = (params: LedgerApiParams) => Promise -export type OnConnected = () => Promise +export type OnConnected = () => Promise export type OnStatusChanged = () => Promise export type OnAccountsChanged = () => Promise export type RequestAccounts = () => Promise diff --git a/wallet-gateway/remote/src/dapp-api/server.test.ts b/wallet-gateway/remote/src/dapp-api/server.test.ts index bd8ecf24a..810af3907 100644 --- a/wallet-gateway/remote/src/dapp-api/server.test.ts +++ b/wallet-gateway/remote/src/dapp-api/server.test.ts @@ -66,17 +66,14 @@ test('call connect rpc', async () => { id: 0, jsonrpc: '2.0', result: { - sessionToken: '', - status: { - kernel: { - id: 'remote-da', - clientType: 'remote', - }, - isConnected: false, - isNetworkConnected: false, - networkReason: 'Unauthenticated', - userUrl: 'http://localhost:3030/login/', + kernel: { + id: 'remote-da', + clientType: 'remote', }, + isConnected: false, + isNetworkConnected: false, + networkReason: 'Unauthenticated', + userUrl: 'http://localhost:3030/login/', }, }) }) diff --git a/wallet-gateway/remote/src/user-api/controller.ts b/wallet-gateway/remote/src/user-api/controller.ts index 1edde3f46..1dbdf0c64 100644 --- a/wallet-gateway/remote/src/user-api/controller.ts +++ b/wallet-gateway/remote/src/user-api/controller.ts @@ -586,14 +586,20 @@ export const userController = ( }) const status = await networkStatus(ledgerClient) notifier.emit('onConnected', { - status: { - kernel: kernelInfo, - isConnected: true, - isNetworkConnected: status.isConnected, - networkReason: status.reason ? status.reason : 'OK', + kernel: kernelInfo, + isConnected: true, + isNetworkConnected: status.isConnected, + networkReason: status.reason ? status.reason : 'OK', + network: { networkId: network.id, + ledgerApi: { + baseUrl: network.ledgerApi.baseUrl, + }, + }, + session: { + accessToken: accessToken, + userId: userId, }, - sessionToken: accessToken, }) return Promise.resolve({