@canton-network/core-wallet-store-sql 0.9.0 → 0.11.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/dist/bootstrap.d.ts +6 -0
- package/dist/bootstrap.d.ts.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/index.cjs +526 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +515 -5
- package/dist/index.js.map +1 -0
- package/dist/migrations/001-init.d.ts.map +1 -1
- package/dist/migrations/001-init.js +0 -2
- package/dist/schema.d.ts +2 -2
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +29 -2
- package/dist/store-sql.d.ts.map +1 -1
- package/package.json +19 -9
- package/dist/cli.js +0 -66
- package/dist/migrations/002-drop-grpc-url.d.ts +0 -5
- package/dist/migrations/002-drop-grpc-url.d.ts.map +0 -1
- package/dist/migrations/002-drop-grpc-url.js +0 -16
- package/dist/migrator.js +0 -66
- package/dist/store-sql.js +0 -288
- package/dist/store-sql.test.d.ts +0 -2
- package/dist/store-sql.test.d.ts.map +0 -1
- package/dist/store-sql.test.js +0 -207
package/dist/schema.js
CHANGED
|
@@ -47,6 +47,20 @@ export const toAuth = (table) => {
|
|
|
47
47
|
clientSecret: table.adminClientSecret,
|
|
48
48
|
},
|
|
49
49
|
};
|
|
50
|
+
case 'self_signed':
|
|
51
|
+
return {
|
|
52
|
+
identityProviderId: table.identityProviderId,
|
|
53
|
+
type: table.type,
|
|
54
|
+
issuer: table.issuer,
|
|
55
|
+
audience: table.audience,
|
|
56
|
+
scope: table.scope,
|
|
57
|
+
clientId: table.clientId,
|
|
58
|
+
clientSecret: table.clientSecret,
|
|
59
|
+
admin: {
|
|
60
|
+
clientId: table.adminClientId,
|
|
61
|
+
clientSecret: table.adminClientSecret,
|
|
62
|
+
},
|
|
63
|
+
};
|
|
50
64
|
default:
|
|
51
65
|
throw new Error(`Unknown auth type: ${table.type}`);
|
|
52
66
|
}
|
|
@@ -98,8 +112,21 @@ export const fromAuth = (auth) => {
|
|
|
98
112
|
adminClientId: auth.admin?.clientId || '',
|
|
99
113
|
adminClientSecret: auth.admin?.clientSecret || '',
|
|
100
114
|
};
|
|
101
|
-
|
|
102
|
-
|
|
115
|
+
case 'self_signed':
|
|
116
|
+
return {
|
|
117
|
+
identityProviderId: auth.identityProviderId,
|
|
118
|
+
type: auth.type,
|
|
119
|
+
issuer: auth.issuer,
|
|
120
|
+
configUrl: '',
|
|
121
|
+
audience: auth.audience,
|
|
122
|
+
tokenUrl: '',
|
|
123
|
+
grantType: '',
|
|
124
|
+
scope: auth.scope,
|
|
125
|
+
clientId: auth.clientId,
|
|
126
|
+
clientSecret: auth.clientSecret,
|
|
127
|
+
adminClientId: auth.admin?.clientId || '',
|
|
128
|
+
adminClientSecret: auth.admin?.clientSecret || '',
|
|
129
|
+
};
|
|
103
130
|
}
|
|
104
131
|
};
|
|
105
132
|
export const toNetwork = (table, authTable) => {
|
package/dist/store-sql.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store-sql.d.ts","sourceRoot":"","sources":["../src/store-sql.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAC7B,OAAO,EACH,WAAW,EAEX,SAAS,EAEZ,MAAM,kCAAkC,CAAA;AACzC,OAAO,EACH,KAAK,IAAI,SAAS,EAClB,MAAM,EACN,OAAO,EACP,OAAO,EACP,YAAY,EACZ,WAAW,EACX,OAAO,EACP,WAAW,EACd,MAAM,mCAAmC,CAAA;AAC1C,OAAO,EAAmB,MAAM,EAAiB,MAAM,QAAQ,CAAA;AAE/D,OAAO,EACH,EAAE,EAQL,MAAM,aAAa,CAAA;AAEpB,qBAAa,QAAS,YAAW,SAAS,EAAE,SAAS,CAAC,QAAQ,CAAC;IAIvD,OAAO,CAAC,EAAE;IACV,OAAO,CAAC,MAAM;IAJlB,WAAW,EAAE,WAAW,GAAG,SAAS,CAAA;gBAGxB,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,EACd,MAAM,EAAE,MAAM,EACtB,WAAW,CAAC,EAAE,WAAW;IAQ7B,eAAe,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,QAAQ;IAIhD,OAAO,CAAC,eAAe;IAMjB,UAAU,CAAC,MAAM,GAAE,YAAiB,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IA2B7D,gBAAgB,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAK/C,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAwBjD,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAsCxC,UAAU,IAAI,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC;IAQ1C,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAc3C,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAS9B,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAW7C,iBAAiB,IAAI,OAAO,CAAC,OAAO,CAAC;IAkBrC,YAAY,IAAI,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAuBvC,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"store-sql.d.ts","sourceRoot":"","sources":["../src/store-sql.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAC7B,OAAO,EACH,WAAW,EAEX,SAAS,EAEZ,MAAM,kCAAkC,CAAA;AACzC,OAAO,EACH,KAAK,IAAI,SAAS,EAClB,MAAM,EACN,OAAO,EACP,OAAO,EACP,YAAY,EACZ,WAAW,EACX,OAAO,EACP,WAAW,EACd,MAAM,mCAAmC,CAAA;AAC1C,OAAO,EAAmB,MAAM,EAAiB,MAAM,QAAQ,CAAA;AAE/D,OAAO,EACH,EAAE,EAQL,MAAM,aAAa,CAAA;AAEpB,qBAAa,QAAS,YAAW,SAAS,EAAE,SAAS,CAAC,QAAQ,CAAC;IAIvD,OAAO,CAAC,EAAE;IACV,OAAO,CAAC,MAAM;IAJlB,WAAW,EAAE,WAAW,GAAG,SAAS,CAAA;gBAGxB,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,EACd,MAAM,EAAE,MAAM,EACtB,WAAW,CAAC,EAAE,WAAW;IAQ7B,eAAe,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,QAAQ;IAIhD,OAAO,CAAC,eAAe;IAMjB,UAAU,CAAC,MAAM,GAAE,YAAiB,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IA2B7D,gBAAgB,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAK/C,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAwBjD,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAsCxC,UAAU,IAAI,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC;IAQ1C,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAc3C,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAS9B,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAW7C,iBAAiB,IAAI,OAAO,CAAC,OAAO,CAAC;IAkBrC,YAAY,IAAI,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAuBvC,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IA0B9C,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAuB3C,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA4B7C,cAAc,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBvD,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;CAc5E;AAED,eAAO,MAAM,UAAU,GAAI,QAAQ,WAAW,eAqB7C,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,26 +1,35 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@canton-network/core-wallet-store-sql",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"repository": "github:hyperledger-labs/splice-wallet-kernel",
|
|
6
6
|
"description": "SQL implementation of the Store API",
|
|
7
7
|
"license": "Apache-2.0",
|
|
8
8
|
"author": "Marc Juchli <marc.juchli@digitalasset.com>",
|
|
9
9
|
"packageManager": "yarn@4.9.4",
|
|
10
|
-
"main": "
|
|
11
|
-
"
|
|
10
|
+
"main": "dist/index.cjs",
|
|
11
|
+
"module": "dist/index.js",
|
|
12
|
+
"types": "dist/index.d.ts",
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"import": "./dist/index.js",
|
|
17
|
+
"require": "./dist/index.cjs",
|
|
18
|
+
"default": "./dist/index.js"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
12
21
|
"scripts": {
|
|
13
|
-
"build": "tsc -b",
|
|
14
|
-
"dev": "tsc -b
|
|
22
|
+
"build": "tsup && tsc -p tsconfig.types.json && tsc -b tsconfig.migrations.json",
|
|
23
|
+
"dev": "tsup --watch --onSuccess \"tsc -p tsconfig.types.json && tsc -b tsconfig.migrations.json\"",
|
|
15
24
|
"flatpack": "yarn pack --out \"$FLATPACK_OUTDIR\"",
|
|
16
25
|
"clean": "tsc -b --clean; rm -rf dist",
|
|
17
26
|
"test": "yarn node --experimental-vm-modules $(yarn bin jest)"
|
|
18
27
|
},
|
|
19
28
|
"dependencies": {
|
|
20
|
-
"@canton-network/core-ledger-client": "",
|
|
21
|
-
"@canton-network/core-rpc-errors": "",
|
|
22
|
-
"@canton-network/core-wallet-auth": "",
|
|
23
|
-
"@canton-network/core-wallet-store": "",
|
|
29
|
+
"@canton-network/core-ledger-client": "^0.16.0",
|
|
30
|
+
"@canton-network/core-rpc-errors": "^0.7.0",
|
|
31
|
+
"@canton-network/core-wallet-auth": "^0.11.0",
|
|
32
|
+
"@canton-network/core-wallet-store": "^0.10.0",
|
|
24
33
|
"better-sqlite3": "^12.2.0",
|
|
25
34
|
"commander": "^14.0.0",
|
|
26
35
|
"kysely": "^0.28.5",
|
|
@@ -38,6 +47,7 @@
|
|
|
38
47
|
"pino-test": "^1.1.0",
|
|
39
48
|
"ts-jest": "^29.4.0",
|
|
40
49
|
"ts-jest-resolver": "^2.0.1",
|
|
50
|
+
"tsup": "^8.5.0",
|
|
41
51
|
"tsx": "^4.20.4",
|
|
42
52
|
"typescript": "^5.8.3"
|
|
43
53
|
},
|
package/dist/cli.js
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
// Copyright (c) 2025 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
|
|
2
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
-
import { Command } from 'commander';
|
|
4
|
-
import { connection, StoreSql } from './store-sql.js';
|
|
5
|
-
import { migrator } from './migrator.js';
|
|
6
|
-
import { pino } from 'pino';
|
|
7
|
-
const logger = pino({ name: 'main', level: 'debug' });
|
|
8
|
-
export function createCLI(config) {
|
|
9
|
-
console.log('Wallet Store Sql CLI');
|
|
10
|
-
const program = new Command();
|
|
11
|
-
program
|
|
12
|
-
.command('up')
|
|
13
|
-
.description('Run all pending migrations')
|
|
14
|
-
.action(async () => {
|
|
15
|
-
const db = connection(config);
|
|
16
|
-
const umzug = migrator(db);
|
|
17
|
-
await umzug.up();
|
|
18
|
-
await db.destroy();
|
|
19
|
-
});
|
|
20
|
-
program
|
|
21
|
-
.command('down')
|
|
22
|
-
.description('Rollback last migration')
|
|
23
|
-
.action(async () => {
|
|
24
|
-
const db = connection(config);
|
|
25
|
-
const umzug = migrator(db);
|
|
26
|
-
await umzug.down();
|
|
27
|
-
await db.destroy();
|
|
28
|
-
});
|
|
29
|
-
program
|
|
30
|
-
.command('status')
|
|
31
|
-
.description('Show executed and pending migrations')
|
|
32
|
-
.action(async () => {
|
|
33
|
-
const db = connection(config);
|
|
34
|
-
const umzug = migrator(db);
|
|
35
|
-
const executed = await umzug.executed();
|
|
36
|
-
const pending = await umzug.pending();
|
|
37
|
-
console.log('Executed migrations:', executed);
|
|
38
|
-
console.log('Pending migrations:', pending);
|
|
39
|
-
await db.destroy();
|
|
40
|
-
});
|
|
41
|
-
program
|
|
42
|
-
.command('reset')
|
|
43
|
-
.description('Rollback all migrations and reapply them')
|
|
44
|
-
.action(async () => {
|
|
45
|
-
const db = connection(config);
|
|
46
|
-
const umzug = migrator(db);
|
|
47
|
-
const executed = await umzug.executed();
|
|
48
|
-
// Rollback all executed migrations in reverse order
|
|
49
|
-
for (const migration of executed.reverse()) {
|
|
50
|
-
await umzug.down({ to: migration.name });
|
|
51
|
-
}
|
|
52
|
-
// Reapply all migrations
|
|
53
|
-
await umzug.up();
|
|
54
|
-
await db.destroy();
|
|
55
|
-
});
|
|
56
|
-
program
|
|
57
|
-
.command('bootstrap')
|
|
58
|
-
.description('Bootstrap DB from config')
|
|
59
|
-
.action(async () => {
|
|
60
|
-
const db = connection(config);
|
|
61
|
-
const store = new StoreSql(db, logger);
|
|
62
|
-
await Promise.all(config.networks.map((network) => store.addNetwork(network)));
|
|
63
|
-
await db.destroy();
|
|
64
|
-
});
|
|
65
|
-
return program;
|
|
66
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"002-drop-grpc-url.d.ts","sourceRoot":"","sources":["../../src/migrations/002-drop-grpc-url.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAC/B,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAA;AAEjC,wBAAsB,EAAE,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAQtD;AAED,wBAAsB,IAAI,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAOxD"}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
// Copyright (c) 2025 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
|
|
2
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
-
export async function up(db) {
|
|
4
|
-
console.log('Running 002-drop-grpc-url...');
|
|
5
|
-
// --- networks ---
|
|
6
|
-
await db.schema
|
|
7
|
-
.alterTable('networks')
|
|
8
|
-
.dropColumn('ledger_api_admin_grpc_url')
|
|
9
|
-
.execute();
|
|
10
|
-
}
|
|
11
|
-
export async function down(db) {
|
|
12
|
-
await db.schema
|
|
13
|
-
.alterTable('networks')
|
|
14
|
-
.addColumn('ledger_api_admin_grpc_url', 'text', (col) => col.notNull().defaultTo(''))
|
|
15
|
-
.execute();
|
|
16
|
-
}
|
package/dist/migrator.js
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
// Copyright (c) 2025 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
|
|
2
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
-
import { Umzug } from 'umzug';
|
|
4
|
-
class KyselyStorage {
|
|
5
|
-
db;
|
|
6
|
-
constructor(db) {
|
|
7
|
-
this.db = db;
|
|
8
|
-
}
|
|
9
|
-
async ensureTable() {
|
|
10
|
-
await this.db.schema
|
|
11
|
-
.createTable('migrations')
|
|
12
|
-
.ifNotExists()
|
|
13
|
-
.addColumn('name', 'text', (col) => col.primaryKey())
|
|
14
|
-
.addColumn('executedAt', 'text', (col) => col.notNull())
|
|
15
|
-
.execute();
|
|
16
|
-
}
|
|
17
|
-
async executed() {
|
|
18
|
-
await this.ensureTable();
|
|
19
|
-
const rows = await this.db
|
|
20
|
-
.selectFrom('migrations')
|
|
21
|
-
.select('name')
|
|
22
|
-
.execute();
|
|
23
|
-
return rows.map((r) => r.name);
|
|
24
|
-
}
|
|
25
|
-
async logMigration({ name }) {
|
|
26
|
-
await this.ensureTable();
|
|
27
|
-
await this.db
|
|
28
|
-
.insertInto('migrations')
|
|
29
|
-
.values({ name, executedAt: new Date().toISOString() })
|
|
30
|
-
.execute();
|
|
31
|
-
}
|
|
32
|
-
async unlogMigration({ name }) {
|
|
33
|
-
await this.ensureTable();
|
|
34
|
-
await this.db
|
|
35
|
-
.deleteFrom('migrations')
|
|
36
|
-
.where('name', '=', name)
|
|
37
|
-
.execute();
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
export const migrator = (db) => {
|
|
41
|
-
const ext = import.meta.url.endsWith('.ts') ? 'ts' : 'js';
|
|
42
|
-
const glob = new URL(`./migrations/*.${ext}`, import.meta.url).pathname;
|
|
43
|
-
return new Umzug({
|
|
44
|
-
migrations: {
|
|
45
|
-
glob: glob,
|
|
46
|
-
resolve: ({ name, path, context }) => {
|
|
47
|
-
// Dynamic import for ESM
|
|
48
|
-
return {
|
|
49
|
-
name,
|
|
50
|
-
up: async () => {
|
|
51
|
-
console.log(path);
|
|
52
|
-
const { up } = await import(path);
|
|
53
|
-
return up(context);
|
|
54
|
-
},
|
|
55
|
-
down: async () => {
|
|
56
|
-
const { down } = await import(path);
|
|
57
|
-
return down(context);
|
|
58
|
-
},
|
|
59
|
-
};
|
|
60
|
-
},
|
|
61
|
-
},
|
|
62
|
-
context: db,
|
|
63
|
-
storage: new KyselyStorage(db),
|
|
64
|
-
logger: console,
|
|
65
|
-
});
|
|
66
|
-
};
|
package/dist/store-sql.js
DELETED
|
@@ -1,288 +0,0 @@
|
|
|
1
|
-
// Copyright (c) 2025 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
|
|
2
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
-
import { assertConnected, } from '@canton-network/core-wallet-auth';
|
|
4
|
-
import { CamelCasePlugin, Kysely, SqliteDialect } from 'kysely';
|
|
5
|
-
import Database from 'better-sqlite3';
|
|
6
|
-
import { fromAuth, fromNetwork, fromTransaction, fromWallet, toNetwork, toTransaction, toWallet, } from './schema.js';
|
|
7
|
-
export class StoreSql {
|
|
8
|
-
db;
|
|
9
|
-
logger;
|
|
10
|
-
authContext;
|
|
11
|
-
constructor(db, logger, authContext) {
|
|
12
|
-
this.db = db;
|
|
13
|
-
this.logger = logger;
|
|
14
|
-
this.logger = logger.child({ component: 'StoreInternal' });
|
|
15
|
-
this.authContext = authContext;
|
|
16
|
-
// this.syncWallets()
|
|
17
|
-
}
|
|
18
|
-
withAuthContext(context) {
|
|
19
|
-
return new StoreSql(this.db, this.logger, context);
|
|
20
|
-
}
|
|
21
|
-
assertConnected() {
|
|
22
|
-
return assertConnected(this.authContext).userId;
|
|
23
|
-
}
|
|
24
|
-
// Wallet methods
|
|
25
|
-
async getWallets(filter = {}) {
|
|
26
|
-
const userId = this.assertConnected();
|
|
27
|
-
const { chainIds, signingProviderIds } = filter;
|
|
28
|
-
const chainIdSet = chainIds ? new Set(chainIds) : null;
|
|
29
|
-
const signingProviderIdSet = signingProviderIds
|
|
30
|
-
? new Set(signingProviderIds)
|
|
31
|
-
: null;
|
|
32
|
-
const wallets = await this.db
|
|
33
|
-
.selectFrom('wallets')
|
|
34
|
-
.selectAll()
|
|
35
|
-
.where('userId', '=', userId)
|
|
36
|
-
.execute();
|
|
37
|
-
return wallets
|
|
38
|
-
.filter((wallet) => {
|
|
39
|
-
const matchedChainIds = chainIdSet
|
|
40
|
-
? chainIdSet.has(wallet.chainId)
|
|
41
|
-
: true;
|
|
42
|
-
const matchedStorageProviderIdS = signingProviderIdSet
|
|
43
|
-
? signingProviderIdSet.has(wallet.signingProviderId)
|
|
44
|
-
: true;
|
|
45
|
-
return matchedChainIds && matchedStorageProviderIdS;
|
|
46
|
-
})
|
|
47
|
-
.map((table) => toWallet(table));
|
|
48
|
-
}
|
|
49
|
-
async getPrimaryWallet() {
|
|
50
|
-
const wallets = await this.getWallets();
|
|
51
|
-
return wallets.find((w) => w.primary === true);
|
|
52
|
-
}
|
|
53
|
-
async setPrimaryWallet(partyId) {
|
|
54
|
-
const wallets = await this.getWallets();
|
|
55
|
-
if (!wallets.some((w) => w.partyId === partyId)) {
|
|
56
|
-
throw new Error(`Wallet with partyId "${partyId}" not found`);
|
|
57
|
-
}
|
|
58
|
-
const primary = wallets.find((w) => w.primary === true);
|
|
59
|
-
await this.db.transaction().execute(async (trx) => {
|
|
60
|
-
if (primary) {
|
|
61
|
-
await trx
|
|
62
|
-
.updateTable('wallets')
|
|
63
|
-
.set({ primary: 0 })
|
|
64
|
-
.where('partyId', '=', primary.partyId)
|
|
65
|
-
.execute();
|
|
66
|
-
}
|
|
67
|
-
await trx
|
|
68
|
-
.updateTable('wallets')
|
|
69
|
-
.set({ primary: 1 })
|
|
70
|
-
.where('partyId', '=', partyId)
|
|
71
|
-
.execute();
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
async addWallet(wallet) {
|
|
75
|
-
this.logger.info('Adding wallet');
|
|
76
|
-
const userId = this.assertConnected();
|
|
77
|
-
const wallets = await this.getWallets();
|
|
78
|
-
if (wallets.some((w) => w.partyId === wallet.partyId)) {
|
|
79
|
-
throw new Error(`Wallet with partyId "${wallet.partyId}" already exists`);
|
|
80
|
-
}
|
|
81
|
-
if (wallets.length === 0) {
|
|
82
|
-
// If this is the first wallet, set it as primary automatically
|
|
83
|
-
wallet.primary = true;
|
|
84
|
-
}
|
|
85
|
-
await this.db.transaction().execute(async (trx) => {
|
|
86
|
-
if (wallet.primary) {
|
|
87
|
-
// If the new wallet is primary, set all others to non-primary
|
|
88
|
-
await trx
|
|
89
|
-
.updateTable('wallets')
|
|
90
|
-
.set({ primary: 0 })
|
|
91
|
-
.where((eb) => eb.and([
|
|
92
|
-
eb('primary', '=', 1),
|
|
93
|
-
eb('userId', '=', userId),
|
|
94
|
-
]))
|
|
95
|
-
.execute();
|
|
96
|
-
}
|
|
97
|
-
await trx
|
|
98
|
-
.insertInto('wallets')
|
|
99
|
-
.values(fromWallet(wallet, userId))
|
|
100
|
-
.execute();
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
// Session methods
|
|
104
|
-
async getSession() {
|
|
105
|
-
const sessions = await this.db
|
|
106
|
-
.selectFrom('sessions')
|
|
107
|
-
.selectAll()
|
|
108
|
-
.executeTakeFirst();
|
|
109
|
-
return sessions;
|
|
110
|
-
}
|
|
111
|
-
async setSession(session) {
|
|
112
|
-
const userId = this.assertConnected();
|
|
113
|
-
await this.db.transaction().execute(async (trx) => {
|
|
114
|
-
await trx
|
|
115
|
-
.deleteFrom('sessions')
|
|
116
|
-
.where('userId', '=', userId)
|
|
117
|
-
.execute();
|
|
118
|
-
await trx
|
|
119
|
-
.insertInto('sessions')
|
|
120
|
-
.values({ ...session, userId })
|
|
121
|
-
.execute();
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
async removeSession() {
|
|
125
|
-
const userId = this.assertConnected();
|
|
126
|
-
await this.db
|
|
127
|
-
.deleteFrom('sessions')
|
|
128
|
-
.where('userId', '=', userId)
|
|
129
|
-
.execute();
|
|
130
|
-
}
|
|
131
|
-
// Network methods
|
|
132
|
-
async getNetwork(chainId) {
|
|
133
|
-
this.assertConnected();
|
|
134
|
-
const networks = await this.listNetworks();
|
|
135
|
-
if (!networks)
|
|
136
|
-
throw new Error('No networks available');
|
|
137
|
-
const network = networks.find((n) => n.chainId === chainId);
|
|
138
|
-
if (!network)
|
|
139
|
-
throw new Error(`Network "${chainId}" not found`);
|
|
140
|
-
return network;
|
|
141
|
-
}
|
|
142
|
-
async getCurrentNetwork() {
|
|
143
|
-
const session = await this.getSession();
|
|
144
|
-
if (!session) {
|
|
145
|
-
throw new Error('No session found');
|
|
146
|
-
}
|
|
147
|
-
const chainId = session.network;
|
|
148
|
-
if (!chainId) {
|
|
149
|
-
throw new Error('No current network set in session');
|
|
150
|
-
}
|
|
151
|
-
const networks = await this.listNetworks();
|
|
152
|
-
const network = networks.find((n) => n.chainId === chainId);
|
|
153
|
-
if (!network) {
|
|
154
|
-
throw new Error(`Network "${chainId}" not found`);
|
|
155
|
-
}
|
|
156
|
-
return network;
|
|
157
|
-
}
|
|
158
|
-
async listNetworks() {
|
|
159
|
-
let query = this.db.selectFrom('networks').selectAll();
|
|
160
|
-
if (this.authContext) {
|
|
161
|
-
const userId = this.assertConnected();
|
|
162
|
-
query = query.where((eb) => eb.or([
|
|
163
|
-
eb('userId', 'is', null), // Global networks
|
|
164
|
-
eb('userId', '=', userId), // User-specific networks
|
|
165
|
-
]));
|
|
166
|
-
}
|
|
167
|
-
else {
|
|
168
|
-
query = query.where('userId', 'is', null); // Only global networks
|
|
169
|
-
}
|
|
170
|
-
const networks = await query.execute();
|
|
171
|
-
const idps = await this.db.selectFrom('idps').selectAll().execute();
|
|
172
|
-
const idpMap = new Map(idps.map((idp) => [idp.identityProviderId, idp]));
|
|
173
|
-
return networks.map((table) => toNetwork(table, idpMap.get(table.identityProviderId)));
|
|
174
|
-
}
|
|
175
|
-
async updateNetwork(network) {
|
|
176
|
-
const userId = this.assertConnected();
|
|
177
|
-
// todo: check and compare userid of existing network
|
|
178
|
-
await this.db.transaction().execute(async (trx) => {
|
|
179
|
-
await trx
|
|
180
|
-
.updateTable('networks')
|
|
181
|
-
.set(fromNetwork(network, userId))
|
|
182
|
-
.where('chainId', '=', network.chainId)
|
|
183
|
-
.execute();
|
|
184
|
-
await trx
|
|
185
|
-
.updateTable('idps')
|
|
186
|
-
.set(fromAuth(network.auth))
|
|
187
|
-
.where('identityProviderId', '=', network.auth.identityProviderId)
|
|
188
|
-
.execute();
|
|
189
|
-
});
|
|
190
|
-
}
|
|
191
|
-
async addNetwork(network) {
|
|
192
|
-
const userId = this.authContext?.userId;
|
|
193
|
-
await this.db.transaction().execute(async (trx) => {
|
|
194
|
-
const networkAlreadyExists = await trx
|
|
195
|
-
.selectFrom('networks')
|
|
196
|
-
.selectAll()
|
|
197
|
-
.where('chainId', '=', network.chainId)
|
|
198
|
-
.executeTakeFirst();
|
|
199
|
-
if (networkAlreadyExists) {
|
|
200
|
-
throw new Error(`Network ${network.chainId} already exists`);
|
|
201
|
-
}
|
|
202
|
-
else {
|
|
203
|
-
await trx
|
|
204
|
-
.insertInto('idps')
|
|
205
|
-
.values(fromAuth(network.auth))
|
|
206
|
-
.execute();
|
|
207
|
-
await trx
|
|
208
|
-
.insertInto('networks')
|
|
209
|
-
.values(fromNetwork(network, userId))
|
|
210
|
-
.execute();
|
|
211
|
-
}
|
|
212
|
-
});
|
|
213
|
-
}
|
|
214
|
-
async removeNetwork(chainId) {
|
|
215
|
-
const userId = this.assertConnected();
|
|
216
|
-
await this.db.transaction().execute(async (trx) => {
|
|
217
|
-
const network = await trx
|
|
218
|
-
.selectFrom('networks')
|
|
219
|
-
.selectAll()
|
|
220
|
-
.where('chainId', '=', chainId)
|
|
221
|
-
.executeTakeFirst();
|
|
222
|
-
if (!network) {
|
|
223
|
-
throw new Error(`Network ${chainId} does not exists`);
|
|
224
|
-
}
|
|
225
|
-
if (network.userId !== userId) {
|
|
226
|
-
throw new Error(`Network ${chainId} is not owned by user ${userId}`);
|
|
227
|
-
}
|
|
228
|
-
await trx
|
|
229
|
-
.deleteFrom('networks')
|
|
230
|
-
.where('chainId', '=', chainId)
|
|
231
|
-
.execute();
|
|
232
|
-
await trx
|
|
233
|
-
.deleteFrom('idps')
|
|
234
|
-
.where('identityProviderId', '=', network.identityProviderId)
|
|
235
|
-
.execute();
|
|
236
|
-
});
|
|
237
|
-
}
|
|
238
|
-
// Transaction methods
|
|
239
|
-
async setTransaction(transaction) {
|
|
240
|
-
const userId = this.assertConnected();
|
|
241
|
-
const existing = await this.getTransaction(transaction.commandId);
|
|
242
|
-
if (existing) {
|
|
243
|
-
await this.db
|
|
244
|
-
.updateTable('transactions')
|
|
245
|
-
.set(fromTransaction(transaction, userId))
|
|
246
|
-
.where('commandId', '=', transaction.commandId)
|
|
247
|
-
.execute();
|
|
248
|
-
}
|
|
249
|
-
else {
|
|
250
|
-
await this.db
|
|
251
|
-
.insertInto('transactions')
|
|
252
|
-
.values(fromTransaction(transaction, userId))
|
|
253
|
-
.execute();
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
async getTransaction(commandId) {
|
|
257
|
-
const userId = this.assertConnected();
|
|
258
|
-
const transaction = await this.db
|
|
259
|
-
.selectFrom('transactions')
|
|
260
|
-
.selectAll()
|
|
261
|
-
.where((eb) => eb.and([
|
|
262
|
-
eb('commandId', '=', commandId),
|
|
263
|
-
eb('userId', '=', userId),
|
|
264
|
-
]))
|
|
265
|
-
.executeTakeFirst();
|
|
266
|
-
return transaction ? toTransaction(transaction) : undefined;
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
export const connection = (config) => {
|
|
270
|
-
switch (config.connection.type) {
|
|
271
|
-
case 'sqlite':
|
|
272
|
-
return new Kysely({
|
|
273
|
-
dialect: new SqliteDialect({
|
|
274
|
-
database: new Database(config.connection.database),
|
|
275
|
-
}),
|
|
276
|
-
plugins: [new CamelCasePlugin()],
|
|
277
|
-
});
|
|
278
|
-
case 'memory':
|
|
279
|
-
return new Kysely({
|
|
280
|
-
dialect: new SqliteDialect({
|
|
281
|
-
database: new Database(':memory:'),
|
|
282
|
-
}),
|
|
283
|
-
plugins: [new CamelCasePlugin()],
|
|
284
|
-
});
|
|
285
|
-
default:
|
|
286
|
-
throw new Error(`Unsupported database type: ${config.connection.type}`);
|
|
287
|
-
}
|
|
288
|
-
};
|
package/dist/store-sql.test.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"store-sql.test.d.ts","sourceRoot":"","sources":["../src/store-sql.test.ts"],"names":[],"mappings":""}
|