@breeztech/breez-sdk-spark 0.14.0 → 0.15.1
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/breez-sdk-spark.tgz +0 -0
- package/bundler/breez_sdk_spark_wasm.d.ts +114 -40
- package/bundler/breez_sdk_spark_wasm.js +1 -1
- package/bundler/breez_sdk_spark_wasm_bg.js +118 -104
- package/bundler/breez_sdk_spark_wasm_bg.wasm +0 -0
- package/bundler/breez_sdk_spark_wasm_bg.wasm.d.ts +12 -11
- package/deno/breez_sdk_spark_wasm.d.ts +114 -40
- package/deno/breez_sdk_spark_wasm.js +118 -104
- package/deno/breez_sdk_spark_wasm_bg.wasm +0 -0
- package/deno/breez_sdk_spark_wasm_bg.wasm.d.ts +12 -11
- package/nodejs/breez_sdk_spark_wasm.d.ts +114 -40
- package/nodejs/breez_sdk_spark_wasm.js +121 -106
- package/nodejs/breez_sdk_spark_wasm_bg.wasm +0 -0
- package/nodejs/breez_sdk_spark_wasm_bg.wasm.d.ts +12 -11
- package/nodejs/index.mjs +3 -2
- package/nodejs/mysql-session-manager/index.cjs +26 -8
- package/nodejs/mysql-session-manager/migrations.cjs +40 -3
- package/nodejs/mysql-storage/index.cjs +67 -48
- package/nodejs/mysql-storage/migrations.cjs +220 -85
- package/nodejs/mysql-token-store/index.cjs +133 -68
- package/nodejs/mysql-token-store/migrations.cjs +309 -80
- package/nodejs/mysql-tree-store/index.cjs +76 -41
- package/nodejs/mysql-tree-store/migrations.cjs +254 -71
- package/nodejs/postgres-session-manager/index.cjs +27 -9
- package/nodejs/postgres-session-manager/migrations.cjs +45 -6
- package/nodejs/postgres-storage/index.cjs +81 -62
- package/nodejs/postgres-storage/migrations.cjs +207 -79
- package/nodejs/postgres-token-store/index.cjs +111 -67
- package/nodejs/postgres-token-store/migrations.cjs +153 -61
- package/nodejs/postgres-tree-store/index.cjs +60 -42
- package/nodejs/postgres-tree-store/migrations.cjs +130 -46
- package/package.json +1 -1
- package/ssr/index.js +14 -9
- package/web/breez_sdk_spark_wasm.d.ts +126 -51
- package/web/breez_sdk_spark_wasm.js +118 -104
- package/web/breez_sdk_spark_wasm_bg.wasm +0 -0
- package/web/breez_sdk_spark_wasm_bg.wasm.d.ts +12 -11
|
@@ -78,9 +78,19 @@ class MysqlTreeStore {
|
|
|
78
78
|
* @param {import('mysql2/promise').Pool} pool
|
|
79
79
|
* @param {Buffer|Uint8Array} identity - 33-byte secp256k1 compressed pubkey
|
|
80
80
|
* identifying the tenant. All reads and writes are scoped by this.
|
|
81
|
+
* @param {"Enforced"|"Disabled"} [foreignKeyMode="Enforced"] - whether
|
|
82
|
+
* migrations create database-enforced foreign keys.
|
|
81
83
|
* @param {object} [logger]
|
|
84
|
+
* @param {boolean} [runMigration=true] - whether to run schema migrations
|
|
85
|
+
* on initialize.
|
|
82
86
|
*/
|
|
83
|
-
constructor(
|
|
87
|
+
constructor(
|
|
88
|
+
pool,
|
|
89
|
+
identity,
|
|
90
|
+
foreignKeyMode = "Enforced",
|
|
91
|
+
logger = null,
|
|
92
|
+
runMigration = true
|
|
93
|
+
) {
|
|
84
94
|
if (!identity || identity.length !== 33) {
|
|
85
95
|
throw new TreeStoreError(
|
|
86
96
|
"tenant identity (33-byte secp256k1 pubkey) is required"
|
|
@@ -89,13 +99,20 @@ class MysqlTreeStore {
|
|
|
89
99
|
this.pool = pool;
|
|
90
100
|
this.identity = Buffer.from(identity);
|
|
91
101
|
this.lockName = _identityLockName(TREE_STORE_LOCK_PREFIX, identity);
|
|
102
|
+
this.foreignKeyMode = foreignKeyMode;
|
|
92
103
|
this.logger = logger;
|
|
104
|
+
this.runMigration = runMigration;
|
|
93
105
|
}
|
|
94
106
|
|
|
95
107
|
async initialize() {
|
|
96
108
|
try {
|
|
97
|
-
|
|
98
|
-
|
|
109
|
+
if (this.runMigration) {
|
|
110
|
+
const migrationManager = new MysqlTreeStoreMigrationManager(
|
|
111
|
+
this.logger,
|
|
112
|
+
this.foreignKeyMode
|
|
113
|
+
);
|
|
114
|
+
await migrationManager.migrate(this.pool, this.identity);
|
|
115
|
+
}
|
|
99
116
|
return this;
|
|
100
117
|
} catch (error) {
|
|
101
118
|
throw new TreeStoreError(
|
|
@@ -209,8 +226,8 @@ class MysqlTreeStore {
|
|
|
209
226
|
try {
|
|
210
227
|
const [rows] = await this.pool.query(
|
|
211
228
|
`SELECT COALESCE(SUM(l.value), 0) AS balance
|
|
212
|
-
FROM
|
|
213
|
-
LEFT JOIN
|
|
229
|
+
FROM brz_tree_leaves l
|
|
230
|
+
LEFT JOIN brz_tree_reservations r
|
|
214
231
|
ON l.reservation_id = r.id AND l.user_id = r.user_id
|
|
215
232
|
WHERE l.user_id = ?
|
|
216
233
|
AND (
|
|
@@ -233,8 +250,8 @@ class MysqlTreeStore {
|
|
|
233
250
|
const [rows] = await this.pool.query(
|
|
234
251
|
`SELECT l.id, l.status, l.is_missing_from_operators, l.data,
|
|
235
252
|
l.reservation_id, r.purpose
|
|
236
|
-
FROM
|
|
237
|
-
LEFT JOIN
|
|
253
|
+
FROM brz_tree_leaves l
|
|
254
|
+
LEFT JOIN brz_tree_reservations r
|
|
238
255
|
ON l.reservation_id = r.id AND l.user_id = r.user_id
|
|
239
256
|
WHERE l.user_id = ?`,
|
|
240
257
|
[this.identity]
|
|
@@ -298,9 +315,9 @@ class MysqlTreeStore {
|
|
|
298
315
|
|
|
299
316
|
const [swapRows] = await conn.query(
|
|
300
317
|
`SELECT
|
|
301
|
-
(SELECT EXISTS(SELECT 1 FROM
|
|
318
|
+
(SELECT EXISTS(SELECT 1 FROM brz_tree_reservations WHERE user_id = ? AND purpose = 'Swap')) AS has_active_swap,
|
|
302
319
|
COALESCE(
|
|
303
|
-
(SELECT (last_completed_at >= ?) FROM
|
|
320
|
+
(SELECT (last_completed_at >= ?) FROM brz_tree_swap_status WHERE user_id = ?),
|
|
304
321
|
0
|
|
305
322
|
) AS swap_completed_during_refresh`,
|
|
306
323
|
[this.identity, refreshTimestamp, this.identity]
|
|
@@ -315,7 +332,7 @@ class MysqlTreeStore {
|
|
|
315
332
|
await this._cleanupSpentMarkers(conn, refreshTimestamp);
|
|
316
333
|
|
|
317
334
|
const [spentRows] = await conn.query(
|
|
318
|
-
"SELECT leaf_id FROM
|
|
335
|
+
"SELECT leaf_id FROM brz_tree_spent_leaves WHERE user_id = ? AND spent_at >= ?",
|
|
319
336
|
[this.identity, refreshTimestamp]
|
|
320
337
|
);
|
|
321
338
|
const spentIds = new Set(spentRows.map((r) => r.leaf_id));
|
|
@@ -324,7 +341,7 @@ class MysqlTreeStore {
|
|
|
324
341
|
// _cleanupStaleReservations (which now NULLs reservation_id explicitly,
|
|
325
342
|
// since the composite FK uses NO ACTION).
|
|
326
343
|
await conn.query(
|
|
327
|
-
"DELETE FROM
|
|
344
|
+
"DELETE FROM brz_tree_leaves WHERE user_id = ? AND reservation_id IS NULL AND added_at < ?",
|
|
328
345
|
[this.identity, refreshTimestamp]
|
|
329
346
|
);
|
|
330
347
|
|
|
@@ -344,7 +361,7 @@ class MysqlTreeStore {
|
|
|
344
361
|
try {
|
|
345
362
|
await this._withTransaction(async (conn) => {
|
|
346
363
|
const [existsRows] = await conn.query(
|
|
347
|
-
"SELECT id FROM
|
|
364
|
+
"SELECT id FROM brz_tree_reservations WHERE user_id = ? AND id = ?",
|
|
348
365
|
[this.identity, id]
|
|
349
366
|
);
|
|
350
367
|
|
|
@@ -353,11 +370,11 @@ class MysqlTreeStore {
|
|
|
353
370
|
}
|
|
354
371
|
|
|
355
372
|
await conn.query(
|
|
356
|
-
"DELETE FROM
|
|
373
|
+
"DELETE FROM brz_tree_leaves WHERE user_id = ? AND reservation_id = ?",
|
|
357
374
|
[this.identity, id]
|
|
358
375
|
);
|
|
359
376
|
await conn.query(
|
|
360
|
-
"DELETE FROM
|
|
377
|
+
"DELETE FROM brz_tree_reservations WHERE user_id = ? AND id = ?",
|
|
361
378
|
[this.identity, id]
|
|
362
379
|
);
|
|
363
380
|
|
|
@@ -378,11 +395,11 @@ class MysqlTreeStore {
|
|
|
378
395
|
try {
|
|
379
396
|
// _withWriteTransaction acquires the GET_LOCK so this serializes
|
|
380
397
|
// against `setLeaves`. Without it, a concurrent setLeaves could read
|
|
381
|
-
//
|
|
398
|
+
// brz_tree_spent_leaves before our marker commits and re-insert the
|
|
382
399
|
// just-spent leaf as Available.
|
|
383
400
|
await this._withWriteTransaction(async (conn) => {
|
|
384
401
|
const [resRows] = await conn.query(
|
|
385
|
-
"SELECT id, purpose FROM
|
|
402
|
+
"SELECT id, purpose FROM brz_tree_reservations WHERE user_id = ? AND id = ?",
|
|
386
403
|
[this.identity, id]
|
|
387
404
|
);
|
|
388
405
|
|
|
@@ -390,17 +407,17 @@ class MysqlTreeStore {
|
|
|
390
407
|
if (resRows.length > 0) {
|
|
391
408
|
isSwap = resRows[0].purpose === "Swap";
|
|
392
409
|
const [leafRows] = await conn.query(
|
|
393
|
-
"SELECT id FROM
|
|
410
|
+
"SELECT id FROM brz_tree_leaves WHERE user_id = ? AND reservation_id = ?",
|
|
394
411
|
[this.identity, id]
|
|
395
412
|
);
|
|
396
413
|
const reservedLeafIds = leafRows.map((r) => r.id);
|
|
397
414
|
await this._batchInsertSpentLeaves(conn, reservedLeafIds);
|
|
398
415
|
await conn.query(
|
|
399
|
-
"DELETE FROM
|
|
416
|
+
"DELETE FROM brz_tree_leaves WHERE user_id = ? AND reservation_id = ?",
|
|
400
417
|
[this.identity, id]
|
|
401
418
|
);
|
|
402
419
|
await conn.query(
|
|
403
|
-
"DELETE FROM
|
|
420
|
+
"DELETE FROM brz_tree_reservations WHERE user_id = ? AND id = ?",
|
|
404
421
|
[this.identity, id]
|
|
405
422
|
);
|
|
406
423
|
}
|
|
@@ -413,7 +430,7 @@ class MysqlTreeStore {
|
|
|
413
430
|
// (and thus has no row) gets one created lazily.
|
|
414
431
|
if (isSwap && newLeaves && newLeaves.length > 0) {
|
|
415
432
|
await conn.query(
|
|
416
|
-
`INSERT INTO
|
|
433
|
+
`INSERT INTO brz_tree_swap_status (user_id, last_completed_at) VALUES (?, NOW(6))
|
|
417
434
|
ON DUPLICATE KEY UPDATE last_completed_at = VALUES(last_completed_at)`,
|
|
418
435
|
[this.identity]
|
|
419
436
|
);
|
|
@@ -436,7 +453,7 @@ class MysqlTreeStore {
|
|
|
436
453
|
|
|
437
454
|
const [totalRows] = await conn.query(
|
|
438
455
|
`SELECT COALESCE(SUM(value), 0) AS total
|
|
439
|
-
FROM
|
|
456
|
+
FROM brz_tree_leaves
|
|
440
457
|
WHERE user_id = ?
|
|
441
458
|
AND status = 'Available'
|
|
442
459
|
AND is_missing_from_operators = 0
|
|
@@ -447,7 +464,7 @@ class MysqlTreeStore {
|
|
|
447
464
|
|
|
448
465
|
const [slimRows] = await conn.query(
|
|
449
466
|
`SELECT id, value
|
|
450
|
-
FROM
|
|
467
|
+
FROM brz_tree_leaves
|
|
451
468
|
WHERE user_id = ?
|
|
452
469
|
AND status = 'Available'
|
|
453
470
|
AND is_missing_from_operators = 0
|
|
@@ -456,7 +473,7 @@ class MysqlTreeStore {
|
|
|
456
473
|
value <= ?
|
|
457
474
|
OR id = (
|
|
458
475
|
SELECT id FROM (
|
|
459
|
-
SELECT id FROM
|
|
476
|
+
SELECT id FROM brz_tree_leaves
|
|
460
477
|
WHERE user_id = ?
|
|
461
478
|
AND status = 'Available'
|
|
462
479
|
AND is_missing_from_operators = 0
|
|
@@ -581,7 +598,7 @@ class MysqlTreeStore {
|
|
|
581
598
|
try {
|
|
582
599
|
return await this._withTransaction(async (conn) => {
|
|
583
600
|
const [existsRows] = await conn.query(
|
|
584
|
-
"SELECT id FROM
|
|
601
|
+
"SELECT id FROM brz_tree_reservations WHERE user_id = ? AND id = ?",
|
|
585
602
|
[this.identity, reservationId]
|
|
586
603
|
);
|
|
587
604
|
|
|
@@ -590,14 +607,14 @@ class MysqlTreeStore {
|
|
|
590
607
|
}
|
|
591
608
|
|
|
592
609
|
const [oldLeafRows] = await conn.query(
|
|
593
|
-
"SELECT id FROM
|
|
610
|
+
"SELECT id FROM brz_tree_leaves WHERE user_id = ? AND reservation_id = ?",
|
|
594
611
|
[this.identity, reservationId]
|
|
595
612
|
);
|
|
596
613
|
const oldLeafIds = oldLeafRows.map((r) => r.id);
|
|
597
614
|
|
|
598
615
|
await this._batchInsertSpentLeaves(conn, oldLeafIds);
|
|
599
616
|
await conn.query(
|
|
600
|
-
"DELETE FROM
|
|
617
|
+
"DELETE FROM brz_tree_leaves WHERE user_id = ? AND reservation_id = ?",
|
|
601
618
|
[this.identity, reservationId]
|
|
602
619
|
);
|
|
603
620
|
|
|
@@ -608,7 +625,7 @@ class MysqlTreeStore {
|
|
|
608
625
|
await this._batchSetReservationId(conn, reservationId, reservedLeafIds);
|
|
609
626
|
|
|
610
627
|
await conn.query(
|
|
611
|
-
"UPDATE
|
|
628
|
+
"UPDATE brz_tree_reservations SET pending_change_amount = 0 WHERE user_id = ? AND id = ?",
|
|
612
629
|
[this.identity, reservationId]
|
|
613
630
|
);
|
|
614
631
|
|
|
@@ -665,7 +682,7 @@ class MysqlTreeStore {
|
|
|
665
682
|
if (!ids || ids.length === 0) return [];
|
|
666
683
|
const placeholders = ids.map(() => "?").join(", ");
|
|
667
684
|
const [rows] = await conn.query(
|
|
668
|
-
`SELECT data FROM
|
|
685
|
+
`SELECT data FROM brz_tree_leaves WHERE user_id = ? AND id IN (${placeholders})`,
|
|
669
686
|
[this.identity, ...ids]
|
|
670
687
|
);
|
|
671
688
|
return rows.map((r) => parseJson(r.data));
|
|
@@ -784,7 +801,7 @@ class MysqlTreeStore {
|
|
|
784
801
|
|
|
785
802
|
async _calculatePendingBalance(conn) {
|
|
786
803
|
const [rows] = await conn.query(
|
|
787
|
-
"SELECT COALESCE(SUM(pending_change_amount), 0) AS pending FROM
|
|
804
|
+
"SELECT COALESCE(SUM(pending_change_amount), 0) AS pending FROM brz_tree_reservations WHERE user_id = ?",
|
|
788
805
|
[this.identity]
|
|
789
806
|
);
|
|
790
807
|
return Number(rows[0].pending);
|
|
@@ -792,7 +809,7 @@ class MysqlTreeStore {
|
|
|
792
809
|
|
|
793
810
|
async _createReservation(conn, reservationId, leaves, purpose, pendingChange) {
|
|
794
811
|
await conn.query(
|
|
795
|
-
"INSERT INTO
|
|
812
|
+
"INSERT INTO brz_tree_reservations (user_id, id, purpose, pending_change_amount) VALUES (?, ?, ?, ?)",
|
|
796
813
|
[this.identity, reservationId, purpose, pendingChange]
|
|
797
814
|
);
|
|
798
815
|
|
|
@@ -825,7 +842,7 @@ class MysqlTreeStore {
|
|
|
825
842
|
}
|
|
826
843
|
|
|
827
844
|
await conn.query(
|
|
828
|
-
`INSERT INTO
|
|
845
|
+
`INSERT INTO brz_tree_leaves (user_id, id, status, is_missing_from_operators, data, value, added_at)
|
|
829
846
|
VALUES ${valueClauses}
|
|
830
847
|
ON DUPLICATE KEY UPDATE
|
|
831
848
|
status = VALUES(status),
|
|
@@ -842,7 +859,7 @@ class MysqlTreeStore {
|
|
|
842
859
|
|
|
843
860
|
const placeholders = buildPlaceholders(leafIds.length);
|
|
844
861
|
await conn.query(
|
|
845
|
-
`UPDATE
|
|
862
|
+
`UPDATE brz_tree_leaves SET reservation_id = ? WHERE user_id = ? AND id IN (${placeholders})`,
|
|
846
863
|
[reservationId, this.identity, ...leafIds]
|
|
847
864
|
);
|
|
848
865
|
}
|
|
@@ -859,7 +876,7 @@ class MysqlTreeStore {
|
|
|
859
876
|
// problems (FK violations, NOT NULL violations, type errors) still
|
|
860
877
|
// propagate.
|
|
861
878
|
await conn.query(
|
|
862
|
-
`INSERT INTO
|
|
879
|
+
`INSERT INTO brz_tree_spent_leaves (user_id, leaf_id) VALUES ${valueClauses}
|
|
863
880
|
ON DUPLICATE KEY UPDATE leaf_id = leaf_id`,
|
|
864
881
|
params
|
|
865
882
|
);
|
|
@@ -870,7 +887,7 @@ class MysqlTreeStore {
|
|
|
870
887
|
|
|
871
888
|
const placeholders = buildPlaceholders(leafIds.length);
|
|
872
889
|
await conn.query(
|
|
873
|
-
`DELETE FROM
|
|
890
|
+
`DELETE FROM brz_tree_spent_leaves WHERE user_id = ? AND leaf_id IN (${placeholders})`,
|
|
874
891
|
[this.identity, ...leafIds]
|
|
875
892
|
);
|
|
876
893
|
}
|
|
@@ -881,11 +898,11 @@ class MysqlTreeStore {
|
|
|
881
898
|
/// user_id (NOT NULL).
|
|
882
899
|
async _cleanupStaleReservations(conn) {
|
|
883
900
|
await conn.query(
|
|
884
|
-
`UPDATE
|
|
901
|
+
`UPDATE brz_tree_leaves SET reservation_id = NULL
|
|
885
902
|
WHERE user_id = ?
|
|
886
903
|
AND reservation_id IN (
|
|
887
904
|
SELECT id FROM (
|
|
888
|
-
SELECT id FROM
|
|
905
|
+
SELECT id FROM brz_tree_reservations
|
|
889
906
|
WHERE user_id = ?
|
|
890
907
|
AND created_at < DATE_SUB(NOW(6), INTERVAL ? SECOND)
|
|
891
908
|
) AS stale
|
|
@@ -893,7 +910,7 @@ class MysqlTreeStore {
|
|
|
893
910
|
[this.identity, this.identity, RESERVATION_TIMEOUT_SECS]
|
|
894
911
|
);
|
|
895
912
|
await conn.query(
|
|
896
|
-
`DELETE FROM
|
|
913
|
+
`DELETE FROM brz_tree_reservations
|
|
897
914
|
WHERE user_id = ? AND created_at < DATE_SUB(NOW(6), INTERVAL ? SECOND)`,
|
|
898
915
|
[this.identity, RESERVATION_TIMEOUT_SECS]
|
|
899
916
|
);
|
|
@@ -905,7 +922,7 @@ class MysqlTreeStore {
|
|
|
905
922
|
);
|
|
906
923
|
|
|
907
924
|
await conn.query(
|
|
908
|
-
"DELETE FROM
|
|
925
|
+
"DELETE FROM brz_tree_spent_leaves WHERE user_id = ? AND spent_at < ?",
|
|
909
926
|
[this.identity, cleanupCutoff]
|
|
910
927
|
);
|
|
911
928
|
}
|
|
@@ -924,11 +941,29 @@ function createMysqlPool(config) {
|
|
|
924
941
|
|
|
925
942
|
async function createMysqlTreeStore(config, identity, logger = null) {
|
|
926
943
|
const pool = createMysqlPool(config);
|
|
927
|
-
return createMysqlTreeStoreWithPool(
|
|
944
|
+
return createMysqlTreeStoreWithPool(
|
|
945
|
+
pool,
|
|
946
|
+
identity,
|
|
947
|
+
config.foreignKeyMode || "Enforced",
|
|
948
|
+
logger,
|
|
949
|
+
config.runMigration !== false
|
|
950
|
+
);
|
|
928
951
|
}
|
|
929
952
|
|
|
930
|
-
async function createMysqlTreeStoreWithPool(
|
|
931
|
-
|
|
953
|
+
async function createMysqlTreeStoreWithPool(
|
|
954
|
+
pool,
|
|
955
|
+
identity,
|
|
956
|
+
foreignKeyMode = "Enforced",
|
|
957
|
+
logger = null,
|
|
958
|
+
runMigration = true
|
|
959
|
+
) {
|
|
960
|
+
const store = new MysqlTreeStore(
|
|
961
|
+
pool,
|
|
962
|
+
identity,
|
|
963
|
+
foreignKeyMode,
|
|
964
|
+
logger,
|
|
965
|
+
runMigration
|
|
966
|
+
);
|
|
932
967
|
await store.initialize();
|
|
933
968
|
return store;
|
|
934
969
|
}
|