@canton-network/core-signing-store-sql 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.
package/README.md ADDED
@@ -0,0 +1 @@
1
+ # signing-store
@@ -0,0 +1,6 @@
1
+ import { Kysely } from 'kysely';
2
+ import { StoreConfig } from '@canton-network/core-wallet-store';
3
+ import { Logger } from 'pino';
4
+ import { DB } from './schema';
5
+ export declare function bootstrap(db: Kysely<DB>, config: StoreConfig, logger: Logger): Promise<void>;
6
+ //# sourceMappingURL=bootstrap.d.ts.map
@@ -0,0 +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,CAEf"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ import { Command } from 'commander';
2
+ import type { StoreConfig } from '@canton-network/core-wallet-store';
3
+ export declare function createCLI(config: StoreConfig): Command;
4
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAGnC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAA;AAMpE,wBAAgB,SAAS,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAkEtD"}
package/dist/index.cjs ADDED
@@ -0,0 +1,370 @@
1
+ 'use strict';
2
+
3
+ var coreWalletAuth = require('@canton-network/core-wallet-auth');
4
+ var kysely = require('kysely');
5
+ var Database = require('better-sqlite3');
6
+ var zod = require('zod');
7
+ var umzug = require('umzug');
8
+ var commander = require('commander');
9
+ var pino = require('pino');
10
+
11
+ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
12
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
13
+
14
+ var Database__default = /*#__PURE__*/_interopDefault(Database);
15
+
16
+ var __defProp = Object.defineProperty;
17
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
18
+ var __publicField = (obj, key, value) => __defNormalProp(obj, key + "" , value);
19
+ var fromSigningKey = (key, userId, encrypt) => {
20
+ return {
21
+ id: key.id,
22
+ userId,
23
+ name: key.name,
24
+ publicKey: key.publicKey,
25
+ privateKey: key.privateKey ? key.privateKey : null,
26
+ metadata: key.metadata ? JSON.stringify(key.metadata) : null,
27
+ createdAt: key.createdAt.toISOString(),
28
+ updatedAt: key.updatedAt.toISOString()
29
+ };
30
+ };
31
+ var toSigningKey = (table, decrypt) => {
32
+ return {
33
+ id: table.id,
34
+ name: table.name,
35
+ publicKey: table.publicKey,
36
+ ...table.privateKey ? {
37
+ privateKey: table.privateKey
38
+ } : {},
39
+ createdAt: new Date(table.createdAt),
40
+ updatedAt: new Date(table.updatedAt),
41
+ ...table.metadata ? { metadata: JSON.parse(table.metadata) } : {}
42
+ };
43
+ };
44
+ var fromSigningTransaction = (transaction, userId) => {
45
+ return {
46
+ id: transaction.id,
47
+ userId,
48
+ hash: transaction.hash,
49
+ signature: transaction.signature || null,
50
+ publicKey: transaction.publicKey,
51
+ status: transaction.status,
52
+ metadata: transaction.metadata ? JSON.stringify(transaction.metadata) : null,
53
+ createdAt: transaction.createdAt.toISOString(),
54
+ updatedAt: transaction.updatedAt.toISOString()
55
+ };
56
+ };
57
+ var toSigningTransaction = (table) => {
58
+ return {
59
+ id: table.id,
60
+ hash: table.hash,
61
+ ...table.signature ? { signature: table.signature } : {},
62
+ publicKey: table.publicKey,
63
+ status: table.status,
64
+ ...table.metadata ? { metadata: JSON.parse(table.metadata) } : {},
65
+ createdAt: new Date(table.createdAt),
66
+ updatedAt: new Date(table.updatedAt)
67
+ };
68
+ };
69
+ var fromSigningDriverConfig = (config, userId) => {
70
+ return {
71
+ userId,
72
+ driverId: config.driverId,
73
+ config: JSON.stringify(config.config)
74
+ };
75
+ };
76
+ var toSigningDriverConfig = (table) => {
77
+ return {
78
+ driverId: table.driverId,
79
+ config: JSON.parse(table.config)
80
+ };
81
+ };
82
+ var storeConfigSchema = zod.z.object({
83
+ connection: zod.z.discriminatedUnion("type", [
84
+ zod.z.object({
85
+ type: zod.z.literal("memory")
86
+ }),
87
+ zod.z.object({
88
+ type: zod.z.literal("sqlite"),
89
+ database: zod.z.string()
90
+ }),
91
+ zod.z.object({
92
+ type: zod.z.literal("postgres"),
93
+ host: zod.z.string(),
94
+ port: zod.z.number(),
95
+ user: zod.z.string(),
96
+ password: zod.z.string(),
97
+ database: zod.z.string()
98
+ })
99
+ ])
100
+ });
101
+
102
+ // src/store-sql.ts
103
+ var StoreSql = class _StoreSql {
104
+ constructor(db, logger2, authContext) {
105
+ this.db = db;
106
+ this.logger = logger2;
107
+ __publicField(this, "authContext");
108
+ this.logger = logger2.child({ component: "StoreSql" });
109
+ this.authContext = authContext;
110
+ }
111
+ withAuthContext(context) {
112
+ return new _StoreSql(this.db, this.logger, context);
113
+ }
114
+ assertConnected() {
115
+ return coreWalletAuth.assertConnected(this.authContext).userId;
116
+ }
117
+ // SigningDriverStore methods
118
+ async getSigningKey(userId, keyId) {
119
+ const result = await this.db.selectFrom("signingKeys").selectAll().where("userId", "=", userId).where("id", "=", keyId).executeTakeFirst();
120
+ return result ? toSigningKey(result) : void 0;
121
+ }
122
+ async getSigningKeyByPublicKey(publicKey) {
123
+ const result = await this.db.selectFrom("signingKeys").selectAll().where("publicKey", "=", publicKey).executeTakeFirst();
124
+ return result ? toSigningKey(result) : void 0;
125
+ }
126
+ async setSigningKey(userId, key) {
127
+ const serialized = fromSigningKey(key, userId);
128
+ console.log(
129
+ "setSigningKey - serialized data:",
130
+ JSON.stringify(serialized, null, 2)
131
+ );
132
+ console.log("setSigningKey - serialized types:", {
133
+ id: typeof serialized.id,
134
+ userId: typeof serialized.userId,
135
+ name: typeof serialized.name,
136
+ publicKey: typeof serialized.publicKey,
137
+ privateKey: typeof serialized.privateKey,
138
+ metadata: typeof serialized.metadata,
139
+ createdAt: typeof serialized.createdAt,
140
+ updatedAt: typeof serialized.updatedAt
141
+ });
142
+ await this.db.insertInto("signingKeys").values(serialized).onConflict(
143
+ (oc) => oc.columns(["userId", "id"]).doUpdateSet({
144
+ name: serialized.name,
145
+ publicKey: serialized.publicKey,
146
+ privateKey: serialized.privateKey,
147
+ metadata: serialized.metadata,
148
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
149
+ })
150
+ ).execute();
151
+ }
152
+ async deleteSigningKey(userId, keyId) {
153
+ await this.db.deleteFrom("signingKeys").where("userId", "=", userId).where("id", "=", keyId).execute();
154
+ }
155
+ async listSigningKeys(userId) {
156
+ const results = await this.db.selectFrom("signingKeys").selectAll().where("userId", "=", userId).orderBy("createdAt", "desc").execute();
157
+ return results.map((result) => toSigningKey(result));
158
+ }
159
+ async getSigningTransaction(userId, txId) {
160
+ const result = await this.db.selectFrom("signingTransactions").selectAll().where("userId", "=", userId).where("id", "=", txId).executeTakeFirst();
161
+ return result ? toSigningTransaction(result) : void 0;
162
+ }
163
+ async setSigningTransaction(userId, transaction) {
164
+ const serialized = fromSigningTransaction(transaction, userId);
165
+ await this.db.insertInto("signingTransactions").values(serialized).onConflict(
166
+ (oc) => oc.columns(["userId", "id"]).doUpdateSet({
167
+ hash: serialized.hash,
168
+ signature: serialized.signature,
169
+ publicKey: serialized.publicKey,
170
+ status: serialized.status,
171
+ metadata: serialized.metadata,
172
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
173
+ })
174
+ ).execute();
175
+ }
176
+ async updateSigningTransactionStatus(userId, txId, status) {
177
+ await this.db.updateTable("signingTransactions").set({ status, updatedAt: (/* @__PURE__ */ new Date()).toISOString() }).where("userId", "=", userId).where("id", "=", txId).execute();
178
+ }
179
+ async listSigningTransactions(userId, limit = 100, before) {
180
+ let query = this.db.selectFrom("signingTransactions").selectAll().where("userId", "=", userId).orderBy("createdAt", "desc").limit(limit);
181
+ if (before) {
182
+ const beforeTx = await this.getSigningTransaction(userId, before);
183
+ if (beforeTx) {
184
+ query = query.where(
185
+ "createdAt",
186
+ "<",
187
+ beforeTx.createdAt.toISOString()
188
+ );
189
+ }
190
+ }
191
+ const results = await query.execute();
192
+ return results.map(toSigningTransaction);
193
+ }
194
+ async listSigningTransactionsByTxIdsAndPublicKeys(txIds, publicKeys) {
195
+ const results = await this.db.selectFrom("signingTransactions").selectAll().where(
196
+ (eb) => eb.or([
197
+ eb("publicKey", "in", publicKeys),
198
+ eb("id", "in", txIds)
199
+ ])
200
+ ).execute();
201
+ return results.map(toSigningTransaction);
202
+ }
203
+ async getSigningDriverConfiguration(userId, driverId) {
204
+ const result = await this.db.selectFrom("signingDriverConfigs").selectAll().where("userId", "=", userId).where("driverId", "=", driverId).executeTakeFirst();
205
+ return result ? toSigningDriverConfig(result) : void 0;
206
+ }
207
+ async setSigningDriverConfiguration(userId, config) {
208
+ const serialized = fromSigningDriverConfig(config, userId);
209
+ await this.db.insertInto("signingDriverConfigs").values(serialized).onConflict(
210
+ (oc) => oc.columns(["userId", "driverId"]).doUpdateSet({
211
+ config: serialized.config
212
+ })
213
+ ).execute();
214
+ }
215
+ async setSigningKeys(userId, keys) {
216
+ if (keys.length === 0) return;
217
+ const serialized = keys.map((key) => fromSigningKey(key, userId));
218
+ await this.db.insertInto("signingKeys").values(serialized).onConflict(
219
+ (oc) => oc.columns(["userId", "id"]).doUpdateSet({
220
+ name: serialized[0].name,
221
+ publicKey: serialized[0].publicKey,
222
+ privateKey: serialized[0].privateKey,
223
+ metadata: serialized[0].metadata,
224
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
225
+ })
226
+ ).execute();
227
+ }
228
+ async setSigningTransactions(userId, transactions) {
229
+ if (transactions.length === 0) return;
230
+ const serialized = transactions.map(
231
+ (tx) => fromSigningTransaction(tx, userId)
232
+ );
233
+ await this.db.insertInto("signingTransactions").values(serialized).onConflict(
234
+ (oc) => oc.columns(["userId", "id"]).doUpdateSet({
235
+ hash: serialized[0].hash,
236
+ signature: serialized[0].signature,
237
+ publicKey: serialized[0].publicKey,
238
+ status: serialized[0].status,
239
+ metadata: serialized[0].metadata,
240
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
241
+ })
242
+ ).execute();
243
+ }
244
+ };
245
+ var connection = (config) => {
246
+ switch (config.connection.type) {
247
+ case "sqlite":
248
+ return new kysely.Kysely({
249
+ dialect: new kysely.SqliteDialect({
250
+ database: new Database__default.default(config.connection.database)
251
+ }),
252
+ plugins: [new kysely.CamelCasePlugin()]
253
+ });
254
+ case "memory":
255
+ return new kysely.Kysely({
256
+ dialect: new kysely.SqliteDialect({
257
+ database: new Database__default.default(":memory:")
258
+ }),
259
+ plugins: [new kysely.CamelCasePlugin()]
260
+ });
261
+ default:
262
+ throw new Error(
263
+ `Unsupported database type: ${config.connection.type}`
264
+ );
265
+ }
266
+ };
267
+ var KyselyStorage = class {
268
+ constructor(db) {
269
+ this.db = db;
270
+ }
271
+ async ensureTable() {
272
+ await this.db.schema.createTable("migrations").ifNotExists().addColumn("name", "text", (col) => col.primaryKey()).addColumn("executedAt", "text", (col) => col.notNull()).execute();
273
+ }
274
+ async executed() {
275
+ await this.ensureTable();
276
+ const rows = await this.db.selectFrom("migrations").select("name").execute();
277
+ return rows.map((r) => r.name);
278
+ }
279
+ async logMigration({ name }) {
280
+ await this.ensureTable();
281
+ await this.db.insertInto("migrations").values({ name, executedAt: (/* @__PURE__ */ new Date()).toISOString() }).execute();
282
+ }
283
+ async unlogMigration({ name }) {
284
+ await this.ensureTable();
285
+ await this.db.deleteFrom("migrations").where("name", "=", name).execute();
286
+ }
287
+ };
288
+ var migrator = (db) => {
289
+ const ext = (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)).endsWith(".ts") ? "ts" : "js";
290
+ const glob = new URL(`./migrations/*.${ext}`, (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))).pathname;
291
+ return new umzug.Umzug({
292
+ migrations: {
293
+ glob,
294
+ resolve: ({ name, path, context }) => {
295
+ return {
296
+ name,
297
+ up: async () => {
298
+ console.log(path);
299
+ const { up } = await import(path);
300
+ return up(context);
301
+ },
302
+ down: async () => {
303
+ const { down } = await import(path);
304
+ return down(context);
305
+ }
306
+ };
307
+ }
308
+ },
309
+ context: db,
310
+ storage: new KyselyStorage(db),
311
+ logger: console
312
+ });
313
+ };
314
+
315
+ // src/bootstrap.ts
316
+ async function bootstrap(db, config, logger2) {
317
+ new StoreSql(db, logger2);
318
+ }
319
+
320
+ // src/cli.ts
321
+ var logger = pino.pino({ name: "main", level: "debug" });
322
+ function createCLI(config) {
323
+ const program = new commander.Command();
324
+ program.command("up").description("Run all pending migrations").action(async () => {
325
+ const db = connection(config);
326
+ const umzug = migrator(db);
327
+ await umzug.up();
328
+ await db.destroy();
329
+ });
330
+ program.command("down").description("Rollback last migration").action(async () => {
331
+ const db = connection(config);
332
+ const umzug = migrator(db);
333
+ await umzug.down();
334
+ await db.destroy();
335
+ });
336
+ program.command("status").description("Show executed and pending migrations").action(async () => {
337
+ const db = connection(config);
338
+ const umzug = migrator(db);
339
+ const executed = await umzug.executed();
340
+ const pending = await umzug.pending();
341
+ console.log("Executed migrations:", executed);
342
+ console.log("Pending migrations:", pending);
343
+ await db.destroy();
344
+ });
345
+ program.command("reset").description("Rollback all migrations and reapply them").action(async () => {
346
+ const db = connection(config);
347
+ const umzug = migrator(db);
348
+ const executed = await umzug.executed();
349
+ for (const migration of executed.reverse()) {
350
+ await umzug.down({ to: migration.name });
351
+ }
352
+ await umzug.up();
353
+ await db.destroy();
354
+ });
355
+ program.command("bootstrap").description("Bootstrap DB from config").action(async () => {
356
+ const db = connection(config);
357
+ await bootstrap(db, config, logger);
358
+ await db.destroy();
359
+ });
360
+ return program;
361
+ }
362
+
363
+ exports.StoreSql = StoreSql;
364
+ exports.bootstrap = bootstrap;
365
+ exports.connection = connection;
366
+ exports.createCLI = createCLI;
367
+ exports.migrator = migrator;
368
+ exports.storeConfigSchema = storeConfigSchema;
369
+ //# sourceMappingURL=index.cjs.map
370
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/schema.ts","../src/store-sql.ts","../src/migrator.ts","../src/bootstrap.ts","../src/cli.ts"],"names":["z","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 { UserId } from '@canton-network/core-wallet-auth'\nimport {\n SigningKey,\n SigningTransaction,\n SigningDriverConfig,\n SigningDriverStatus,\n} from '@canton-network/core-signing-lib'\nimport { z } from 'zod'\n\ninterface MigrationTable {\n name: string\n executedAt: string\n}\n\nexport interface SigningKeyTable {\n id: string\n userId: UserId\n name: string\n publicKey: string\n privateKey: string | null\n metadata: string | null\n createdAt: string\n updatedAt: string\n}\n\nexport interface SigningTransactionTable {\n id: string\n userId: UserId\n hash: string\n signature: string | null\n publicKey: string\n status: string\n metadata: string | null\n createdAt: string\n updatedAt: string\n}\n\nexport interface SigningDriverConfigTable {\n userId: UserId\n driverId: string\n config: string\n}\n\nexport interface DB {\n migrations: MigrationTable\n signingKeys: SigningKeyTable\n signingTransactions: SigningTransactionTable\n signingDriverConfigs: SigningDriverConfigTable\n}\n\n// Signing driver conversion functions\n\nexport const fromSigningKey = (\n key: SigningKey,\n userId: UserId,\n encrypt?: (data: string) => string\n): SigningKeyTable => {\n return {\n id: key.id,\n userId: userId,\n name: key.name,\n publicKey: key.publicKey,\n privateKey: key.privateKey\n ? encrypt\n ? encrypt(key.privateKey)\n : key.privateKey\n : null,\n metadata: key.metadata ? JSON.stringify(key.metadata) : null,\n createdAt: key.createdAt.toISOString(),\n updatedAt: key.updatedAt.toISOString(),\n }\n}\n\nexport const toSigningKey = (\n table: SigningKeyTable,\n decrypt?: (data: string) => string\n): SigningKey => {\n return {\n id: table.id,\n name: table.name,\n publicKey: table.publicKey,\n ...(table.privateKey\n ? {\n privateKey: decrypt\n ? decrypt(table.privateKey)\n : table.privateKey,\n }\n : {}),\n createdAt: new Date(table.createdAt),\n updatedAt: new Date(table.updatedAt),\n ...(table.metadata ? { metadata: JSON.parse(table.metadata) } : {}),\n }\n}\n\nexport const fromSigningTransaction = (\n transaction: SigningTransaction,\n userId: UserId\n): SigningTransactionTable => {\n return {\n id: transaction.id,\n userId: userId,\n hash: transaction.hash,\n signature: transaction.signature || null,\n publicKey: transaction.publicKey,\n status: transaction.status,\n metadata: transaction.metadata\n ? JSON.stringify(transaction.metadata)\n : null,\n createdAt: transaction.createdAt.toISOString(),\n updatedAt: transaction.updatedAt.toISOString(),\n }\n}\n\nexport const toSigningTransaction = (\n table: SigningTransactionTable\n): SigningTransaction => {\n return {\n id: table.id,\n hash: table.hash,\n ...(table.signature ? { signature: table.signature } : {}),\n publicKey: table.publicKey,\n status: table.status as SigningDriverStatus,\n ...(table.metadata ? { metadata: JSON.parse(table.metadata) } : {}),\n createdAt: new Date(table.createdAt),\n updatedAt: new Date(table.updatedAt),\n }\n}\n\nexport const fromSigningDriverConfig = (\n config: SigningDriverConfig,\n userId: UserId\n): SigningDriverConfigTable => {\n return {\n userId: userId,\n driverId: config.driverId,\n config: JSON.stringify(config.config),\n }\n}\n\nexport const toSigningDriverConfig = (\n table: SigningDriverConfigTable\n): SigningDriverConfig => {\n return {\n driverId: table.driverId,\n config: JSON.parse(table.config),\n }\n}\n\nexport const storeConfigSchema = z.object({\n connection: z.discriminatedUnion('type', [\n z.object({\n type: z.literal('memory'),\n }),\n z.object({\n type: z.literal('sqlite'),\n database: z.string(),\n }),\n z.object({\n type: z.literal('postgres'),\n host: z.string(),\n port: z.number(),\n user: z.string(),\n password: z.string(),\n database: z.string(),\n }),\n ]),\n})\n\nexport type StoreConfig = z.infer<typeof storeConfigSchema>\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 SigningDriverStore,\n SigningKey,\n SigningTransaction,\n SigningDriverStatus,\n SigningDriverConfig,\n} from '@canton-network/core-signing-lib'\nimport { CamelCasePlugin, Kysely, SqliteDialect } from 'kysely'\nimport Database from 'better-sqlite3'\nimport {\n DB,\n fromSigningKey,\n toSigningKey,\n fromSigningTransaction,\n toSigningTransaction,\n fromSigningDriverConfig,\n toSigningDriverConfig,\n SigningKeyTable,\n StoreConfig,\n} from './schema.js'\n\nexport class StoreSql implements SigningDriverStore, 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\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 // SigningDriverStore methods\n async getSigningKey(\n userId: string,\n keyId: string\n ): Promise<SigningKey | undefined> {\n const result = await this.db\n .selectFrom('signingKeys')\n .selectAll()\n .where('userId', '=', userId)\n .where('id', '=', keyId)\n .executeTakeFirst()\n\n return result ? toSigningKey(result) : undefined\n }\n\n async getSigningKeyByPublicKey(\n publicKey: string\n ): Promise<SigningKey | undefined> {\n const result = await this.db\n .selectFrom('signingKeys')\n .selectAll()\n .where('publicKey', '=', publicKey)\n .executeTakeFirst()\n return result ? toSigningKey(result) : undefined\n }\n\n async setSigningKey(userId: string, key: SigningKey): Promise<void> {\n const serialized = fromSigningKey(key, userId)\n\n console.log(\n 'setSigningKey - serialized data:',\n JSON.stringify(serialized, null, 2)\n )\n console.log('setSigningKey - serialized types:', {\n id: typeof serialized.id,\n userId: typeof serialized.userId,\n name: typeof serialized.name,\n publicKey: typeof serialized.publicKey,\n privateKey: typeof serialized.privateKey,\n metadata: typeof serialized.metadata,\n createdAt: typeof serialized.createdAt,\n updatedAt: typeof serialized.updatedAt,\n })\n\n await this.db\n .insertInto('signingKeys')\n .values(serialized)\n .onConflict((oc) =>\n oc.columns(['userId', 'id']).doUpdateSet({\n name: serialized.name,\n publicKey: serialized.publicKey,\n privateKey: serialized.privateKey,\n metadata: serialized.metadata,\n updatedAt: new Date().toISOString(),\n })\n )\n .execute()\n }\n\n async deleteSigningKey(userId: string, keyId: string): Promise<void> {\n await this.db\n .deleteFrom('signingKeys')\n .where('userId', '=', userId)\n .where('id', '=', keyId)\n .execute()\n }\n\n async listSigningKeys(userId: string): Promise<SigningKey[]> {\n const results = await this.db\n .selectFrom('signingKeys')\n .selectAll()\n .where('userId', '=', userId)\n .orderBy('createdAt', 'desc')\n .execute()\n\n return results.map((result: SigningKeyTable) => toSigningKey(result))\n }\n\n async getSigningTransaction(\n userId: string,\n txId: string\n ): Promise<SigningTransaction | undefined> {\n const result = await this.db\n .selectFrom('signingTransactions')\n .selectAll()\n .where('userId', '=', userId)\n .where('id', '=', txId)\n .executeTakeFirst()\n\n return result ? toSigningTransaction(result) : undefined\n }\n\n async setSigningTransaction(\n userId: string,\n transaction: SigningTransaction\n ): Promise<void> {\n const serialized = fromSigningTransaction(transaction, userId)\n\n await this.db\n .insertInto('signingTransactions')\n .values(serialized)\n .onConflict((oc) =>\n oc.columns(['userId', 'id']).doUpdateSet({\n hash: serialized.hash,\n signature: serialized.signature,\n publicKey: serialized.publicKey,\n status: serialized.status,\n metadata: serialized.metadata,\n updatedAt: new Date().toISOString(),\n })\n )\n .execute()\n }\n\n async updateSigningTransactionStatus(\n userId: string,\n txId: string,\n status: SigningDriverStatus\n ): Promise<void> {\n await this.db\n .updateTable('signingTransactions')\n .set({ status, updatedAt: new Date().toISOString() })\n .where('userId', '=', userId)\n .where('id', '=', txId)\n .execute()\n }\n\n async listSigningTransactions(\n userId: string,\n limit: number = 100,\n before?: string\n ): Promise<SigningTransaction[]> {\n let query = this.db\n .selectFrom('signingTransactions')\n .selectAll()\n .where('userId', '=', userId)\n .orderBy('createdAt', 'desc')\n .limit(limit)\n\n if (before) {\n const beforeTx = await this.getSigningTransaction(userId, before)\n if (beforeTx) {\n query = query.where(\n 'createdAt',\n '<',\n beforeTx.createdAt.toISOString()\n )\n }\n }\n\n const results = await query.execute()\n return results.map(toSigningTransaction)\n }\n\n async listSigningTransactionsByTxIdsAndPublicKeys(\n txIds: string[],\n publicKeys: string[]\n ): Promise<SigningTransaction[]> {\n const results = await this.db\n .selectFrom('signingTransactions')\n .selectAll()\n .where((eb) =>\n eb.or([\n eb('publicKey', 'in', publicKeys),\n eb('id', 'in', txIds),\n ])\n )\n .execute()\n\n return results.map(toSigningTransaction)\n }\n\n async getSigningDriverConfiguration(\n userId: string,\n driverId: string\n ): Promise<SigningDriverConfig | undefined> {\n const result = await this.db\n .selectFrom('signingDriverConfigs')\n .selectAll()\n .where('userId', '=', userId)\n .where('driverId', '=', driverId)\n .executeTakeFirst()\n\n return result ? toSigningDriverConfig(result) : undefined\n }\n\n async setSigningDriverConfiguration(\n userId: string,\n config: SigningDriverConfig\n ): Promise<void> {\n const serialized = fromSigningDriverConfig(config, userId)\n\n await this.db\n .insertInto('signingDriverConfigs')\n .values(serialized)\n .onConflict((oc) =>\n oc.columns(['userId', 'driverId']).doUpdateSet({\n config: serialized.config,\n })\n )\n .execute()\n }\n\n async setSigningKeys(userId: string, keys: SigningKey[]): Promise<void> {\n if (keys.length === 0) return\n\n const serialized = keys.map((key) => fromSigningKey(key, userId))\n\n await this.db\n .insertInto('signingKeys')\n .values(serialized)\n .onConflict((oc) =>\n oc.columns(['userId', 'id']).doUpdateSet({\n name: serialized[0].name,\n publicKey: serialized[0].publicKey,\n privateKey: serialized[0].privateKey,\n metadata: serialized[0].metadata,\n updatedAt: new Date().toISOString(),\n })\n )\n .execute()\n }\n\n async setSigningTransactions(\n userId: string,\n transactions: SigningTransaction[]\n ): Promise<void> {\n if (transactions.length === 0) return\n\n const serialized = transactions.map((tx) =>\n fromSigningTransaction(tx, userId)\n )\n\n await this.db\n .insertInto('signingTransactions')\n .values(serialized)\n .onConflict((oc) =>\n oc.columns(['userId', 'id']).doUpdateSet({\n hash: serialized[0].hash,\n signature: serialized[0].signature,\n publicKey: serialized[0].publicKey,\n status: serialized[0].status,\n metadata: serialized[0].metadata,\n updatedAt: new Date().toISOString(),\n })\n )\n .execute()\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 new StoreSql(db, logger)\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"]}
@@ -0,0 +1,7 @@
1
+ export * from './store-sql.js';
2
+ export * from './migrator.js';
3
+ export * from './cli.js';
4
+ export * from './bootstrap.js';
5
+ import { storeConfigSchema } from './schema.js';
6
+ export { storeConfigSchema };
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,cAAc,gBAAgB,CAAA;AAC9B,cAAc,eAAe,CAAA;AAC7B,cAAc,UAAU,CAAA;AACxB,cAAc,gBAAgB,CAAA;AAC9B,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAE/C,OAAO,EAAE,iBAAiB,EAAE,CAAA"}