@canton-network/core-wallet-store-sql 0.11.0 → 0.12.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.
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../src/bootstrap.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAE/B,OAAO,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAA;AAC/D,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAC7B,OAAO,EAAE,EAAE,EAAE,MAAM,UAAU,CAAA;AAE7B,wBAAsB,SAAS,CAC3B,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,EACd,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAKf"}
1
+ {"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../src/bootstrap.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAE/B,OAAO,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAA;AAC/D,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAC7B,OAAO,EAAE,EAAE,EAAE,MAAM,UAAU,CAAA;AAE7B,wBAAsB,SAAS,CAC3B,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,EACd,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAUf"}
package/dist/index.cjs CHANGED
@@ -15,161 +15,70 @@ var Database__default = /*#__PURE__*/_interopDefault(Database);
15
15
  var __defProp = Object.defineProperty;
16
16
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
17
17
  var __publicField = (obj, key, value) => __defNormalProp(obj, key + "" , value);
18
-
19
- // src/schema.ts
20
- var toAuth = (table) => {
18
+ var toIdp = (table) => {
21
19
  switch (table.type) {
22
- case "password":
23
- return {
24
- identityProviderId: table.identityProviderId,
25
- type: table.type,
26
- issuer: table.issuer,
27
- configUrl: table.configUrl,
28
- audience: table.audience,
29
- tokenUrl: table.tokenUrl || "",
30
- grantType: table.grantType || "",
31
- scope: table.scope,
32
- clientId: table.clientId,
33
- admin: {
34
- clientId: table.adminClientId,
35
- clientSecret: table.adminClientSecret
36
- }
37
- };
38
- case "implicit":
39
- return {
40
- identityProviderId: table.identityProviderId,
41
- type: table.type,
42
- issuer: table.issuer,
43
- configUrl: table.configUrl,
44
- audience: table.audience,
45
- scope: table.scope,
46
- clientId: table.clientId,
47
- admin: {
48
- clientId: table.adminClientId,
49
- clientSecret: table.adminClientSecret
50
- }
51
- };
52
- case "client_credentials":
20
+ case "oauth": {
21
+ if (!table.configUrl) {
22
+ throw new Error(`Missing configUrl for oauth IdP: ${table.id}`);
23
+ }
53
24
  return {
54
- identityProviderId: table.identityProviderId,
25
+ id: table.id,
55
26
  type: table.type,
56
27
  issuer: table.issuer,
57
- configUrl: table.configUrl,
58
- audience: table.audience,
59
- scope: table.scope,
60
- clientId: table.clientId,
61
- clientSecret: table.clientSecret,
62
- admin: {
63
- clientId: table.adminClientId,
64
- clientSecret: table.adminClientSecret
65
- }
28
+ configUrl: table.configUrl
66
29
  };
30
+ }
67
31
  case "self_signed":
68
32
  return {
69
- identityProviderId: table.identityProviderId,
33
+ id: table.id,
70
34
  type: table.type,
71
- issuer: table.issuer,
72
- audience: table.audience,
73
- scope: table.scope,
74
- clientId: table.clientId,
75
- clientSecret: table.clientSecret,
76
- admin: {
77
- clientId: table.adminClientId,
78
- clientSecret: table.adminClientSecret
79
- }
35
+ issuer: table.issuer
80
36
  };
81
- default:
82
- throw new Error(`Unknown auth type: ${table.type}`);
83
37
  }
84
38
  };
85
- var fromAuth = (auth) => {
86
- switch (auth.type) {
87
- case "password":
88
- return {
89
- identityProviderId: auth.identityProviderId,
90
- type: auth.type,
91
- issuer: auth.issuer,
92
- configUrl: auth.configUrl,
93
- audience: auth.audience,
94
- tokenUrl: auth.tokenUrl,
95
- grantType: auth.grantType,
96
- scope: auth.scope,
97
- clientId: auth.clientId,
98
- clientSecret: "",
99
- adminClientId: auth.admin?.clientId || "",
100
- adminClientSecret: auth.admin?.clientSecret || ""
101
- };
102
- case "implicit":
39
+ var fromIdp = (idp) => {
40
+ switch (idp.type) {
41
+ case "oauth":
103
42
  return {
104
- identityProviderId: auth.identityProviderId,
105
- type: auth.type,
106
- issuer: auth.issuer,
107
- configUrl: auth.configUrl,
108
- audience: auth.audience,
109
- tokenUrl: "",
110
- grantType: "",
111
- scope: auth.scope,
112
- clientId: auth.clientId,
113
- clientSecret: "",
114
- adminClientId: auth.admin?.clientId || "",
115
- adminClientSecret: auth.admin?.clientSecret || ""
116
- };
117
- case "client_credentials":
118
- return {
119
- identityProviderId: auth.identityProviderId,
120
- type: auth.type,
121
- issuer: auth.issuer,
122
- configUrl: auth.configUrl,
123
- audience: auth.audience,
124
- tokenUrl: "",
125
- grantType: "",
126
- scope: auth.scope,
127
- clientId: auth.clientId,
128
- clientSecret: auth.clientSecret,
129
- adminClientId: auth.admin?.clientId || "",
130
- adminClientSecret: auth.admin?.clientSecret || ""
43
+ id: idp.id,
44
+ type: idp.type,
45
+ issuer: idp.issuer,
46
+ configUrl: idp.configUrl
131
47
  };
132
48
  case "self_signed":
133
49
  return {
134
- identityProviderId: auth.identityProviderId,
135
- type: auth.type,
136
- issuer: auth.issuer,
137
- configUrl: "",
138
- audience: auth.audience,
139
- tokenUrl: "",
140
- grantType: "",
141
- scope: auth.scope,
142
- clientId: auth.clientId,
143
- clientSecret: auth.clientSecret,
144
- adminClientId: auth.admin?.clientId || "",
145
- adminClientSecret: auth.admin?.clientSecret || ""
50
+ id: idp.id,
51
+ type: idp.type,
52
+ issuer: idp.issuer,
53
+ configUrl: void 0
146
54
  };
147
55
  }
148
56
  };
149
- var toNetwork = (table, authTable) => {
150
- if (!authTable) {
151
- throw new Error(`Missing auth table for network: ${table.name}`);
152
- }
57
+ var toNetwork = (table) => {
153
58
  return {
154
59
  name: table.name,
155
- chainId: table.chainId,
60
+ id: table.id,
156
61
  synchronizerId: table.synchronizerId,
62
+ identityProviderId: table.identityProviderId,
157
63
  description: table.description,
158
64
  ledgerApi: {
159
65
  baseUrl: table.ledgerApiBaseUrl
160
66
  },
161
- auth: toAuth(authTable)
67
+ auth: coreWalletAuth.authSchema.parse(JSON.parse(table.auth)),
68
+ adminAuth: table.adminAuth ? coreWalletAuth.authSchema.parse(JSON.parse(table.adminAuth)) : void 0
162
69
  };
163
70
  };
164
71
  var fromNetwork = (network, userId) => {
165
72
  return {
166
73
  name: network.name,
167
- chainId: network.chainId,
74
+ id: network.id,
168
75
  synchronizerId: network.synchronizerId,
169
76
  description: network.description,
170
77
  ledgerApiBaseUrl: network.ledgerApi.baseUrl,
171
78
  userId,
172
- identityProviderId: network.auth.identityProviderId
79
+ identityProviderId: network.identityProviderId,
80
+ auth: JSON.stringify(network.auth),
81
+ adminAuth: network.adminAuth ? JSON.stringify(network.adminAuth) : void 0
173
82
  };
174
83
  };
175
84
  var fromWallet = (wallet, userId) => {
@@ -218,15 +127,22 @@ var StoreSql = class _StoreSql {
218
127
  // Wallet methods
219
128
  async getWallets(filter = {}) {
220
129
  const userId = this.assertConnected();
221
- const { chainIds, signingProviderIds } = filter;
222
- const chainIdSet = chainIds ? new Set(chainIds) : null;
130
+ const { networkIds, signingProviderIds } = filter;
131
+ const networkIdSet = networkIds ? new Set(networkIds) : null;
223
132
  const signingProviderIdSet = signingProviderIds ? new Set(signingProviderIds) : null;
224
133
  const wallets = await this.db.selectFrom("wallets").selectAll().where("userId", "=", userId).execute();
225
134
  return wallets.filter((wallet) => {
226
- const matchedChainIds = chainIdSet ? chainIdSet.has(wallet.chainId) : true;
227
- const matchedStorageProviderIdS = signingProviderIdSet ? signingProviderIdSet.has(wallet.signingProviderId) : true;
228
- return matchedChainIds && matchedStorageProviderIdS;
229
- }).map((table) => toWallet(table));
135
+ const matchedNetworkIds = networkIdSet ? networkIdSet.has(wallet.networkId) : true;
136
+ const matchedSigningProviderIds = signingProviderIdSet ? signingProviderIdSet.has(wallet.signingProviderId) : true;
137
+ return matchedNetworkIds && matchedSigningProviderIds;
138
+ }).map(
139
+ (table) => toWallet({
140
+ ...table,
141
+ externalTxId: table.externalTxId ?? "",
142
+ topologyTransactions: table.topologyTransactions ?? "",
143
+ status: table.status ?? ""
144
+ })
145
+ );
230
146
  }
231
147
  async getPrimaryWallet() {
232
148
  const wallets = await this.getWallets();
@@ -269,29 +185,84 @@ var StoreSql = class _StoreSql {
269
185
  await trx.insertInto("wallets").values(fromWallet(wallet, userId)).execute();
270
186
  });
271
187
  }
188
+ async updateWallet({ status, partyId }) {
189
+ this.logger.info("Updating wallet");
190
+ await this.db.transaction().execute(async (trx) => {
191
+ await trx.updateTable("wallets").set({ status }).where("partyId", "=", partyId).execute();
192
+ });
193
+ }
194
+ async removeWallet(partyId) {
195
+ this.logger.info("Removing wallet");
196
+ await this.db.transaction().execute(async (trx) => {
197
+ await trx.deleteFrom("wallets").where("partyId", "=", partyId).execute();
198
+ });
199
+ }
272
200
  // Session methods
273
201
  async getSession() {
274
- const sessions = await this.db.selectFrom("sessions").selectAll().executeTakeFirst();
202
+ const userId = this.assertConnected();
203
+ const sessions = await this.db.selectFrom("sessions").selectAll().where("userId", "=", userId).executeTakeFirst();
275
204
  return sessions;
276
205
  }
277
206
  async setSession(session) {
278
207
  const userId = this.assertConnected();
279
208
  await this.db.transaction().execute(async (trx) => {
280
- await trx.deleteFrom("sessions").where("userId", "=", userId).execute();
281
- await trx.insertInto("sessions").values({ ...session, userId }).execute();
209
+ const deleted = await trx.deleteFrom("sessions").where("userId", "=", userId).execute();
210
+ this.logger.debug(deleted, "Deleted old session");
211
+ const inserted = await trx.insertInto("sessions").values({ ...session, userId }).execute();
212
+ this.logger.debug(inserted, "Inserted new session");
282
213
  });
283
214
  }
284
215
  async removeSession() {
285
216
  const userId = this.assertConnected();
286
217
  await this.db.deleteFrom("sessions").where("userId", "=", userId).execute();
287
218
  }
219
+ // IDP methods
220
+ async getIdp(idpId) {
221
+ this.assertConnected();
222
+ const idps = await this.listIdps();
223
+ if (!idps) throw new Error("No IDPs available");
224
+ const idp = idps.find((n) => n.id === idpId);
225
+ if (!idp) throw new Error(`IDP "${idpId}" not found`);
226
+ return idp;
227
+ }
228
+ async listIdps() {
229
+ const query = this.db.selectFrom("idps").selectAll();
230
+ const idps = await query.execute();
231
+ return idps.map((table) => toIdp(table));
232
+ }
233
+ async updateIdp(idp) {
234
+ await this.db.transaction().execute(async (trx) => {
235
+ const idpEntry = fromIdp(idp);
236
+ this.logger.info(idpEntry, "Updating idp table");
237
+ await trx.updateTable("idps").set(idpEntry).where("id", "=", idp.id).execute();
238
+ });
239
+ }
240
+ async addIdp(idp) {
241
+ await this.db.transaction().execute(async (trx) => {
242
+ const idpAlreadyExists = await trx.selectFrom("idps").selectAll().where("id", "=", idp.id).executeTakeFirst();
243
+ if (idpAlreadyExists) {
244
+ throw new Error(`IDP ${idp.id} already exists`);
245
+ } else {
246
+ await trx.insertInto("idps").values(fromIdp(idp)).execute();
247
+ }
248
+ });
249
+ }
250
+ async removeIdp(idpId) {
251
+ await this.db.transaction().execute(async (trx) => {
252
+ const idp = await trx.selectFrom("idps").selectAll().where("id", "=", idpId).executeTakeFirst();
253
+ if (!idp) {
254
+ throw new Error(`IDP ${idpId} does not exists`);
255
+ }
256
+ await trx.deleteFrom("idps").where("id", "=", idpId).execute();
257
+ });
258
+ }
288
259
  // Network methods
289
- async getNetwork(chainId) {
260
+ async getNetwork(networkId) {
290
261
  this.assertConnected();
291
262
  const networks = await this.listNetworks();
292
263
  if (!networks) throw new Error("No networks available");
293
- const network = networks.find((n) => n.chainId === chainId);
294
- if (!network) throw new Error(`Network "${chainId}" not found`);
264
+ const network = networks.find((n) => n.id === networkId);
265
+ if (!network) throw new Error(`Network "${networkId}" not found`);
295
266
  return network;
296
267
  }
297
268
  async getCurrentNetwork() {
@@ -299,14 +270,14 @@ var StoreSql = class _StoreSql {
299
270
  if (!session) {
300
271
  throw new Error("No session found");
301
272
  }
302
- const chainId = session.network;
303
- if (!chainId) {
273
+ const networkId = session.network;
274
+ if (!networkId) {
304
275
  throw new Error("No current network set in session");
305
276
  }
306
277
  const networks = await this.listNetworks();
307
- const network = networks.find((n) => n.chainId === chainId);
278
+ const network = networks.find((n) => n.id === networkId);
308
279
  if (!network) {
309
- throw new Error(`Network "${chainId}" not found`);
280
+ throw new Error(`Network "${networkId}" not found`);
310
281
  }
311
282
  return network;
312
283
  }
@@ -326,53 +297,49 @@ var StoreSql = class _StoreSql {
326
297
  query = query.where("userId", "is", null);
327
298
  }
328
299
  const networks = await query.execute();
329
- const idps = await this.db.selectFrom("idps").selectAll().execute();
330
- const idpMap = new Map(idps.map((idp) => [idp.identityProviderId, idp]));
331
- return networks.map(
332
- (table) => toNetwork(table, idpMap.get(table.identityProviderId))
333
- );
300
+ return networks.map((table) => toNetwork(table));
334
301
  }
335
302
  async updateNetwork(network) {
336
- const userId = this.assertConnected();
303
+ this.assertConnected();
337
304
  await this.db.transaction().execute(async (trx) => {
338
- const networkEntry = fromNetwork(network, userId);
305
+ const networkEntry = fromNetwork(network, void 0);
339
306
  this.logger.info(networkEntry, "Updating network table");
340
- await trx.updateTable("networks").set(networkEntry).where("chainId", "=", network.chainId).execute();
341
- const authEntry = fromAuth(network.auth);
342
- this.logger.info(authEntry, "Updating auth table");
343
- await trx.updateTable("idps").set(authEntry).where(
344
- "identityProviderId",
345
- "=",
346
- network.auth.identityProviderId
347
- ).execute();
307
+ await trx.updateTable("networks").set(networkEntry).where("id", "=", network.id).execute();
348
308
  });
349
309
  }
350
310
  async addNetwork(network) {
351
311
  const userId = this.authContext?.userId;
312
+ const idps = await this.listIdps();
313
+ const networkIdp = idps.find(
314
+ (idp) => idp.id === network.identityProviderId
315
+ );
316
+ if (!networkIdp) {
317
+ throw new Error(
318
+ `Identity provider "${network.identityProviderId}" not found`
319
+ );
320
+ }
352
321
  await this.db.transaction().execute(async (trx) => {
353
- const networkAlreadyExists = await trx.selectFrom("networks").selectAll().where("chainId", "=", network.chainId).executeTakeFirst();
322
+ const networkAlreadyExists = await trx.selectFrom("networks").selectAll().where("id", "=", network.id).executeTakeFirst();
354
323
  if (networkAlreadyExists) {
355
- throw new Error(`Network ${network.chainId} already exists`);
324
+ throw new Error(`Network ${network.id} already exists`);
356
325
  } else {
357
- await trx.insertInto("idps").values(fromAuth(network.auth)).execute();
358
326
  await trx.insertInto("networks").values(fromNetwork(network, userId)).execute();
359
327
  }
360
328
  });
361
329
  }
362
- async removeNetwork(chainId) {
330
+ async removeNetwork(networkId) {
363
331
  const userId = this.assertConnected();
364
332
  await this.db.transaction().execute(async (trx) => {
365
- const network = await trx.selectFrom("networks").selectAll().where("chainId", "=", chainId).executeTakeFirst();
333
+ const network = await trx.selectFrom("networks").selectAll().where("id", "=", networkId).executeTakeFirst();
366
334
  if (!network) {
367
- throw new Error(`Network ${chainId} does not exists`);
335
+ throw new Error(`Network ${networkId} does not exists`);
368
336
  }
369
337
  if (network.userId !== userId) {
370
338
  throw new Error(
371
- `Network ${chainId} is not owned by user ${userId}`
339
+ `Network ${networkId} is not owned by user ${userId}`
372
340
  );
373
341
  }
374
- await trx.deleteFrom("networks").where("chainId", "=", chainId).execute();
375
- await trx.deleteFrom("idps").where("identityProviderId", "=", network.identityProviderId).execute();
342
+ await trx.deleteFrom("networks").where("id", "=", networkId).execute();
376
343
  });
377
344
  }
378
345
  // Transaction methods
@@ -469,6 +436,7 @@ var migrator = (db) => {
469
436
  // src/bootstrap.ts
470
437
  async function bootstrap(db, config, logger2) {
471
438
  const store = new StoreSql(db, logger2);
439
+ await Promise.all(config.idps.map((idp) => store.addIdp(idp)));
472
440
  await Promise.all(
473
441
  config.networks.map((network) => store.addNetwork(network))
474
442
  );
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/schema.ts","../src/store-sql.ts","../src/migrator.ts","../src/bootstrap.ts","../src/cli.ts"],"names":["logger","assertConnected","Kysely","SqliteDialect","Database","CamelCasePlugin","Umzug","pino","Command"],"mappings":"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","file":"index.cjs","sourcesContent":["// Copyright (c) 2025 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Auth, UserId } from '@canton-network/core-wallet-auth'\nimport {\n Wallet,\n Transaction,\n Session,\n Network,\n} from '@canton-network/core-wallet-store'\n\ninterface MigrationTable {\n name: string\n executedAt: string\n}\n\ninterface IdpTable {\n identityProviderId: string\n type: string\n issuer: string\n configUrl: string\n audience: string\n tokenUrl: string\n grantType: string\n scope: string\n clientId: string\n clientSecret: string\n adminClientId: string\n adminClientSecret: string\n}\n\ninterface NetworkTable {\n name: string\n chainId: string\n synchronizerId: string\n description: string\n ledgerApiBaseUrl: string\n userId: UserId | undefined // global if undefined\n identityProviderId: string\n}\n\ninterface WalletTable {\n primary: number\n partyId: string\n hint: string\n publicKey: string\n namespace: string\n chainId: string\n signingProviderId: string\n userId: UserId\n}\n\ninterface TransactionTable {\n status: string\n commandId: string\n preparedTransaction: string\n preparedTransactionHash: string\n payload: string | undefined\n userId: UserId\n}\n\ninterface SessionTable extends Session {\n userId: UserId\n}\n\nexport interface DB {\n migrations: MigrationTable\n idps: IdpTable\n networks: NetworkTable\n wallets: WalletTable\n transactions: TransactionTable\n sessions: SessionTable\n}\n\nexport const toAuth = (table: IdpTable): Auth => {\n switch (table.type) {\n case 'password':\n return {\n identityProviderId: table.identityProviderId,\n type: table.type,\n issuer: table.issuer,\n configUrl: table.configUrl,\n audience: table.audience,\n tokenUrl: table.tokenUrl || '',\n grantType: table.grantType || '',\n scope: table.scope,\n clientId: table.clientId,\n admin: {\n clientId: table.adminClientId,\n clientSecret: table.adminClientSecret,\n },\n }\n case 'implicit':\n return {\n identityProviderId: table.identityProviderId,\n type: table.type,\n issuer: table.issuer,\n configUrl: table.configUrl,\n audience: table.audience,\n scope: table.scope,\n clientId: table.clientId,\n admin: {\n clientId: table.adminClientId,\n clientSecret: table.adminClientSecret,\n },\n }\n case 'client_credentials':\n return {\n identityProviderId: table.identityProviderId,\n type: table.type,\n issuer: table.issuer,\n configUrl: table.configUrl,\n audience: table.audience,\n scope: table.scope,\n clientId: table.clientId,\n clientSecret: table.clientSecret,\n admin: {\n clientId: table.adminClientId,\n clientSecret: table.adminClientSecret,\n },\n }\n case 'self_signed':\n return {\n identityProviderId: table.identityProviderId,\n type: table.type,\n issuer: table.issuer,\n audience: table.audience,\n scope: table.scope,\n clientId: table.clientId,\n clientSecret: table.clientSecret,\n admin: {\n clientId: table.adminClientId,\n clientSecret: table.adminClientSecret,\n },\n }\n default:\n throw new Error(`Unknown auth type: ${table.type}`)\n }\n}\n\nexport const fromAuth = (auth: Auth): IdpTable => {\n switch (auth.type) {\n case 'password':\n return {\n identityProviderId: auth.identityProviderId,\n type: auth.type,\n issuer: auth.issuer,\n configUrl: auth.configUrl,\n audience: auth.audience,\n tokenUrl: auth.tokenUrl,\n grantType: auth.grantType,\n scope: auth.scope,\n clientId: auth.clientId,\n clientSecret: '',\n adminClientId: auth.admin?.clientId || '',\n adminClientSecret: auth.admin?.clientSecret || '',\n }\n case 'implicit':\n return {\n identityProviderId: auth.identityProviderId,\n type: auth.type,\n issuer: auth.issuer,\n configUrl: auth.configUrl,\n audience: auth.audience,\n tokenUrl: '',\n grantType: '',\n scope: auth.scope,\n clientId: auth.clientId,\n clientSecret: '',\n adminClientId: auth.admin?.clientId || '',\n adminClientSecret: auth.admin?.clientSecret || '',\n }\n case 'client_credentials':\n return {\n identityProviderId: auth.identityProviderId,\n type: auth.type,\n issuer: auth.issuer,\n configUrl: auth.configUrl,\n audience: auth.audience,\n tokenUrl: '',\n grantType: '',\n scope: auth.scope,\n clientId: auth.clientId,\n clientSecret: auth.clientSecret,\n adminClientId: auth.admin?.clientId || '',\n adminClientSecret: auth.admin?.clientSecret || '',\n }\n case 'self_signed':\n return {\n identityProviderId: auth.identityProviderId,\n type: auth.type,\n issuer: auth.issuer,\n configUrl: '',\n audience: auth.audience,\n tokenUrl: '',\n grantType: '',\n scope: auth.scope,\n clientId: auth.clientId,\n clientSecret: auth.clientSecret,\n adminClientId: auth.admin?.clientId || '',\n adminClientSecret: auth.admin?.clientSecret || '',\n }\n }\n}\n\nexport const toNetwork = (\n table: NetworkTable,\n authTable?: IdpTable\n): Network => {\n if (!authTable) {\n throw new Error(`Missing auth table for network: ${table.name}`)\n }\n return {\n name: table.name,\n chainId: table.chainId,\n synchronizerId: table.synchronizerId,\n description: table.description,\n ledgerApi: {\n baseUrl: table.ledgerApiBaseUrl,\n },\n auth: toAuth(authTable),\n }\n}\n\nexport const fromNetwork = (\n network: Network,\n userId?: UserId\n): NetworkTable => {\n return {\n name: network.name,\n chainId: network.chainId,\n synchronizerId: network.synchronizerId,\n description: network.description,\n ledgerApiBaseUrl: network.ledgerApi.baseUrl,\n userId: userId,\n identityProviderId: network.auth.identityProviderId,\n }\n}\n\nexport const fromWallet = (wallet: Wallet, userId: UserId): WalletTable => {\n return {\n ...wallet,\n primary: wallet.primary ? 1 : 0,\n userId: userId,\n }\n}\n\nexport const toWallet = (table: WalletTable): Wallet => {\n return {\n ...table,\n primary: table.primary === 1,\n }\n}\n\nexport const fromTransaction = (\n transaction: Transaction,\n userId: UserId\n): TransactionTable => {\n return {\n ...transaction,\n payload: transaction.payload\n ? JSON.stringify(transaction.payload)\n : undefined,\n userId: userId,\n }\n}\n\nexport const toTransaction = (table: TransactionTable): Transaction => {\n return {\n ...table,\n status: table.status as 'pending' | 'signed' | 'executed' | 'failed',\n payload: table.payload ? JSON.parse(table.payload) : undefined,\n }\n}\n","// Copyright (c) 2025 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Logger } from 'pino'\nimport {\n AuthContext,\n UserId,\n AuthAware,\n assertConnected,\n} from '@canton-network/core-wallet-auth'\nimport {\n Store as BaseStore,\n Wallet,\n PartyId,\n Session,\n WalletFilter,\n Transaction,\n Network,\n StoreConfig,\n} from '@canton-network/core-wallet-store'\nimport { CamelCasePlugin, Kysely, SqliteDialect } from 'kysely'\nimport Database from 'better-sqlite3'\nimport {\n DB,\n fromAuth,\n fromNetwork,\n fromTransaction,\n fromWallet,\n toNetwork,\n toTransaction,\n toWallet,\n} from './schema.js'\n\nexport class StoreSql implements BaseStore, AuthAware<StoreSql> {\n authContext: AuthContext | undefined\n\n constructor(\n private db: Kysely<DB>,\n private logger: Logger,\n authContext?: AuthContext\n ) {\n this.logger = logger.child({ component: 'StoreSql' })\n this.authContext = authContext\n\n // this.syncWallets()\n }\n\n withAuthContext(context?: AuthContext): StoreSql {\n return new StoreSql(this.db, this.logger, context)\n }\n\n private assertConnected(): UserId {\n return assertConnected(this.authContext).userId\n }\n\n // Wallet methods\n\n async getWallets(filter: WalletFilter = {}): Promise<Array<Wallet>> {\n const userId = this.assertConnected()\n const { chainIds, signingProviderIds } = filter\n const chainIdSet = chainIds ? new Set(chainIds) : null\n const signingProviderIdSet = signingProviderIds\n ? new Set(signingProviderIds)\n : null\n\n const wallets = await this.db\n .selectFrom('wallets')\n .selectAll()\n .where('userId', '=', userId)\n .execute()\n\n return wallets\n .filter((wallet) => {\n const matchedChainIds = chainIdSet\n ? chainIdSet.has(wallet.chainId)\n : true\n const matchedStorageProviderIdS = signingProviderIdSet\n ? signingProviderIdSet.has(wallet.signingProviderId)\n : true\n return matchedChainIds && matchedStorageProviderIdS\n })\n .map((table) => toWallet(table))\n }\n\n async getPrimaryWallet(): Promise<Wallet | undefined> {\n const wallets = await this.getWallets()\n return wallets.find((w) => w.primary === true)\n }\n\n async setPrimaryWallet(partyId: PartyId): Promise<void> {\n const wallets = await this.getWallets()\n if (!wallets.some((w) => w.partyId === partyId)) {\n throw new Error(`Wallet with partyId \"${partyId}\" not found`)\n }\n\n const primary = wallets.find((w) => w.primary === true)\n\n await this.db.transaction().execute(async (trx) => {\n if (primary) {\n await trx\n .updateTable('wallets')\n .set({ primary: 0 })\n .where('partyId', '=', primary.partyId)\n .execute()\n }\n await trx\n .updateTable('wallets')\n .set({ primary: 1 })\n .where('partyId', '=', partyId)\n .execute()\n })\n }\n\n async addWallet(wallet: Wallet): Promise<void> {\n this.logger.info('Adding wallet')\n const userId = this.assertConnected()\n\n const wallets = await this.getWallets()\n if (wallets.some((w) => w.partyId === wallet.partyId)) {\n throw new Error(\n `Wallet with partyId \"${wallet.partyId}\" already exists`\n )\n }\n\n if (wallets.length === 0) {\n // If this is the first wallet, set it as primary automatically\n wallet.primary = true\n }\n\n await this.db.transaction().execute(async (trx) => {\n if (wallet.primary) {\n // If the new wallet is primary, set all others to non-primary\n await trx\n .updateTable('wallets')\n .set({ primary: 0 })\n .where((eb) =>\n eb.and([\n eb('primary', '=', 1),\n eb('userId', '=', userId),\n ])\n )\n .execute()\n }\n await trx\n .insertInto('wallets')\n .values(fromWallet(wallet, userId))\n .execute()\n })\n }\n\n // Session methods\n async getSession(): Promise<Session | undefined> {\n const sessions = await this.db\n .selectFrom('sessions')\n .selectAll()\n .executeTakeFirst()\n return sessions\n }\n\n async setSession(session: Session): Promise<void> {\n const userId = this.assertConnected()\n await this.db.transaction().execute(async (trx) => {\n await trx\n .deleteFrom('sessions')\n .where('userId', '=', userId)\n .execute()\n await trx\n .insertInto('sessions')\n .values({ ...session, userId })\n .execute()\n })\n }\n\n async removeSession(): Promise<void> {\n const userId = this.assertConnected()\n await this.db\n .deleteFrom('sessions')\n .where('userId', '=', userId)\n .execute()\n }\n\n // Network methods\n async getNetwork(chainId: string): Promise<Network> {\n this.assertConnected()\n\n const networks = await this.listNetworks()\n if (!networks) throw new Error('No networks available')\n\n const network = networks.find((n) => n.chainId === chainId)\n if (!network) throw new Error(`Network \"${chainId}\" not found`)\n return network\n }\n\n async getCurrentNetwork(): Promise<Network> {\n const session = await this.getSession()\n if (!session) {\n throw new Error('No session found')\n }\n const chainId = session.network\n if (!chainId) {\n throw new Error('No current network set in session')\n }\n\n const networks = await this.listNetworks()\n const network = networks.find((n) => n.chainId === chainId)\n if (!network) {\n throw new Error(`Network \"${chainId}\" not found`)\n }\n return network\n }\n\n async listNetworks(): Promise<Array<Network>> {\n let query = this.db.selectFrom('networks').selectAll()\n\n if (this.authContext) {\n const userId = this.assertConnected()\n query = query.where((eb) =>\n eb.or([\n eb('userId', 'is', null), // Global networks\n eb('userId', '=', userId), // User-specific networks\n ])\n )\n } else {\n query = query.where('userId', 'is', null) // Only global networks\n }\n\n const networks = await query.execute()\n const idps = await this.db.selectFrom('idps').selectAll().execute()\n const idpMap = new Map(idps.map((idp) => [idp.identityProviderId, idp]))\n return networks.map((table) =>\n toNetwork(table, idpMap.get(table.identityProviderId))\n )\n }\n\n async updateNetwork(network: Network): Promise<void> {\n const userId = this.assertConnected()\n // todo: check and compare userid of existing network\n await this.db.transaction().execute(async (trx) => {\n const networkEntry = fromNetwork(network, userId)\n this.logger.info(networkEntry, 'Updating network table')\n await trx\n .updateTable('networks')\n .set(networkEntry)\n .where('chainId', '=', network.chainId)\n .execute()\n\n const authEntry = fromAuth(network.auth)\n this.logger.info(authEntry, 'Updating auth table')\n await trx\n .updateTable('idps')\n .set(authEntry)\n .where(\n 'identityProviderId',\n '=',\n network.auth.identityProviderId\n )\n .execute()\n })\n }\n\n async addNetwork(network: Network): Promise<void> {\n const userId = this.authContext?.userId\n await this.db.transaction().execute(async (trx) => {\n const networkAlreadyExists = await trx\n .selectFrom('networks')\n .selectAll()\n .where('chainId', '=', network.chainId)\n .executeTakeFirst()\n if (networkAlreadyExists) {\n throw new Error(`Network ${network.chainId} already exists`)\n } else {\n await trx\n .insertInto('idps')\n .values(fromAuth(network.auth))\n .execute()\n await trx\n .insertInto('networks')\n .values(fromNetwork(network, userId))\n .execute()\n }\n })\n }\n\n async removeNetwork(chainId: string): Promise<void> {\n const userId = this.assertConnected()\n await this.db.transaction().execute(async (trx) => {\n const network = await trx\n .selectFrom('networks')\n .selectAll()\n .where('chainId', '=', chainId)\n .executeTakeFirst()\n if (!network) {\n throw new Error(`Network ${chainId} does not exists`)\n }\n if (network.userId !== userId) {\n throw new Error(\n `Network ${chainId} is not owned by user ${userId}`\n )\n }\n await trx\n .deleteFrom('networks')\n .where('chainId', '=', chainId)\n .execute()\n await trx\n .deleteFrom('idps')\n .where('identityProviderId', '=', network.identityProviderId)\n .execute()\n })\n }\n\n // Transaction methods\n async setTransaction(transaction: Transaction): Promise<void> {\n const userId = this.assertConnected()\n\n const existing = await this.getTransaction(transaction.commandId)\n if (existing) {\n await this.db\n .updateTable('transactions')\n .set(fromTransaction(transaction, userId))\n .where('commandId', '=', transaction.commandId)\n .execute()\n } else {\n await this.db\n .insertInto('transactions')\n .values(fromTransaction(transaction, userId))\n .execute()\n }\n }\n\n async getTransaction(commandId: string): Promise<Transaction | undefined> {\n const userId = this.assertConnected()\n const transaction = await this.db\n .selectFrom('transactions')\n .selectAll()\n .where((eb) =>\n eb.and([\n eb('commandId', '=', commandId),\n eb('userId', '=', userId),\n ])\n )\n .executeTakeFirst()\n return transaction ? toTransaction(transaction) : undefined\n }\n}\n\nexport const connection = (config: StoreConfig) => {\n switch (config.connection.type) {\n case 'sqlite':\n return new Kysely<DB>({\n dialect: new SqliteDialect({\n database: new Database(config.connection.database),\n }),\n plugins: [new CamelCasePlugin()],\n })\n case 'memory':\n return new Kysely<DB>({\n dialect: new SqliteDialect({\n database: new Database(':memory:'),\n }),\n plugins: [new CamelCasePlugin()],\n })\n default:\n throw new Error(\n `Unsupported database type: ${config.connection.type}`\n )\n }\n}\n","// Copyright (c) 2025 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Umzug, MigrationMeta, UmzugStorage } from 'umzug'\nimport { Kysely } from 'kysely'\nimport { DB } from './schema'\n\nclass KyselyStorage implements UmzugStorage {\n constructor(private db: Kysely<DB>) {}\n\n private async ensureTable() {\n await this.db.schema\n .createTable('migrations')\n .ifNotExists()\n .addColumn('name', 'text', (col) => col.primaryKey())\n .addColumn('executedAt', 'text', (col) => col.notNull())\n .execute()\n }\n\n async executed(): Promise<string[]> {\n await this.ensureTable()\n const rows = await this.db\n .selectFrom('migrations')\n .select('name')\n .execute()\n return rows.map((r) => r.name)\n }\n\n async logMigration({ name }: MigrationMeta): Promise<void> {\n await this.ensureTable()\n await this.db\n .insertInto('migrations')\n .values({ name, executedAt: new Date().toISOString() })\n .execute()\n }\n\n async unlogMigration({ name }: MigrationMeta): Promise<void> {\n await this.ensureTable()\n await this.db\n .deleteFrom('migrations')\n .where('name', '=', name)\n .execute()\n }\n}\n\nexport const migrator = (db: Kysely<DB>) => {\n const ext = import.meta.url.endsWith('.ts') ? 'ts' : 'js'\n const glob = new URL(`./migrations/*.${ext}`, import.meta.url).pathname\n return new Umzug({\n migrations: {\n glob: glob,\n resolve: ({ name, path, context }) => {\n // Dynamic import for ESM\n return {\n name,\n up: async () => {\n console.log(path)\n const { up } = await import(path!)\n return up(context)\n },\n down: async () => {\n const { down } = await import(path!)\n return down(context)\n },\n }\n },\n },\n context: db,\n storage: new KyselyStorage(db),\n logger: console,\n })\n}\n","// Copyright (c) 2025 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Kysely } from 'kysely'\nimport { StoreSql } from './store-sql.js'\nimport { StoreConfig } from '@canton-network/core-wallet-store'\nimport { Logger } from 'pino'\nimport { DB } from './schema'\n\nexport async function bootstrap(\n db: Kysely<DB>,\n config: StoreConfig,\n logger: Logger\n): Promise<void> {\n const store = new StoreSql(db, logger)\n await Promise.all(\n config.networks.map((network) => store.addNetwork(network))\n )\n}\n","// Copyright (c) 2025 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Command } from 'commander'\nimport { connection } from './store-sql.js'\nimport { migrator } from './migrator.js'\nimport type { StoreConfig } from '@canton-network/core-wallet-store'\nimport { pino } from 'pino'\nimport { bootstrap } from './bootstrap.js'\n\nconst logger = pino({ name: 'main', level: 'debug' })\n\nexport function createCLI(config: StoreConfig): Command {\n const program = new Command()\n\n program\n .command('up')\n .description('Run all pending migrations')\n .action(async () => {\n const db = connection(config)\n const umzug = migrator(db)\n await umzug.up()\n await db.destroy()\n })\n\n program\n .command('down')\n .description('Rollback last migration')\n .action(async () => {\n const db = connection(config)\n const umzug = migrator(db)\n await umzug.down()\n await db.destroy()\n })\n\n program\n .command('status')\n .description('Show executed and pending migrations')\n .action(async () => {\n const db = connection(config)\n const umzug = migrator(db)\n const executed = await umzug.executed()\n const pending = await umzug.pending()\n\n console.log('Executed migrations:', executed)\n console.log('Pending migrations:', pending)\n\n await db.destroy()\n })\n\n program\n .command('reset')\n .description('Rollback all migrations and reapply them')\n .action(async () => {\n const db = connection(config)\n const umzug = migrator(db)\n const executed = await umzug.executed()\n\n // Rollback all executed migrations in reverse order\n for (const migration of executed.reverse()) {\n await umzug.down({ to: migration.name })\n }\n\n // Reapply all migrations\n await umzug.up()\n await db.destroy()\n })\n\n program\n .command('bootstrap')\n .description('Bootstrap DB from config')\n .action(async () => {\n const db = connection(config)\n await bootstrap(db, config, logger)\n await db.destroy()\n })\n\n return program\n}\n"]}
1
+ {"version":3,"sources":["../src/schema.ts","../src/store-sql.ts","../src/migrator.ts","../src/bootstrap.ts","../src/cli.ts"],"names":["authSchema","logger","assertConnected","Kysely","SqliteDialect","Database","CamelCasePlugin","Umzug","pino","Command"],"mappings":"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","file":"index.cjs","sourcesContent":["// Copyright (c) 2025 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { authSchema, Idp, UserId } from '@canton-network/core-wallet-auth'\nimport {\n Wallet,\n Transaction,\n Session,\n Network,\n} from '@canton-network/core-wallet-store'\n\ninterface MigrationTable {\n name: string\n executedAt: string\n}\n\ninterface IdpTable {\n id: string\n type: 'oauth' | 'self_signed'\n issuer: string\n configUrl: string | undefined\n}\n\ninterface NetworkTable {\n id: string\n name: string\n synchronizerId: string\n description: string\n ledgerApiBaseUrl: string\n identityProviderId: string\n userId: UserId | undefined // global if undefined\n\n auth: string // json stringified\n adminAuth: string | undefined // json stringified\n}\n\ninterface WalletTable {\n primary: number\n partyId: string\n hint: string\n publicKey: string\n namespace: string\n networkId: string\n signingProviderId: string\n userId: UserId\n externalTxId?: string\n topologyTransactions?: string\n status?: string\n}\n\ninterface TransactionTable {\n status: string\n commandId: string\n preparedTransaction: string\n preparedTransactionHash: string\n payload: string | undefined\n userId: UserId\n}\n\ninterface SessionTable extends Session {\n userId: UserId\n}\n\nexport interface DB {\n migrations: MigrationTable\n idps: IdpTable\n networks: NetworkTable\n wallets: WalletTable\n transactions: TransactionTable\n sessions: SessionTable\n}\n\nexport const toIdp = (table: IdpTable): Idp => {\n switch (table.type) {\n case 'oauth': {\n if (!table.configUrl) {\n throw new Error(`Missing configUrl for oauth IdP: ${table.id}`)\n }\n\n return {\n id: table.id,\n type: table.type,\n issuer: table.issuer,\n configUrl: table.configUrl,\n }\n }\n case 'self_signed':\n return {\n id: table.id,\n type: table.type,\n issuer: table.issuer,\n }\n }\n}\n\nexport const fromIdp = (idp: Idp): IdpTable => {\n switch (idp.type) {\n case 'oauth':\n return {\n id: idp.id,\n type: idp.type,\n issuer: idp.issuer,\n configUrl: idp.configUrl,\n }\n case 'self_signed':\n return {\n id: idp.id,\n type: idp.type,\n issuer: idp.issuer,\n configUrl: undefined,\n }\n }\n}\n\nexport const toNetwork = (table: NetworkTable): Network => {\n return {\n name: table.name,\n id: table.id,\n synchronizerId: table.synchronizerId,\n identityProviderId: table.identityProviderId,\n description: table.description,\n ledgerApi: {\n baseUrl: table.ledgerApiBaseUrl,\n },\n auth: authSchema.parse(JSON.parse(table.auth)),\n adminAuth: table.adminAuth\n ? authSchema.parse(JSON.parse(table.adminAuth))\n : undefined,\n }\n}\n\nexport const fromNetwork = (\n network: Network,\n userId?: UserId\n): NetworkTable => {\n return {\n name: network.name,\n id: network.id,\n synchronizerId: network.synchronizerId,\n description: network.description,\n ledgerApiBaseUrl: network.ledgerApi.baseUrl,\n userId: userId,\n identityProviderId: network.identityProviderId,\n auth: JSON.stringify(network.auth),\n adminAuth: network.adminAuth\n ? JSON.stringify(network.adminAuth)\n : undefined,\n }\n}\n\nexport const fromWallet = (wallet: Wallet, userId: UserId): WalletTable => {\n return {\n ...wallet,\n primary: wallet.primary ? 1 : 0,\n userId: userId,\n }\n}\n\nexport const toWallet = (table: WalletTable): Wallet => {\n return {\n ...table,\n primary: table.primary === 1,\n }\n}\n\nexport const fromTransaction = (\n transaction: Transaction,\n userId: UserId\n): TransactionTable => {\n return {\n ...transaction,\n payload: transaction.payload\n ? JSON.stringify(transaction.payload)\n : undefined,\n userId: userId,\n }\n}\n\nexport const toTransaction = (table: TransactionTable): Transaction => {\n return {\n ...table,\n status: table.status as 'pending' | 'signed' | 'executed' | 'failed',\n payload: table.payload ? JSON.parse(table.payload) : undefined,\n }\n}\n","// Copyright (c) 2025 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Logger } from 'pino'\nimport {\n AuthContext,\n UserId,\n AuthAware,\n assertConnected,\n Idp,\n} from '@canton-network/core-wallet-auth'\nimport {\n Store as BaseStore,\n Wallet,\n PartyId,\n Session,\n WalletFilter,\n Transaction,\n Network,\n StoreConfig,\n UpdateWallet,\n} from '@canton-network/core-wallet-store'\nimport { CamelCasePlugin, Kysely, SqliteDialect } from 'kysely'\nimport Database from 'better-sqlite3'\nimport {\n DB,\n fromIdp,\n fromNetwork,\n fromTransaction,\n fromWallet,\n toIdp,\n toNetwork,\n toTransaction,\n toWallet,\n} from './schema.js'\n\nexport class StoreSql implements BaseStore, AuthAware<StoreSql> {\n authContext: AuthContext | undefined\n\n constructor(\n private db: Kysely<DB>,\n private logger: Logger,\n authContext?: AuthContext\n ) {\n this.logger = logger.child({ component: 'StoreSql' })\n this.authContext = authContext\n\n // this.syncWallets()\n }\n\n withAuthContext(context?: AuthContext): StoreSql {\n return new StoreSql(this.db, this.logger, context)\n }\n\n private assertConnected(): UserId {\n return assertConnected(this.authContext).userId\n }\n\n // Wallet methods\n\n async getWallets(filter: WalletFilter = {}): Promise<Array<Wallet>> {\n const userId = this.assertConnected()\n const { networkIds, signingProviderIds } = filter\n const networkIdSet = networkIds ? new Set(networkIds) : null\n const signingProviderIdSet = signingProviderIds\n ? new Set(signingProviderIds)\n : null\n\n const wallets = await this.db\n .selectFrom('wallets')\n .selectAll()\n .where('userId', '=', userId)\n .execute()\n\n return wallets\n .filter((wallet) => {\n const matchedNetworkIds = networkIdSet\n ? networkIdSet.has(wallet.networkId)\n : true\n const matchedSigningProviderIds = signingProviderIdSet\n ? signingProviderIdSet.has(wallet.signingProviderId)\n : true\n return matchedNetworkIds && matchedSigningProviderIds\n })\n .map((table) =>\n toWallet({\n ...table,\n externalTxId: table.externalTxId ?? '',\n topologyTransactions: table.topologyTransactions ?? '',\n status: table.status ?? '',\n })\n )\n }\n\n async getPrimaryWallet(): Promise<Wallet | undefined> {\n const wallets = await this.getWallets()\n return wallets.find((w) => w.primary === true)\n }\n\n async setPrimaryWallet(partyId: PartyId): Promise<void> {\n const wallets = await this.getWallets()\n if (!wallets.some((w) => w.partyId === partyId)) {\n throw new Error(`Wallet with partyId \"${partyId}\" not found`)\n }\n\n const primary = wallets.find((w) => w.primary === true)\n\n await this.db.transaction().execute(async (trx) => {\n if (primary) {\n await trx\n .updateTable('wallets')\n .set({ primary: 0 })\n .where('partyId', '=', primary.partyId)\n .execute()\n }\n await trx\n .updateTable('wallets')\n .set({ primary: 1 })\n .where('partyId', '=', partyId)\n .execute()\n })\n }\n\n async addWallet(wallet: Wallet): Promise<void> {\n this.logger.info('Adding wallet')\n const userId = this.assertConnected()\n\n const wallets = await this.getWallets()\n if (wallets.some((w) => w.partyId === wallet.partyId)) {\n throw new Error(\n `Wallet with partyId \"${wallet.partyId}\" already exists`\n )\n }\n\n if (wallets.length === 0) {\n // If this is the first wallet, set it as primary automatically\n wallet.primary = true\n }\n\n await this.db.transaction().execute(async (trx) => {\n if (wallet.primary) {\n // If the new wallet is primary, set all others to non-primary\n await trx\n .updateTable('wallets')\n .set({ primary: 0 })\n .where((eb) =>\n eb.and([\n eb('primary', '=', 1),\n eb('userId', '=', userId),\n ])\n )\n .execute()\n }\n await trx\n .insertInto('wallets')\n .values(fromWallet(wallet, userId))\n .execute()\n })\n }\n\n async updateWallet({ status, partyId }: UpdateWallet): Promise<void> {\n this.logger.info('Updating wallet')\n\n await this.db.transaction().execute(async (trx) => {\n await trx\n .updateTable('wallets')\n .set({ status })\n .where('partyId', '=', partyId)\n .execute()\n })\n }\n\n async removeWallet(partyId: PartyId): Promise<void> {\n this.logger.info('Removing wallet')\n\n await this.db.transaction().execute(async (trx) => {\n await trx\n .deleteFrom('wallets')\n .where('partyId', '=', partyId)\n .execute()\n })\n }\n\n // Session methods\n async getSession(): Promise<Session | undefined> {\n const userId = this.assertConnected()\n const sessions = await this.db\n .selectFrom('sessions')\n .selectAll()\n .where('userId', '=', userId)\n .executeTakeFirst()\n return sessions\n }\n\n async setSession(session: Session): Promise<void> {\n const userId = this.assertConnected()\n await this.db.transaction().execute(async (trx) => {\n const deleted = await trx\n .deleteFrom('sessions')\n .where('userId', '=', userId)\n .execute()\n this.logger.debug(deleted, 'Deleted old session')\n const inserted = await trx\n .insertInto('sessions')\n .values({ ...session, userId })\n .execute()\n this.logger.debug(inserted, 'Inserted new session')\n })\n }\n\n async removeSession(): Promise<void> {\n const userId = this.assertConnected()\n await this.db\n .deleteFrom('sessions')\n .where('userId', '=', userId)\n .execute()\n }\n\n // IDP methods\n\n async getIdp(idpId: string): Promise<Idp> {\n this.assertConnected()\n\n const idps = await this.listIdps()\n if (!idps) throw new Error('No IDPs available')\n\n const idp = idps.find((n) => n.id === idpId)\n if (!idp) throw new Error(`IDP \"${idpId}\" not found`)\n return idp\n }\n\n async listIdps(): Promise<Array<Idp>> {\n // All IDPs are global for now -- TO-DO: user-specific IDPs\n const query = this.db.selectFrom('idps').selectAll()\n\n const idps = await query.execute()\n return idps.map((table) => toIdp(table))\n }\n\n async updateIdp(idp: Idp): Promise<void> {\n // todo: check and compare userid of existing idp\n await this.db.transaction().execute(async (trx) => {\n const idpEntry = fromIdp(idp)\n this.logger.info(idpEntry, 'Updating idp table')\n await trx\n .updateTable('idps')\n .set(idpEntry)\n .where('id', '=', idp.id)\n .execute()\n })\n }\n\n async addIdp(idp: Idp): Promise<void> {\n await this.db.transaction().execute(async (trx) => {\n const idpAlreadyExists = await trx\n .selectFrom('idps')\n .selectAll()\n .where('id', '=', idp.id)\n .executeTakeFirst()\n if (idpAlreadyExists) {\n throw new Error(`IDP ${idp.id} already exists`)\n } else {\n await trx.insertInto('idps').values(fromIdp(idp)).execute()\n }\n })\n }\n\n async removeIdp(idpId: string): Promise<void> {\n await this.db.transaction().execute(async (trx) => {\n const idp = await trx\n .selectFrom('idps')\n .selectAll()\n .where('id', '=', idpId)\n .executeTakeFirst()\n if (!idp) {\n throw new Error(`IDP ${idpId} does not exists`)\n }\n await trx.deleteFrom('idps').where('id', '=', idpId).execute()\n })\n }\n\n // Network methods\n async getNetwork(networkId: string): Promise<Network> {\n this.assertConnected()\n\n const networks = await this.listNetworks()\n if (!networks) throw new Error('No networks available')\n\n const network = networks.find((n) => n.id === networkId)\n if (!network) throw new Error(`Network \"${networkId}\" not found`)\n return network\n }\n\n async getCurrentNetwork(): Promise<Network> {\n const session = await this.getSession()\n if (!session) {\n throw new Error('No session found')\n }\n const networkId = session.network\n if (!networkId) {\n throw new Error('No current network set in session')\n }\n\n const networks = await this.listNetworks()\n const network = networks.find((n) => n.id === networkId)\n if (!network) {\n throw new Error(`Network \"${networkId}\" not found`)\n }\n return network\n }\n\n async listNetworks(): Promise<Array<Network>> {\n let query = this.db.selectFrom('networks').selectAll()\n\n if (this.authContext) {\n const userId = this.assertConnected()\n query = query.where((eb) =>\n eb.or([\n eb('userId', 'is', null), // Global networks\n eb('userId', '=', userId), // User-specific networks\n ])\n )\n } else {\n query = query.where('userId', 'is', null) // Only global networks\n }\n\n const networks = await query.execute()\n return networks.map((table) => toNetwork(table))\n }\n\n async updateNetwork(network: Network): Promise<void> {\n // todo: check and compare idpId of existing network\n this.assertConnected()\n await this.db.transaction().execute(async (trx) => {\n // we do not set a userId for now and leave all networks global when updating\n const networkEntry = fromNetwork(network, undefined)\n this.logger.info(networkEntry, 'Updating network table')\n await trx\n .updateTable('networks')\n .set(networkEntry)\n .where('id', '=', network.id)\n .execute()\n })\n }\n\n async addNetwork(network: Network): Promise<void> {\n const userId = this.authContext?.userId\n const idps = await this.listIdps()\n const networkIdp = idps.find(\n (idp) => idp.id === network.identityProviderId\n )\n\n if (!networkIdp) {\n throw new Error(\n `Identity provider \"${network.identityProviderId}\" not found`\n )\n }\n\n await this.db.transaction().execute(async (trx) => {\n const networkAlreadyExists = await trx\n .selectFrom('networks')\n .selectAll()\n .where('id', '=', network.id)\n .executeTakeFirst()\n if (networkAlreadyExists) {\n throw new Error(`Network ${network.id} already exists`)\n } else {\n await trx\n .insertInto('networks')\n .values(fromNetwork(network, userId))\n .execute()\n }\n })\n }\n\n async removeNetwork(networkId: string): Promise<void> {\n const userId = this.assertConnected()\n await this.db.transaction().execute(async (trx) => {\n const network = await trx\n .selectFrom('networks')\n .selectAll()\n .where('id', '=', networkId)\n .executeTakeFirst()\n if (!network) {\n throw new Error(`Network ${networkId} does not exists`)\n }\n if (network.userId !== userId) {\n throw new Error(\n `Network ${networkId} is not owned by user ${userId}`\n )\n }\n await trx\n .deleteFrom('networks')\n .where('id', '=', networkId)\n .execute()\n })\n }\n\n // Transaction methods\n async setTransaction(transaction: Transaction): Promise<void> {\n const userId = this.assertConnected()\n\n const existing = await this.getTransaction(transaction.commandId)\n if (existing) {\n await this.db\n .updateTable('transactions')\n .set(fromTransaction(transaction, userId))\n .where('commandId', '=', transaction.commandId)\n .execute()\n } else {\n await this.db\n .insertInto('transactions')\n .values(fromTransaction(transaction, userId))\n .execute()\n }\n }\n\n async getTransaction(commandId: string): Promise<Transaction | undefined> {\n const userId = this.assertConnected()\n const transaction = await this.db\n .selectFrom('transactions')\n .selectAll()\n .where((eb) =>\n eb.and([\n eb('commandId', '=', commandId),\n eb('userId', '=', userId),\n ])\n )\n .executeTakeFirst()\n return transaction ? toTransaction(transaction) : undefined\n }\n}\n\nexport const connection = (config: StoreConfig) => {\n switch (config.connection.type) {\n case 'sqlite':\n return new Kysely<DB>({\n dialect: new SqliteDialect({\n database: new Database(config.connection.database),\n }),\n plugins: [new CamelCasePlugin()],\n })\n case 'memory':\n return new Kysely<DB>({\n dialect: new SqliteDialect({\n database: new Database(':memory:'),\n }),\n plugins: [new CamelCasePlugin()],\n })\n default:\n throw new Error(\n `Unsupported database type: ${config.connection.type}`\n )\n }\n}\n","// Copyright (c) 2025 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Umzug, MigrationMeta, UmzugStorage } from 'umzug'\nimport { Kysely } from 'kysely'\nimport { DB } from './schema'\n\nclass KyselyStorage implements UmzugStorage {\n constructor(private db: Kysely<DB>) {}\n\n private async ensureTable() {\n await this.db.schema\n .createTable('migrations')\n .ifNotExists()\n .addColumn('name', 'text', (col) => col.primaryKey())\n .addColumn('executedAt', 'text', (col) => col.notNull())\n .execute()\n }\n\n async executed(): Promise<string[]> {\n await this.ensureTable()\n const rows = await this.db\n .selectFrom('migrations')\n .select('name')\n .execute()\n return rows.map((r) => r.name)\n }\n\n async logMigration({ name }: MigrationMeta): Promise<void> {\n await this.ensureTable()\n await this.db\n .insertInto('migrations')\n .values({ name, executedAt: new Date().toISOString() })\n .execute()\n }\n\n async unlogMigration({ name }: MigrationMeta): Promise<void> {\n await this.ensureTable()\n await this.db\n .deleteFrom('migrations')\n .where('name', '=', name)\n .execute()\n }\n}\n\nexport const migrator = (db: Kysely<DB>) => {\n const ext = import.meta.url.endsWith('.ts') ? 'ts' : 'js'\n const glob = new URL(`./migrations/*.${ext}`, import.meta.url).pathname\n return new Umzug({\n migrations: {\n glob: glob,\n resolve: ({ name, path, context }) => {\n // Dynamic import for ESM\n return {\n name,\n up: async () => {\n console.log(path)\n const { up } = await import(path!)\n return up(context)\n },\n down: async () => {\n const { down } = await import(path!)\n return down(context)\n },\n }\n },\n },\n context: db,\n storage: new KyselyStorage(db),\n logger: console,\n })\n}\n","// Copyright (c) 2025 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Kysely } from 'kysely'\nimport { StoreSql } from './store-sql.js'\nimport { StoreConfig } from '@canton-network/core-wallet-store'\nimport { Logger } from 'pino'\nimport { DB } from './schema'\n\nexport async function bootstrap(\n db: Kysely<DB>,\n config: StoreConfig,\n logger: Logger\n): Promise<void> {\n const store = new StoreSql(db, logger)\n\n // Load all IDPs from config into the store\n await Promise.all(config.idps.map((idp) => store.addIdp(idp)))\n\n // Load all networks from config into the store\n await Promise.all(\n config.networks.map((network) => store.addNetwork(network))\n )\n}\n","// Copyright (c) 2025 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Command } from 'commander'\nimport { connection } from './store-sql.js'\nimport { migrator } from './migrator.js'\nimport type { StoreConfig } from '@canton-network/core-wallet-store'\nimport { pino } from 'pino'\nimport { bootstrap } from './bootstrap.js'\n\nconst logger = pino({ name: 'main', level: 'debug' })\n\nexport function createCLI(config: StoreConfig): Command {\n const program = new Command()\n\n program\n .command('up')\n .description('Run all pending migrations')\n .action(async () => {\n const db = connection(config)\n const umzug = migrator(db)\n await umzug.up()\n await db.destroy()\n })\n\n program\n .command('down')\n .description('Rollback last migration')\n .action(async () => {\n const db = connection(config)\n const umzug = migrator(db)\n await umzug.down()\n await db.destroy()\n })\n\n program\n .command('status')\n .description('Show executed and pending migrations')\n .action(async () => {\n const db = connection(config)\n const umzug = migrator(db)\n const executed = await umzug.executed()\n const pending = await umzug.pending()\n\n console.log('Executed migrations:', executed)\n console.log('Pending migrations:', pending)\n\n await db.destroy()\n })\n\n program\n .command('reset')\n .description('Rollback all migrations and reapply them')\n .action(async () => {\n const db = connection(config)\n const umzug = migrator(db)\n const executed = await umzug.executed()\n\n // Rollback all executed migrations in reverse order\n for (const migration of executed.reverse()) {\n await umzug.down({ to: migration.name })\n }\n\n // Reapply all migrations\n await umzug.up()\n await db.destroy()\n })\n\n program\n .command('bootstrap')\n .description('Bootstrap DB from config')\n .action(async () => {\n const db = connection(config)\n await bootstrap(db, config, logger)\n await db.destroy()\n })\n\n return program\n}\n"]}