@canton-network/wallet-gateway-remote 0.27.0 → 1.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 (45) hide show
  1. package/dist/example-config.d.ts +6 -6
  2. package/dist/index.d.ts +3 -3
  3. package/dist/ledger/wallet-sync-service.d.ts +2 -1
  4. package/dist/ledger/wallet-sync-service.d.ts.map +1 -1
  5. package/dist/ledger/wallet-sync-service.js +63 -47
  6. package/dist/ledger/wallet-sync-service.test.js +169 -50
  7. package/dist/user-api/controller.d.ts.map +1 -1
  8. package/dist/user-api/controller.js +34 -5
  9. package/dist/user-api/rpc-gen/typings.d.ts +16 -1
  10. package/dist/user-api/rpc-gen/typings.d.ts.map +1 -1
  11. package/dist/web/frontend/404/index.html +2 -2
  12. package/dist/web/frontend/activities/index.html +3 -3
  13. package/dist/web/frontend/approve/index.html +5 -5
  14. package/dist/web/frontend/assets/404-BCjBS7OU.js +5 -0
  15. package/dist/web/frontend/assets/{activities-CPXS4OC3.js → activities-4fnnetzm.js} +1 -1
  16. package/dist/web/frontend/assets/{addIdentityProvider-BJjhu--M.js → addIdentityProvider-uy13wDEx.js} +2 -2
  17. package/dist/web/frontend/assets/{addNetwork-B0olMmyv.js → addNetwork-B9yARLXq.js} +2 -2
  18. package/dist/web/frontend/assets/{addParty-PUjps7Ie.js → addParty-4qt8FiJv.js} +1 -1
  19. package/dist/web/frontend/assets/{approve-CARzty9R.js → approve-DUxX18Xm.js} +1 -1
  20. package/dist/web/frontend/assets/{callback-BqE26RlP.js → callback-BGMELOxy.js} +1 -1
  21. package/dist/web/frontend/assets/{identityProviders-Cnx8VIsD.js → identityProviders-ByQNvF7K.js} +1 -1
  22. package/dist/web/frontend/assets/{index-nOmkqkbK.js → index-DcZcHMS1.js} +1 -1
  23. package/dist/web/frontend/assets/{index-CgsIALyR.js → index-DvQio60y.js} +1 -1
  24. package/dist/web/frontend/assets/{index-UdyYJ_nU.js → index-lfC4c213.js} +83 -83
  25. package/dist/web/frontend/assets/{login-CkpIib74.js → login-BtNyAQqL.js} +2 -2
  26. package/dist/web/frontend/assets/{networks-D7iP_lGh.js → networks-B8bwNVkz.js} +1 -1
  27. package/dist/web/frontend/assets/{reviewIdentityProvider-BRb38sGH.js → reviewIdentityProvider-CWDFtb4t.js} +3 -3
  28. package/dist/web/frontend/assets/{reviewNetwork-BVdYGugz.js → reviewNetwork-ZgS_rpXv.js} +2 -2
  29. package/dist/web/frontend/assets/{settings-CxEU64oG.js → settings-BiWW1vj2.js} +1 -1
  30. package/dist/web/frontend/assets/{state-CypMU0cY.js → state-BpQr_22x.js} +1 -1
  31. package/dist/web/frontend/assets/{utils-V1qa66Nv.js → utils-BNCwV3PT.js} +1 -1
  32. package/dist/web/frontend/callback/index.html +2 -2
  33. package/dist/web/frontend/identity-providers/add/index.html +3 -3
  34. package/dist/web/frontend/identity-providers/index.html +3 -3
  35. package/dist/web/frontend/identity-providers/review/index.html +3 -3
  36. package/dist/web/frontend/index.html +1 -1
  37. package/dist/web/frontend/login/index.html +4 -4
  38. package/dist/web/frontend/networks/add/index.html +3 -3
  39. package/dist/web/frontend/networks/index.html +3 -3
  40. package/dist/web/frontend/networks/review/index.html +3 -3
  41. package/dist/web/frontend/parties/add/index.html +5 -5
  42. package/dist/web/frontend/parties/index.html +4 -4
  43. package/dist/web/frontend/settings/index.html +3 -3
  44. package/package.json +20 -20
  45. package/dist/web/frontend/assets/404-CEXKCUlr.js +0 -5
@@ -34,7 +34,7 @@ declare const _default: {
34
34
  id: string;
35
35
  type: "self_signed";
36
36
  issuer: string;
37
- configUrl?: never;
37
+ configUrl?: undefined;
38
38
  } | {
39
39
  id: string;
40
40
  type: "oauth";
@@ -61,7 +61,7 @@ declare const _default: {
61
61
  audience: string;
62
62
  clientId: string;
63
63
  clientSecret: string;
64
- clientSecretEnv?: never;
64
+ clientSecretEnv?: undefined;
65
65
  };
66
66
  ledgerApi: {
67
67
  baseUrl: string;
@@ -76,8 +76,8 @@ declare const _default: {
76
76
  clientId: string;
77
77
  scope: string;
78
78
  audience: string;
79
- issuer?: never;
80
- clientSecret?: never;
79
+ issuer?: undefined;
80
+ clientSecret?: undefined;
81
81
  };
82
82
  adminAuth: {
83
83
  method: "client_credentials";
@@ -85,8 +85,8 @@ declare const _default: {
85
85
  audience: string;
86
86
  clientId: string;
87
87
  clientSecretEnv: string;
88
- issuer?: never;
89
- clientSecret?: never;
88
+ issuer?: undefined;
89
+ clientSecret?: undefined;
90
90
  };
91
91
  ledgerApi: {
92
92
  baseUrl: string;
package/dist/index.d.ts CHANGED
@@ -3,9 +3,9 @@ declare const options: {
3
3
  config: string;
4
4
  configSchema: boolean;
5
5
  configExample: boolean;
6
- port?: string | true;
7
- logFormat?: "json" | "pretty";
8
- logLevel?: "error" | "trace" | "debug" | "info" | "warn" | "fatal";
6
+ port?: string | true | undefined;
7
+ logFormat?: "json" | "pretty" | undefined;
8
+ logLevel?: "error" | "trace" | "debug" | "info" | "warn" | "fatal" | undefined;
9
9
  };
10
10
  export type CliOptions = typeof options;
11
11
  export {};
@@ -16,7 +16,8 @@ export declare class WalletSyncService {
16
16
  private static readonly EMPTY_RIGHTS;
17
17
  private sameRights;
18
18
  run(timeoutMs: number): Promise<void>;
19
- protected resolveSigningProvider(namespace: string): Promise<{
19
+ private getParticipantNamespace;
20
+ protected resolveSigningProvider(partyNamespace: string, participantNamespace: string): Promise<{
20
21
  signingProviderId: SigningProvider.PARTICIPANT;
21
22
  matched: boolean;
22
23
  } | {
@@ -1 +1 @@
1
- {"version":3,"file":"wallet-sync-service.d.ts","sourceRoot":"","sources":["../../src/ledger/wallet-sync-service.ts"],"names":[],"mappings":"AAGA,OAAO,EACH,YAAY,EAEf,MAAM,oCAAoC,CAAA;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAA;AAC9D,OAAO,EACH,KAAK,EAIR,MAAM,mCAAmC,CAAA;AAC1C,OAAO,EACH,sBAAsB,EACtB,eAAe,EAClB,MAAM,kCAAkC,CAAA;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAC7B,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAA;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAGlE,qBAAa,iBAAiB;IAEtB,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,cAAc;IAGtB,OAAO,CAAC,cAAc;gBAPd,KAAK,EAAE,KAAK,EACZ,YAAY,EAAE,YAAY,EAC1B,WAAW,EAAE,WAAW,EACxB,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,OAAO,CAC3B,MAAM,CAAC,eAAe,EAAE,sBAAsB,CAAC,CAClD,YAAK,EACE,cAAc,EAAE,sBAAsB;IAGlD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAwB;IAE5D,OAAO,CAAC,UAAU;IAUZ,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;cAU3B,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAC5D;QACI,iBAAiB,EAAE,eAAe,CAAC,WAAW,CAAA;QAC9C,OAAO,EAAE,OAAO,CAAA;KACnB,GACD;QACI,iBAAiB,EAAE,OAAO,CACtB,eAAe,EACf,eAAe,CAAC,WAAW,CAC9B,CAAA;QACD,SAAS,EAAE,MAAM,CAAA;QACjB,OAAO,EAAE,OAAO,CAAA;KACnB,CACN;YA4Ha,iBAAiB;IA8DzB,kBAAkB,IAAI,OAAO,CAAC,OAAO,CAAC;YA8D9B,yBAAyB;YAkEzB,0BAA0B;YAgD1B,mBAAmB;IAsB3B,WAAW,IAAI,OAAO,CAAC,iBAAiB,CAAC;CAuGlD"}
1
+ {"version":3,"file":"wallet-sync-service.d.ts","sourceRoot":"","sources":["../../src/ledger/wallet-sync-service.ts"],"names":[],"mappings":"AAGA,OAAO,EACH,YAAY,EAEf,MAAM,oCAAoC,CAAA;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAA;AAC9D,OAAO,EACH,KAAK,EAIR,MAAM,mCAAmC,CAAA;AAC1C,OAAO,EACH,sBAAsB,EACtB,eAAe,EAClB,MAAM,kCAAkC,CAAA;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAC7B,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAA;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAGlE,qBAAa,iBAAiB;IAEtB,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,cAAc;IAGtB,OAAO,CAAC,cAAc;gBAPd,KAAK,EAAE,KAAK,EACZ,YAAY,EAAE,YAAY,EAC1B,WAAW,EAAE,WAAW,EACxB,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,OAAO,CAC3B,MAAM,CAAC,eAAe,EAAE,sBAAsB,CAAC,CAClD,YAAK,EACE,cAAc,EAAE,sBAAsB;IAGlD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAwB;IAE5D,OAAO,CAAC,UAAU;IAUZ,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAU7B,uBAAuB;cAkBrB,sBAAsB,CAClC,cAAc,EAAE,MAAM,EACtB,oBAAoB,EAAE,MAAM,GAC7B,OAAO,CACJ;QACI,iBAAiB,EAAE,eAAe,CAAC,WAAW,CAAA;QAC9C,OAAO,EAAE,OAAO,CAAA;KACnB,GACD;QACI,iBAAiB,EAAE,OAAO,CACtB,eAAe,EACf,eAAe,CAAC,WAAW,CAC9B,CAAA;QACD,SAAS,EAAE,MAAM,CAAA;QACjB,OAAO,EAAE,OAAO,CAAA;KACnB,CACN;YAwGa,iBAAiB;IA8DzB,kBAAkB,IAAI,OAAO,CAAC,OAAO,CAAC;YA8D9B,yBAAyB;YA2EzB,0BAA0B;YAoD1B,mBAAmB;IAsB3B,WAAW,IAAI,OAAO,CAAC,iBAAiB,CAAC;CAgHlD"}
@@ -28,27 +28,23 @@ export class WalletSyncService {
28
28
  await new Promise((res) => setTimeout(res, timeoutMs));
29
29
  }
30
30
  }
31
- async resolveSigningProvider(namespace) {
31
+ async getParticipantNamespace() {
32
+ const { participantId } = await this.ledgerClient.getWithRetry('/v2/parties/participant-id', defaultRetryableOptions);
33
+ // Extract the namespace part from participantId
34
+ // Format is hint::namespace
35
+ const [, extractedNamespace] = participantId.split('::');
36
+ if (extractedNamespace) {
37
+ return extractedNamespace;
38
+ }
39
+ else {
40
+ throw new Error(`Invalid participantId format: expected "hint::namespace", got "${participantId}"`);
41
+ }
42
+ }
43
+ // Protected for tests
44
+ async resolveSigningProvider(partyNamespace, participantNamespace) {
32
45
  try {
33
- // Check if namespace matches participant namespace first
34
- // (participant parties have namespace === participantId's namespace)
35
- let participantNamespace;
36
- try {
37
- const { participantId } = await this.ledgerClient.getWithRetry('/v2/parties/participant-id', defaultRetryableOptions);
38
- // Extract the namespace part from participantId
39
- // Format is hint::namespace
40
- const [, extractedNamespace] = participantId.split('::');
41
- if (extractedNamespace) {
42
- participantNamespace = extractedNamespace;
43
- }
44
- else {
45
- this.logger.warn({ participantId }, `Invalid participantId format: expected "hint::namespace", got "${participantId}"`);
46
- }
47
- }
48
- catch (err) {
49
- this.logger.warn({ err }, 'Failed to get participant namespace');
50
- }
51
- if (participantNamespace && namespace === participantNamespace) {
46
+ if (participantNamespace &&
47
+ partyNamespace === participantNamespace) {
52
48
  return {
53
49
  signingProviderId: SigningProvider.PARTICIPANT,
54
50
  matched: true,
@@ -82,9 +78,9 @@ export class WalletSyncService {
82
78
  if (!normalizedKey)
83
79
  continue;
84
80
  const keyNamespace = this.partyAllocator.createFingerprintFromKey(normalizedKey);
85
- if (keyNamespace === namespace) {
81
+ if (keyNamespace === partyNamespace) {
86
82
  this.logger.info({
87
- namespace,
83
+ namespace: partyNamespace,
88
84
  providerId,
89
85
  keyId: key.id,
90
86
  publicKey: key.publicKey,
@@ -104,14 +100,14 @@ export class WalletSyncService {
104
100
  }
105
101
  }
106
102
  // No match found - use participant as default provider
107
- this.logger.warn({ namespace }, 'No signing provider match found for namespace, using participant as default and marking wallet as unmatched (disabled)');
103
+ this.logger.warn({ namespace: partyNamespace }, 'No signing provider match found for namespace, using participant as default and marking wallet as unmatched (disabled)');
108
104
  return {
109
105
  signingProviderId: SigningProvider.PARTICIPANT,
110
106
  matched: false,
111
107
  };
112
108
  }
113
109
  catch (err) {
114
- this.logger.error({ err, namespace }, 'Error resolving signing provider, using participant as default and marking wallet as unmatched (disabled)');
110
+ this.logger.error({ err, namespace: partyNamespace }, 'Error resolving signing provider, using participant as default and marking wallet as unmatched (disabled)');
115
111
  // On error, use participant as default but mark as unmatched
116
112
  return {
117
113
  signingProviderId: SigningProvider.PARTICIPANT,
@@ -217,12 +213,12 @@ export class WalletSyncService {
217
213
  }
218
214
  // Participant wallets: disable when party not on ledger (participant node reset, namespace changed).
219
215
  // Other wallets: mark as initialized so user can re-allocate (e.g. after external signing).
220
- async handleWalletsWithoutParty(enabledWallets, partiesWithRights) {
221
- const walletsWithoutParty = enabledWallets.filter((wallet) => !partiesWithRights.has(wallet.partyId));
222
- const markedForAllocateWallets = [];
223
- const disabledExistingWallets = [];
216
+ async handleWalletsWithoutParty(allocatedWallets, partiesWithRights) {
217
+ const walletsWithoutParty = allocatedWallets.filter((wallet) => !partiesWithRights.has(wallet.partyId));
218
+ const updatedToInitialized = [];
219
+ const updatedToDisabled = [];
224
220
  for (const wallet of walletsWithoutParty) {
225
- if (wallet.status !== 'allocated')
221
+ if (wallet.status !== 'allocated' || wallet.disabled)
226
222
  continue;
227
223
  try {
228
224
  if (wallet.signingProviderId === SigningProvider.PARTICIPANT) {
@@ -230,6 +226,12 @@ export class WalletSyncService {
230
226
  partyId: wallet.partyId,
231
227
  signingProviderId: wallet.signingProviderId,
232
228
  }, 'Participant wallet party not on ledger, disabling (participant namespace changed)');
229
+ const disabledWallet = {
230
+ ...wallet,
231
+ disabled: true,
232
+ reason: WALLET_DISABLED_REASON.PARTICIPANT_NAMESPACE_CHANGED,
233
+ ...(wallet.primary && { primary: false }),
234
+ };
233
235
  await this.store.updateWallet({
234
236
  partyId: wallet.partyId,
235
237
  networkId: wallet.networkId,
@@ -237,7 +239,7 @@ export class WalletSyncService {
237
239
  reason: WALLET_DISABLED_REASON.PARTICIPANT_NAMESPACE_CHANGED,
238
240
  ...(wallet.primary && { primary: false }),
239
241
  });
240
- disabledExistingWallets.push(wallet);
242
+ updatedToDisabled.push(disabledWallet);
241
243
  }
242
244
  else {
243
245
  this.logger.info({
@@ -250,7 +252,12 @@ export class WalletSyncService {
250
252
  status: 'initialized',
251
253
  ...(wallet.primary && { primary: false }),
252
254
  });
253
- markedForAllocateWallets.push(wallet);
255
+ const reinitialized = {
256
+ ...wallet,
257
+ status: 'initialized',
258
+ ...(wallet.primary && { primary: false }),
259
+ };
260
+ updatedToInitialized.push(reinitialized);
254
261
  }
255
262
  }
256
263
  catch (err) {
@@ -258,16 +265,15 @@ export class WalletSyncService {
258
265
  }
259
266
  }
260
267
  return {
261
- markedForAllocateWallets,
262
- walletsWithoutParty,
263
- disabledExistingWallets,
268
+ updatedToInitialized,
269
+ updatedToDisabled,
264
270
  };
265
271
  }
266
272
  // Creates wallets for parties user has rights to
267
- async handlePartiesWithoutWallet(newParties, networkId, rightsByParty) {
273
+ async handlePartiesWithoutWallet(newParties, networkId, rightsByParty, participantNamespace) {
268
274
  return await Promise.all(newParties.map(async (partyId) => {
269
275
  const [hint, namespace] = partyId.split('::');
270
- const resolvedSigningProvider = await this.resolveSigningProvider(namespace);
276
+ const resolvedSigningProvider = await this.resolveSigningProvider(namespace, participantNamespace);
271
277
  const isMatched = resolvedSigningProvider.matched;
272
278
  const walletPublicKey = resolvedSigningProvider.signingProviderId ===
273
279
  SigningProvider.PARTICIPANT
@@ -316,6 +322,7 @@ export class WalletSyncService {
316
322
  async syncWallets() {
317
323
  this.logger.info('Starting wallet sync...');
318
324
  try {
325
+ const participantNamespace = await this.getParticipantNamespace();
319
326
  const network = await this.store.getCurrentNetwork();
320
327
  this.logger.info(network, 'Current network');
321
328
  const { rightsByParty, rightsByUser } = await this.getRightsSnapshot();
@@ -332,13 +339,14 @@ export class WalletSyncService {
332
339
  const newParties = partiesWithRights.filter((party) => !existingPartiesOnNetwork.has(`${party}:${network.id}`)
333
340
  // todo: filter on idp id
334
341
  );
335
- const { markedForAllocateWallets, walletsWithoutParty, disabledExistingWallets, } = await this.handleWalletsWithoutParty(existingAllocatedWallets, new Set(partiesWithRights));
342
+ const { updatedToInitialized, updatedToDisabled } = await this.handleWalletsWithoutParty(existingAllocatedWallets, new Set(partiesWithRights));
336
343
  const rightsUpdatedWallets = await this.handleRightsUpdates(existingAllocatedWallets, rightsByParty);
337
344
  this.logger.info({
338
345
  newParties,
339
- markedForAllocate: markedForAllocateWallets.map((w) => w.partyId),
346
+ updatedToInitialized: updatedToInitialized.map((w) => w.partyId),
347
+ updatedToDisabled: updatedToDisabled.map((w) => w.partyId),
340
348
  }, 'Wallets without parties');
341
- const newParticipantWallets = await this.handlePartiesWithoutWallet(newParties, network.id, rightsByParty);
349
+ const newParticipantWallets = await this.handlePartiesWithoutWallet(newParties, network.id, rightsByParty, participantNamespace);
342
350
  // Set primary wallet if none exists, or if primary is on an initialized wallet
343
351
  const networkWallets = await this.store.getWallets();
344
352
  const primaryWallet = networkWallets.find((w) => w.primary);
@@ -349,19 +357,27 @@ export class WalletSyncService {
349
357
  await this.store.setPrimaryWallet(allocatedWallets[0].partyId);
350
358
  this.logger.info(`Set ${allocatedWallets[0].partyId} as primary wallet in network ${network.id}`);
351
359
  }
360
+ const newWallets = newParticipantWallets;
361
+ const updatedRaw = [
362
+ ...updatedToInitialized,
363
+ ...rightsUpdatedWallets,
364
+ ];
365
+ const added = newWallets.filter((wallet) => !wallet.disabled);
366
+ const updated = updatedRaw.filter((wallet) => !wallet.disabled);
352
367
  const disabled = [
353
- ...newParticipantWallets.filter((wallet) => wallet.disabled),
354
- ...disabledExistingWallets,
368
+ ...newWallets.filter((wallet) => wallet.disabled),
369
+ ...updatedRaw.filter((wallet) => wallet.disabled),
370
+ ...updatedToDisabled,
355
371
  ];
356
372
  this.logger.info({
357
- added: newParticipantWallets,
358
- updated: [...walletsWithoutParty, ...rightsUpdatedWallets],
359
- disabled: disabled,
373
+ added,
374
+ updated,
375
+ disabled,
360
376
  }, 'Wallet sync completed.');
361
377
  return {
362
- added: newParticipantWallets,
363
- updated: [...walletsWithoutParty, ...rightsUpdatedWallets],
364
- disabled: disabled,
378
+ added,
379
+ updated,
380
+ disabled,
365
381
  };
366
382
  }
367
383
  catch (err) {