@canton-network/wallet-gateway-remote 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/README.md +25 -0
  2. package/dist/auth/jwt-auth-service.d.ts +11 -0
  3. package/dist/auth/jwt-auth-service.d.ts.map +1 -0
  4. package/dist/auth/jwt-auth-service.js +50 -0
  5. package/dist/config/Config.d.ts +590 -0
  6. package/dist/config/Config.d.ts.map +1 -0
  7. package/dist/config/Config.js +19 -0
  8. package/dist/config/Config.test.d.ts +2 -0
  9. package/dist/config/Config.test.d.ts.map +1 -0
  10. package/dist/config/Config.test.js +19 -0
  11. package/dist/config/ConfigUtils.d.ts +5 -0
  12. package/dist/config/ConfigUtils.d.ts.map +1 -0
  13. package/dist/config/ConfigUtils.js +14 -0
  14. package/dist/dapp-api/controller.d.ts +18 -0
  15. package/dist/dapp-api/controller.d.ts.map +1 -0
  16. package/dist/dapp-api/controller.js +101 -0
  17. package/dist/dapp-api/rpc-gen/index.d.ts +36 -0
  18. package/dist/dapp-api/rpc-gen/index.d.ts.map +1 -0
  19. package/dist/dapp-api/rpc-gen/index.js +17 -0
  20. package/dist/dapp-api/rpc-gen/typings.d.ts +337 -0
  21. package/dist/dapp-api/rpc-gen/typings.d.ts.map +1 -0
  22. package/dist/dapp-api/rpc-gen/typings.js +3 -0
  23. package/dist/dapp-api/server.d.ts +6 -0
  24. package/dist/dapp-api/server.d.ts.map +1 -0
  25. package/dist/dapp-api/server.js +62 -0
  26. package/dist/dapp-api/server.test.d.ts +2 -0
  27. package/dist/dapp-api/server.test.d.ts.map +1 -0
  28. package/dist/dapp-api/server.test.js +45 -0
  29. package/dist/index.d.ts +3 -0
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +30 -0
  32. package/dist/init.d.ts +9 -0
  33. package/dist/init.d.ts.map +1 -0
  34. package/dist/init.js +77 -0
  35. package/dist/ledger/party-allocation-service.d.ts +34 -0
  36. package/dist/ledger/party-allocation-service.d.ts.map +1 -0
  37. package/dist/ledger/party-allocation-service.js +50 -0
  38. package/dist/ledger/party-allocation-service.test.d.ts +2 -0
  39. package/dist/ledger/party-allocation-service.test.d.ts.map +1 -0
  40. package/dist/ledger/party-allocation-service.test.js +85 -0
  41. package/dist/ledger/wallet-sync-service.d.ts +18 -0
  42. package/dist/ledger/wallet-sync-service.d.ts.map +1 -0
  43. package/dist/ledger/wallet-sync-service.js +90 -0
  44. package/dist/middleware/jsonRpcHandler.d.ts +9 -0
  45. package/dist/middleware/jsonRpcHandler.d.ts.map +1 -0
  46. package/dist/middleware/jsonRpcHandler.js +102 -0
  47. package/dist/middleware/jwtAuth.d.ts +5 -0
  48. package/dist/middleware/jwtAuth.d.ts.map +1 -0
  49. package/dist/middleware/jwtAuth.js +20 -0
  50. package/dist/middleware/rateLimit.d.ts +2 -0
  51. package/dist/middleware/rateLimit.d.ts.map +1 -0
  52. package/dist/middleware/rateLimit.js +9 -0
  53. package/dist/notification/NotificationService.d.ts +11 -0
  54. package/dist/notification/NotificationService.d.ts.map +1 -0
  55. package/dist/notification/NotificationService.js +5 -0
  56. package/dist/user-api/controller.d.ts +23 -0
  57. package/dist/user-api/controller.d.ts.map +1 -0
  58. package/dist/user-api/controller.js +336 -0
  59. package/dist/user-api/rpc-gen/index.d.ts +42 -0
  60. package/dist/user-api/rpc-gen/index.d.ts.map +1 -0
  61. package/dist/user-api/rpc-gen/index.js +19 -0
  62. package/dist/user-api/rpc-gen/typings.d.ts +297 -0
  63. package/dist/user-api/rpc-gen/typings.d.ts.map +1 -0
  64. package/dist/user-api/rpc-gen/typings.js +3 -0
  65. package/dist/user-api/server.d.ts +7 -0
  66. package/dist/user-api/server.d.ts.map +1 -0
  67. package/dist/user-api/server.js +20 -0
  68. package/dist/user-api/server.test.d.ts +2 -0
  69. package/dist/user-api/server.test.d.ts.map +1 -0
  70. package/dist/user-api/server.test.js +38 -0
  71. package/dist/web/frontend/404/index.html +20 -0
  72. package/dist/web/frontend/approve/index.html +23 -0
  73. package/dist/web/frontend/assets/404-BHkjVWlW.js +16 -0
  74. package/dist/web/frontend/assets/approve-lRsfAWmm.js +157 -0
  75. package/dist/web/frontend/assets/callback-QrXhW3mX.js +1 -0
  76. package/dist/web/frontend/assets/handle-errors-BcwHAkCd.js +1 -0
  77. package/dist/web/frontend/assets/index-BknZMPaI.css +5 -0
  78. package/dist/web/frontend/assets/index-BxdGgjHv.js +1 -0
  79. package/dist/web/frontend/assets/index-D-GexOrJ.js +697 -0
  80. package/dist/web/frontend/assets/index-TZrNw7dA.css +1 -0
  81. package/dist/web/frontend/assets/login-HUymBqli.js +159 -0
  82. package/dist/web/frontend/assets/networks-BZihbVwK.js +221 -0
  83. package/dist/web/frontend/assets/rpc-client-CCUlY3sp.js +1 -0
  84. package/dist/web/frontend/assets/state-DKGJ6EmM.js +9 -0
  85. package/dist/web/frontend/assets/state-manager-BNW0y5PZ.js +23 -0
  86. package/dist/web/frontend/assets/wallets-BoN6kUME.js +214 -0
  87. package/dist/web/frontend/callback/index.html +13 -0
  88. package/dist/web/frontend/icon.png +0 -0
  89. package/dist/web/frontend/index.html +19 -0
  90. package/dist/web/frontend/login/index.html +21 -0
  91. package/dist/web/frontend/networks/index.html +20 -0
  92. package/dist/web/frontend/wallets/index.html +22 -0
  93. package/dist/web/server.d.ts +2 -0
  94. package/dist/web/server.d.ts.map +1 -0
  95. package/dist/web/server.js +30 -0
  96. package/package.json +86 -0
@@ -0,0 +1,5 @@
1
+ import type { Request, Response, NextFunction } from 'express';
2
+ import { AuthService } from '@canton-network/core-wallet-auth';
3
+ import { Logger } from 'pino';
4
+ export declare function jwtAuth(authService: AuthService, logger: Logger): (req: Request, res: Response, next: NextFunction) => Promise<void>;
5
+ //# sourceMappingURL=jwtAuth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwtAuth.d.ts","sourceRoot":"","sources":["../../src/middleware/jwtAuth.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAA;AAC9D,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAE7B,wBAAgB,OAAO,CAAC,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,IAC9C,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,mBAehE"}
@@ -0,0 +1,20 @@
1
+ // Copyright (c) 2025 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ // middleware/jwtAuth.ts
4
+ export function jwtAuth(authService, logger) {
5
+ return async (req, res, next) => {
6
+ const authHeader = req.headers.authorization;
7
+ try {
8
+ const context = await authService.verifyToken(authHeader);
9
+ req.authContext = context;
10
+ next();
11
+ }
12
+ catch (err) {
13
+ logger.warn({ err }, 'JWT verification failed');
14
+ const message = err instanceof Error ? err.message : String(err);
15
+ res.status(401).json({
16
+ error: 'Invalid or expired token: ' + message,
17
+ });
18
+ }
19
+ };
20
+ }
@@ -0,0 +1,2 @@
1
+ export declare const rpcRateLimit: import("express-rate-limit").RateLimitRequestHandler;
2
+ //# sourceMappingURL=rateLimit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rateLimit.d.ts","sourceRoot":"","sources":["../../src/middleware/rateLimit.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,YAAY,sDAKvB,CAAA"}
@@ -0,0 +1,9 @@
1
+ // Copyright (c) 2025 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ import rateLimit from 'express-rate-limit';
4
+ export const rpcRateLimit = rateLimit({
5
+ windowMs: 1 * 60 * 1000, // 1 minute
6
+ max: 100, // limit each IP to 100 requests per windowMs
7
+ standardHeaders: true,
8
+ legacyHeaders: false,
9
+ });
@@ -0,0 +1,11 @@
1
+ type EventListener = (...args: unknown[]) => void;
2
+ export interface Notifier {
3
+ on(event: string, listener: EventListener): void;
4
+ emit(event: string, ...args: unknown[]): boolean;
5
+ removeListener(event: string, listenerToRemove: EventListener): void;
6
+ }
7
+ export interface NotificationService {
8
+ getNotifier(notifierId: string): Notifier;
9
+ }
10
+ export {};
11
+ //# sourceMappingURL=NotificationService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NotificationService.d.ts","sourceRoot":"","sources":["../../src/notification/NotificationService.ts"],"names":[],"mappings":"AAKA,KAAK,aAAa,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAA;AACjD,MAAM,WAAW,QAAQ;IACrB,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,GAAG,IAAI,CAAA;IAEhD,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,CAAA;IAEhD,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,gBAAgB,EAAE,aAAa,GAAG,IAAI,CAAA;CACvE;AAED,MAAM,WAAW,mBAAmB;IAChC,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,QAAQ,CAAA;CAC5C"}
@@ -0,0 +1,5 @@
1
+ // Copyright (c) 2025 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ // TODO: make events type-of dApp methods (perhaps just )
4
+ // Support event-driven notifications. We represent a notifier with a generic interface to support node and browser implementations.
5
+ export {};
@@ -0,0 +1,23 @@
1
+ import { Store } from '@canton-network/core-wallet-store';
2
+ import { Logger } from 'pino';
3
+ import { NotificationService } from '../notification/NotificationService.js';
4
+ import { AuthContext } from '@canton-network/core-wallet-auth';
5
+ import { KernelInfo } from '../config/Config.js';
6
+ import { SigningDriverInterface, SigningProvider } from '@canton-network/core-signing-lib';
7
+ type AvailableSigningDrivers = Partial<Record<SigningProvider, SigningDriverInterface>>;
8
+ export declare const userController: (kernelInfo: KernelInfo, store: Store, notificationService: NotificationService, authContext: AuthContext | undefined, drivers: AvailableSigningDrivers, _logger: Logger) => {
9
+ addNetwork: import("./rpc-gen/typings.js").AddNetwork;
10
+ removeNetwork: import("./rpc-gen/typings.js").RemoveNetwork;
11
+ createWallet: import("./rpc-gen/typings.js").CreateWallet;
12
+ setPrimaryWallet: import("./rpc-gen/typings.js").SetPrimaryWallet;
13
+ removeWallet: import("./rpc-gen/typings.js").RemoveWallet;
14
+ listWallets: import("./rpc-gen/typings.js").ListWallets;
15
+ syncWallets: import("./rpc-gen/typings.js").SyncWallets;
16
+ sign: import("./rpc-gen/typings.js").Sign;
17
+ execute: import("./rpc-gen/typings.js").Execute;
18
+ listNetworks: import("./rpc-gen/typings.js").ListNetworks;
19
+ addSession: import("./rpc-gen/typings.js").AddSession;
20
+ listSessions: import("./rpc-gen/typings.js").ListSessions;
21
+ };
22
+ export {};
23
+ //# sourceMappingURL=controller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../src/user-api/controller.ts"],"names":[],"mappings":"AAkBA,OAAO,EACH,KAAK,EAIR,MAAM,mCAAmC,CAAA;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAC7B,OAAO,EAAE,mBAAmB,EAAE,MAAM,wCAAwC,CAAA;AAC5E,OAAO,EAEH,WAAW,EAEd,MAAM,kCAAkC,CAAA;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAChD,OAAO,EACH,sBAAsB,EACtB,eAAe,EAClB,MAAM,kCAAkC,CAAA;AAOzC,KAAK,uBAAuB,GAAG,OAAO,CAClC,MAAM,CAAC,eAAe,EAAE,sBAAsB,CAAC,CAClD,CAAA;AAED,eAAO,MAAM,cAAc,GACvB,YAAY,UAAU,EACtB,OAAO,KAAK,EACZ,qBAAqB,mBAAmB,EACxC,aAAa,WAAW,GAAG,SAAS,EACpC,SAAS,uBAAuB,EAChC,SAAS,MAAM;;;;;;;;;;;;;CAiclB,CAAA"}
@@ -0,0 +1,336 @@
1
+ // Copyright (c) 2025 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ // Disabled unused vars rule to allow for future implementations
4
+ /* eslint-disable @typescript-eslint/no-unused-vars */
5
+ import { LedgerClient } from '@canton-network/core-ledger-client';
6
+ import buildController from './rpc-gen/index.js';
7
+ import { assertConnected, clientCredentialsService, } from '@canton-network/core-wallet-auth';
8
+ import { SigningProvider, } from '@canton-network/core-signing-lib';
9
+ import { PartyAllocationService, } from '../ledger/party-allocation-service.js';
10
+ import { WalletSyncService } from '../ledger/wallet-sync-service.js';
11
+ export const userController = (kernelInfo, store, notificationService, authContext, drivers, _logger) => {
12
+ const logger = _logger.child({ component: 'user-controller' });
13
+ return buildController({
14
+ addNetwork: async (params) => {
15
+ const { network } = params;
16
+ const ledgerApi = {
17
+ baseUrl: network.ledgerApi ?? '',
18
+ };
19
+ let auth;
20
+ if (network.auth.type === 'implicit') {
21
+ auth = {
22
+ type: 'implicit',
23
+ identityProviderId: network.auth.identityProviderId,
24
+ issuer: network.auth.issuer ?? '',
25
+ configUrl: network.auth.configUrl ?? '',
26
+ audience: network.auth.audience ?? '',
27
+ scope: network.auth.scope ?? '',
28
+ clientId: network.auth.clientId ?? '',
29
+ };
30
+ }
31
+ else {
32
+ auth = {
33
+ type: 'password',
34
+ identityProviderId: network.auth.identityProviderId,
35
+ issuer: network.auth.issuer ?? '',
36
+ configUrl: network.auth.configUrl ?? '',
37
+ tokenUrl: network.auth.tokenUrl ?? '',
38
+ grantType: network.auth.grantType ?? '',
39
+ scope: network.auth.scope ?? '',
40
+ clientId: network.auth.clientId ?? '',
41
+ audience: network.auth.audience ?? '',
42
+ };
43
+ }
44
+ const newNetwork = {
45
+ name: network.name,
46
+ chainId: network.chainId,
47
+ description: network.description,
48
+ synchronizerId: network.synchronizerId,
49
+ auth,
50
+ ledgerApi,
51
+ };
52
+ // TODO: Add an explicit updateNetwork method to the User API spec and controller
53
+ const existingNetworks = await store.listNetworks();
54
+ if (existingNetworks.find((n) => n.chainId === newNetwork.chainId)) {
55
+ await store.updateNetwork(newNetwork);
56
+ }
57
+ else {
58
+ await store.addNetwork(newNetwork);
59
+ }
60
+ return null;
61
+ },
62
+ removeNetwork: async (params) => {
63
+ await store.removeNetwork(params.networkName);
64
+ return null;
65
+ },
66
+ createWallet: async (params) => {
67
+ logger.info(`Allocating party with params: ${JSON.stringify(params)}`);
68
+ const userId = assertConnected(authContext);
69
+ const notifier = notificationService.getNotifier(userId);
70
+ const network = await store.getCurrentNetwork();
71
+ if (network === undefined) {
72
+ throw new Error('No network session found');
73
+ }
74
+ const adminToken = await clientCredentialsService(network.auth.configUrl, logger).fetchToken({
75
+ clientId: network.auth.admin.clientId,
76
+ clientSecret: network.auth.admin.clientSecret,
77
+ scope: network.auth.scope,
78
+ audience: network.auth.audience,
79
+ });
80
+ logger.debug({ adminToken }, 'Fetched admin token for party allocation');
81
+ const partyAllocator = new PartyAllocationService(network.synchronizerId, adminToken, network.ledgerApi.baseUrl, logger);
82
+ const driver = drivers[params.signingProviderId]?.controller(userId);
83
+ if (!driver) {
84
+ throw new Error(`Signing provider ${params.signingProviderId} not supported`);
85
+ }
86
+ let party;
87
+ let publicKey;
88
+ switch (params.signingProviderId) {
89
+ case SigningProvider.PARTICIPANT: {
90
+ party = await partyAllocator.allocateParty(userId, params.partyHint);
91
+ break;
92
+ }
93
+ case SigningProvider.WALLET_KERNEL: {
94
+ const key = await driver.createKey({
95
+ name: params.partyHint,
96
+ });
97
+ party = await partyAllocator.allocateParty(userId, params.partyHint, key.publicKey, async (hash) => {
98
+ const { signature } = await driver.signTransaction({
99
+ tx: '',
100
+ txHash: hash,
101
+ publicKey: key.publicKey,
102
+ });
103
+ return signature;
104
+ });
105
+ publicKey = key.publicKey;
106
+ break;
107
+ }
108
+ default:
109
+ throw new Error(`Unsupported signing provider: ${params.signingProviderId}`);
110
+ }
111
+ const wallet = {
112
+ signingProviderId: params.signingProviderId,
113
+ chainId: params.chainId,
114
+ primary: params.primary ?? false,
115
+ publicKey: publicKey || party.namespace,
116
+ ...party,
117
+ };
118
+ await store.addWallet(wallet);
119
+ const wallets = await store.getWallets();
120
+ notifier?.emit('accountsChanged', wallets);
121
+ return { wallet };
122
+ },
123
+ setPrimaryWallet: async (params) => {
124
+ store.setPrimaryWallet(params.partyId);
125
+ const notifier = authContext?.userId
126
+ ? notificationService.getNotifier(authContext.userId)
127
+ : undefined;
128
+ notifier?.emit('accountsChanged', await store.getWallets());
129
+ return null;
130
+ },
131
+ removeWallet: async (params) => Promise.resolve({}),
132
+ listWallets: async (params) => {
133
+ // TODO: support filters
134
+ return store.getWallets();
135
+ },
136
+ sign: async ({ preparedTransaction, preparedTransactionHash, partyId, commandId, }) => {
137
+ const wallets = await store.getWallets();
138
+ const wallet = wallets.find((w) => w.partyId === partyId);
139
+ const network = await store.getCurrentNetwork();
140
+ if (wallet === undefined) {
141
+ throw new Error('No primary wallet found');
142
+ }
143
+ const userId = assertConnected(authContext);
144
+ if (network === undefined) {
145
+ throw new Error('No network session found');
146
+ }
147
+ const notifier = notificationService.getNotifier(userId);
148
+ const signingProvider = wallet.signingProviderId;
149
+ const driver = drivers[signingProvider]?.controller(userId);
150
+ if (!driver) {
151
+ throw new Error('No driver found for WALLET_KERNEL');
152
+ }
153
+ switch (wallet.signingProviderId) {
154
+ case SigningProvider.PARTICIPANT: {
155
+ return {
156
+ signature: 'none',
157
+ signedBy: wallet.namespace,
158
+ partyId,
159
+ };
160
+ }
161
+ case SigningProvider.WALLET_KERNEL: {
162
+ const signature = await driver.signTransaction({
163
+ tx: preparedTransaction,
164
+ txHash: preparedTransactionHash,
165
+ publicKey: wallet.publicKey,
166
+ });
167
+ if (!signature.signature) {
168
+ throw new Error('Failed to sign transaction: ' +
169
+ JSON.stringify(signature));
170
+ }
171
+ const signedTx = {
172
+ commandId,
173
+ status: 'signed',
174
+ preparedTransaction,
175
+ preparedTransactionHash,
176
+ };
177
+ store.setTransaction(signedTx);
178
+ notifier.emit('txChanged', signedTx);
179
+ return {
180
+ signature: signature.signature,
181
+ signedBy: wallet.namespace,
182
+ partyId: wallet.partyId,
183
+ };
184
+ }
185
+ default:
186
+ throw new Error(`Unsupported signing provider: ${wallet.signingProviderId}`);
187
+ }
188
+ },
189
+ execute: async ({ commandId, signature, signedBy, partyId, }) => {
190
+ const wallet = await store.getPrimaryWallet();
191
+ const network = await store.getCurrentNetwork();
192
+ const transaction = await store.getTransaction(commandId);
193
+ if (wallet === undefined) {
194
+ throw new Error('No primary wallet found');
195
+ }
196
+ if (transaction === undefined) {
197
+ throw new Error('No transaction found');
198
+ }
199
+ const userId = assertConnected(authContext);
200
+ if (network === undefined) {
201
+ throw new Error('No network session found');
202
+ }
203
+ const notifier = notificationService.getNotifier(userId);
204
+ const ledgerClient = new LedgerClient(new URL(network.ledgerApi.baseUrl), authContext.accessToken, logger);
205
+ switch (wallet.signingProviderId) {
206
+ case SigningProvider.PARTICIPANT: {
207
+ // Participant signing provider specific logic can be added here
208
+ const request = {
209
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- because OpenRPC codegen type is incompatible with ledger codegen type
210
+ commands: transaction?.payload,
211
+ commandId,
212
+ userId,
213
+ actAs: [partyId],
214
+ readAs: [],
215
+ disclosedContracts: [],
216
+ synchronizerId: network.synchronizerId,
217
+ packageIdSelectionPreference: [],
218
+ };
219
+ try {
220
+ const res = await ledgerClient.post('/v2/commands/submit-and-wait', request);
221
+ notifier.emit('txChanged', {
222
+ status: 'executed',
223
+ commandId,
224
+ payload: res,
225
+ });
226
+ return res;
227
+ }
228
+ catch (error) {
229
+ throw new Error('Failed to submit transaction: ' + error);
230
+ }
231
+ }
232
+ case SigningProvider.WALLET_KERNEL: {
233
+ const result = await ledgerClient.post('/v2/interactive-submission/execute', {
234
+ userId,
235
+ preparedTransaction: transaction.preparedTransaction,
236
+ hashingSchemeVersion: 'HASHING_SCHEME_VERSION_V2',
237
+ submissionId: commandId,
238
+ deduplicationPeriod: {
239
+ Empty: {},
240
+ },
241
+ partySignatures: {
242
+ signatures: [
243
+ {
244
+ party: partyId,
245
+ signatures: [
246
+ {
247
+ signature,
248
+ signedBy,
249
+ format: 'SIGNATURE_FORMAT_CONCAT',
250
+ signingAlgorithmSpec: 'SIGNING_ALGORITHM_SPEC_ED25519',
251
+ },
252
+ ],
253
+ },
254
+ ],
255
+ },
256
+ });
257
+ const signedTx = {
258
+ commandId,
259
+ status: 'executed',
260
+ preparedTransaction: transaction.preparedTransaction,
261
+ preparedTransactionHash: transaction.preparedTransactionHash,
262
+ payload: result,
263
+ };
264
+ store.setTransaction(signedTx);
265
+ notifier.emit('txChanged', signedTx);
266
+ return result;
267
+ }
268
+ default:
269
+ throw new Error(`Unsupported signing provider: ${wallet.signingProviderId}`);
270
+ }
271
+ },
272
+ listNetworks: async () => Promise.resolve({ networks: await store.listNetworks() }),
273
+ addSession: async function (params) {
274
+ try {
275
+ await store.setSession({
276
+ network: params.chainId,
277
+ accessToken: authContext?.accessToken || '',
278
+ });
279
+ const network = await store.getCurrentNetwork();
280
+ // Assumption: `setSession` calls `assertConnected`, so its safe to declare that the authContext is defined.
281
+ const { userId, accessToken } = authContext;
282
+ const notifier = notificationService.getNotifier(userId);
283
+ notifier.emit('onConnected', {
284
+ kernel: kernelInfo,
285
+ sessionToken: accessToken,
286
+ chainId: network.chainId,
287
+ });
288
+ return Promise.resolve({
289
+ accessToken,
290
+ status: 'connected',
291
+ network: {
292
+ name: network.name,
293
+ chainId: network.chainId,
294
+ synchronizerId: network.synchronizerId,
295
+ description: network.description,
296
+ ledgerApi: network.ledgerApi,
297
+ auth: network.auth,
298
+ },
299
+ });
300
+ }
301
+ catch (error) {
302
+ logger.error(`Failed to add session: ${error}`);
303
+ throw new Error(`Failed to add session: ${error}`);
304
+ }
305
+ },
306
+ listSessions: async () => {
307
+ const session = await store.getSession();
308
+ if (!session) {
309
+ return { sessions: [] };
310
+ }
311
+ const network = await store.getNetwork(session.network);
312
+ return {
313
+ sessions: [
314
+ {
315
+ accessToken: authContext.accessToken,
316
+ status: 'connected',
317
+ network: {
318
+ name: network.name,
319
+ chainId: network.chainId,
320
+ synchronizerId: network.synchronizerId,
321
+ description: network.description,
322
+ ledgerApi: network.ledgerApi,
323
+ auth: network.auth,
324
+ },
325
+ },
326
+ ],
327
+ };
328
+ },
329
+ syncWallets: async function () {
330
+ const network = await store.getCurrentNetwork();
331
+ assertConnected(authContext);
332
+ const service = new WalletSyncService(store, new LedgerClient(new URL(network.ledgerApi.baseUrl), authContext.accessToken, logger), authContext, logger);
333
+ return await service.syncWallets();
334
+ },
335
+ });
336
+ };
@@ -0,0 +1,42 @@
1
+ import { AddNetwork } from './typings.js';
2
+ import { RemoveNetwork } from './typings.js';
3
+ import { CreateWallet } from './typings.js';
4
+ import { SetPrimaryWallet } from './typings.js';
5
+ import { RemoveWallet } from './typings.js';
6
+ import { ListWallets } from './typings.js';
7
+ import { SyncWallets } from './typings.js';
8
+ import { Sign } from './typings.js';
9
+ import { Execute } from './typings.js';
10
+ import { ListNetworks } from './typings.js';
11
+ import { AddSession } from './typings.js';
12
+ import { ListSessions } from './typings.js';
13
+ export type Methods = {
14
+ addNetwork: AddNetwork;
15
+ removeNetwork: RemoveNetwork;
16
+ createWallet: CreateWallet;
17
+ setPrimaryWallet: SetPrimaryWallet;
18
+ removeWallet: RemoveWallet;
19
+ listWallets: ListWallets;
20
+ syncWallets: SyncWallets;
21
+ sign: Sign;
22
+ execute: Execute;
23
+ listNetworks: ListNetworks;
24
+ addSession: AddSession;
25
+ listSessions: ListSessions;
26
+ };
27
+ declare function buildController(methods: Methods): {
28
+ addNetwork: AddNetwork;
29
+ removeNetwork: RemoveNetwork;
30
+ createWallet: CreateWallet;
31
+ setPrimaryWallet: SetPrimaryWallet;
32
+ removeWallet: RemoveWallet;
33
+ listWallets: ListWallets;
34
+ syncWallets: SyncWallets;
35
+ sign: Sign;
36
+ execute: Execute;
37
+ listNetworks: ListNetworks;
38
+ addSession: AddSession;
39
+ listSessions: ListSessions;
40
+ };
41
+ export default buildController;
42
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/user-api/rpc-gen/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAA;AACnC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAE3C,MAAM,MAAM,OAAO,GAAG;IAClB,UAAU,EAAE,UAAU,CAAA;IACtB,aAAa,EAAE,aAAa,CAAA;IAC5B,YAAY,EAAE,YAAY,CAAA;IAC1B,gBAAgB,EAAE,gBAAgB,CAAA;IAClC,YAAY,EAAE,YAAY,CAAA;IAC1B,WAAW,EAAE,WAAW,CAAA;IACxB,WAAW,EAAE,WAAW,CAAA;IACxB,IAAI,EAAE,IAAI,CAAA;IACV,OAAO,EAAE,OAAO,CAAA;IAChB,YAAY,EAAE,YAAY,CAAA;IAC1B,UAAU,EAAE,UAAU,CAAA;IACtB,YAAY,EAAE,YAAY,CAAA;CAC7B,CAAA;AAED,iBAAS,eAAe,CAAC,OAAO,EAAE,OAAO;;;;;;;;;;;;;EAexC;AAED,eAAe,eAAe,CAAA"}
@@ -0,0 +1,19 @@
1
+ // Copyright (c) 2025 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ function buildController(methods) {
4
+ return {
5
+ addNetwork: methods.addNetwork,
6
+ removeNetwork: methods.removeNetwork,
7
+ createWallet: methods.createWallet,
8
+ setPrimaryWallet: methods.setPrimaryWallet,
9
+ removeWallet: methods.removeWallet,
10
+ listWallets: methods.listWallets,
11
+ syncWallets: methods.syncWallets,
12
+ sign: methods.sign,
13
+ execute: methods.execute,
14
+ listNetworks: methods.listNetworks,
15
+ addSession: methods.addSession,
16
+ listSessions: methods.listSessions,
17
+ };
18
+ }
19
+ export default buildController;