@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
|
@@ -71,9 +71,19 @@ class MysqlTokenStore {
|
|
|
71
71
|
* @param {import('mysql2/promise').Pool} pool
|
|
72
72
|
* @param {Buffer|Uint8Array} identity - 33-byte secp256k1 compressed pubkey
|
|
73
73
|
* identifying the tenant. All reads and writes are scoped by this.
|
|
74
|
+
* @param {"Enforced"|"Disabled"} [foreignKeyMode="Enforced"] - whether
|
|
75
|
+
* migrations create database-enforced foreign keys.
|
|
74
76
|
* @param {object} [logger]
|
|
77
|
+
* @param {boolean} [runMigration=true] - whether to run schema migrations
|
|
78
|
+
* on initialize.
|
|
75
79
|
*/
|
|
76
|
-
constructor(
|
|
80
|
+
constructor(
|
|
81
|
+
pool,
|
|
82
|
+
identity,
|
|
83
|
+
foreignKeyMode = "Enforced",
|
|
84
|
+
logger = null,
|
|
85
|
+
runMigration = true
|
|
86
|
+
) {
|
|
77
87
|
if (!identity || identity.length !== 33) {
|
|
78
88
|
throw new TokenStoreError(
|
|
79
89
|
"tenant identity (33-byte secp256k1 pubkey) is required"
|
|
@@ -82,13 +92,20 @@ class MysqlTokenStore {
|
|
|
82
92
|
this.pool = pool;
|
|
83
93
|
this.identity = Buffer.from(identity);
|
|
84
94
|
this.lockName = _identityLockName(TOKEN_STORE_LOCK_PREFIX, identity);
|
|
95
|
+
this.foreignKeyMode = foreignKeyMode;
|
|
85
96
|
this.logger = logger;
|
|
97
|
+
this.runMigration = runMigration;
|
|
86
98
|
}
|
|
87
99
|
|
|
88
100
|
async initialize() {
|
|
89
101
|
try {
|
|
90
|
-
|
|
91
|
-
|
|
102
|
+
if (this.runMigration) {
|
|
103
|
+
const migrationManager = new MysqlTokenStoreMigrationManager(
|
|
104
|
+
this.logger,
|
|
105
|
+
this.foreignKeyMode
|
|
106
|
+
);
|
|
107
|
+
await migrationManager.migrate(this.pool, this.identity);
|
|
108
|
+
}
|
|
92
109
|
return this;
|
|
93
110
|
} catch (error) {
|
|
94
111
|
throw new TokenStoreError(
|
|
@@ -187,9 +204,9 @@ class MysqlTokenStore {
|
|
|
187
204
|
|
|
188
205
|
const [swapRows] = await conn.query(
|
|
189
206
|
`SELECT
|
|
190
|
-
(SELECT EXISTS(SELECT 1 FROM
|
|
207
|
+
(SELECT EXISTS(SELECT 1 FROM brz_token_reservations WHERE user_id = ? AND purpose = 'Swap')) AS has_active_swap,
|
|
191
208
|
COALESCE(
|
|
192
|
-
(SELECT (last_completed_at >= ?) FROM
|
|
209
|
+
(SELECT (last_completed_at >= ?) FROM brz_token_swap_status WHERE user_id = ?),
|
|
193
210
|
0
|
|
194
211
|
) AS swap_completed`,
|
|
195
212
|
[this.identity, refreshTimestamp, this.identity]
|
|
@@ -204,18 +221,18 @@ class MysqlTokenStore {
|
|
|
204
221
|
refreshTimestamp.getTime() - SPENT_MARKER_CLEANUP_THRESHOLD_MS
|
|
205
222
|
);
|
|
206
223
|
await conn.query(
|
|
207
|
-
"DELETE FROM
|
|
224
|
+
"DELETE FROM brz_token_spent_outputs WHERE user_id = ? AND spent_at < ?",
|
|
208
225
|
[this.identity, cleanupCutoff]
|
|
209
226
|
);
|
|
210
227
|
|
|
211
228
|
const [spentRows] = await conn.query(
|
|
212
|
-
"SELECT output_id FROM
|
|
229
|
+
"SELECT output_id FROM brz_token_spent_outputs WHERE user_id = ? AND spent_at >= ?",
|
|
213
230
|
[this.identity, refreshTimestamp]
|
|
214
231
|
);
|
|
215
232
|
const spentIds = new Set(spentRows.map((r) => r.output_id));
|
|
216
233
|
|
|
217
234
|
await conn.query(
|
|
218
|
-
"DELETE FROM
|
|
235
|
+
"DELETE FROM brz_token_outputs WHERE user_id = ? AND reservation_id IS NULL AND added_at < ?",
|
|
219
236
|
[this.identity, refreshTimestamp]
|
|
220
237
|
);
|
|
221
238
|
|
|
@@ -228,8 +245,8 @@ class MysqlTokenStore {
|
|
|
228
245
|
|
|
229
246
|
const [reservedRows] = await conn.query(
|
|
230
247
|
`SELECT r.id, o.id AS output_id
|
|
231
|
-
FROM
|
|
232
|
-
JOIN
|
|
248
|
+
FROM brz_token_reservations r
|
|
249
|
+
JOIN brz_token_outputs o
|
|
233
250
|
ON o.reservation_id = r.id AND o.user_id = r.user_id
|
|
234
251
|
WHERE r.user_id = ?`,
|
|
235
252
|
[this.identity]
|
|
@@ -261,11 +278,11 @@ class MysqlTokenStore {
|
|
|
261
278
|
if (reservationsToDelete.length > 0) {
|
|
262
279
|
const placeholders = buildPlaceholders(reservationsToDelete.length);
|
|
263
280
|
await conn.query(
|
|
264
|
-
`DELETE FROM
|
|
281
|
+
`DELETE FROM brz_token_outputs WHERE user_id = ? AND reservation_id IN (${placeholders})`,
|
|
265
282
|
[this.identity, ...reservationsToDelete]
|
|
266
283
|
);
|
|
267
284
|
await conn.query(
|
|
268
|
-
`DELETE FROM
|
|
285
|
+
`DELETE FROM brz_token_reservations WHERE user_id = ? AND id IN (${placeholders})`,
|
|
269
286
|
[this.identity, ...reservationsToDelete]
|
|
270
287
|
);
|
|
271
288
|
}
|
|
@@ -275,13 +292,13 @@ class MysqlTokenStore {
|
|
|
275
292
|
outputsToRemoveFromReservation.length
|
|
276
293
|
);
|
|
277
294
|
await conn.query(
|
|
278
|
-
`DELETE FROM
|
|
295
|
+
`DELETE FROM brz_token_outputs WHERE user_id = ? AND id IN (${placeholders})`,
|
|
279
296
|
[this.identity, ...outputsToRemoveFromReservation]
|
|
280
297
|
);
|
|
281
298
|
|
|
282
299
|
const [emptyRows] = await conn.query(
|
|
283
|
-
`SELECT r.id FROM
|
|
284
|
-
LEFT JOIN
|
|
300
|
+
`SELECT r.id FROM brz_token_reservations r
|
|
301
|
+
LEFT JOIN brz_token_outputs o
|
|
285
302
|
ON o.reservation_id = r.id AND o.user_id = r.user_id
|
|
286
303
|
WHERE r.user_id = ? AND o.id IS NULL`,
|
|
287
304
|
[this.identity]
|
|
@@ -290,23 +307,23 @@ class MysqlTokenStore {
|
|
|
290
307
|
if (emptyIds.length > 0) {
|
|
291
308
|
const emptyPlaceholders = buildPlaceholders(emptyIds.length);
|
|
292
309
|
await conn.query(
|
|
293
|
-
`DELETE FROM
|
|
310
|
+
`DELETE FROM brz_token_reservations WHERE user_id = ? AND id IN (${emptyPlaceholders})`,
|
|
294
311
|
[this.identity, ...emptyIds]
|
|
295
312
|
);
|
|
296
313
|
}
|
|
297
314
|
}
|
|
298
315
|
|
|
299
316
|
const [reservedOutputRows] = await conn.query(
|
|
300
|
-
"SELECT id FROM
|
|
317
|
+
"SELECT id FROM brz_token_outputs WHERE user_id = ? AND reservation_id IS NOT NULL",
|
|
301
318
|
[this.identity]
|
|
302
319
|
);
|
|
303
320
|
const reservedOutputIds = new Set(reservedOutputRows.map((r) => r.id));
|
|
304
321
|
|
|
305
322
|
await conn.query(
|
|
306
|
-
`DELETE FROM
|
|
323
|
+
`DELETE FROM brz_token_metadata
|
|
307
324
|
WHERE user_id = ?
|
|
308
325
|
AND identifier NOT IN (
|
|
309
|
-
SELECT DISTINCT token_identifier FROM
|
|
326
|
+
SELECT DISTINCT token_identifier FROM brz_token_outputs WHERE user_id = ?
|
|
310
327
|
)`,
|
|
311
328
|
[this.identity, this.identity]
|
|
312
329
|
);
|
|
@@ -357,10 +374,10 @@ class MysqlTokenStore {
|
|
|
357
374
|
ELSE 0
|
|
358
375
|
END
|
|
359
376
|
), 0) AS CHAR) AS balance
|
|
360
|
-
FROM
|
|
361
|
-
JOIN
|
|
377
|
+
FROM brz_token_metadata m
|
|
378
|
+
JOIN brz_token_outputs o
|
|
362
379
|
ON o.token_identifier = m.identifier AND o.user_id = m.user_id
|
|
363
|
-
LEFT JOIN
|
|
380
|
+
LEFT JOIN brz_token_reservations r
|
|
364
381
|
ON o.reservation_id = r.id AND o.user_id = r.user_id
|
|
365
382
|
WHERE m.user_id = ?
|
|
366
383
|
GROUP BY m.identifier, m.issuer_public_key, m.name, m.ticker,
|
|
@@ -398,10 +415,10 @@ class MysqlTokenStore {
|
|
|
398
415
|
o.token_public_key, o.token_amount, o.token_identifier,
|
|
399
416
|
o.prev_tx_hash, o.prev_tx_vout, o.reservation_id,
|
|
400
417
|
r.purpose
|
|
401
|
-
FROM
|
|
402
|
-
LEFT JOIN
|
|
418
|
+
FROM brz_token_metadata m
|
|
419
|
+
LEFT JOIN brz_token_outputs o
|
|
403
420
|
ON o.token_identifier = m.identifier AND o.user_id = m.user_id
|
|
404
|
-
LEFT JOIN
|
|
421
|
+
LEFT JOIN brz_token_reservations r
|
|
405
422
|
ON o.reservation_id = r.id AND o.user_id = r.user_id
|
|
406
423
|
WHERE m.user_id = ?
|
|
407
424
|
ORDER BY m.identifier, CAST(o.token_amount AS DECIMAL(65,0)) ASC`,
|
|
@@ -470,10 +487,10 @@ class MysqlTokenStore {
|
|
|
470
487
|
o.token_public_key, o.token_amount, o.token_identifier,
|
|
471
488
|
o.prev_tx_hash, o.prev_tx_vout, o.reservation_id,
|
|
472
489
|
r.purpose
|
|
473
|
-
FROM
|
|
474
|
-
LEFT JOIN
|
|
490
|
+
FROM brz_token_metadata m
|
|
491
|
+
LEFT JOIN brz_token_outputs o
|
|
475
492
|
ON o.token_identifier = m.identifier AND o.user_id = m.user_id
|
|
476
|
-
LEFT JOIN
|
|
493
|
+
LEFT JOIN brz_token_reservations r
|
|
477
494
|
ON o.reservation_id = r.id AND o.user_id = r.user_id
|
|
478
495
|
WHERE m.user_id = ? AND ${whereClause}
|
|
479
496
|
ORDER BY CAST(o.token_amount AS DECIMAL(65,0)) ASC`,
|
|
@@ -518,32 +535,62 @@ class MysqlTokenStore {
|
|
|
518
535
|
}
|
|
519
536
|
}
|
|
520
537
|
|
|
521
|
-
|
|
538
|
+
/**
|
|
539
|
+
* Atomically remove spent outputs and insert new outputs.
|
|
540
|
+
* @param {Array<[string, number]>} outputsToRemove - Array of [prevTxHash, prevTxVout] tuples
|
|
541
|
+
* @param {Object|null} outputsToAdd - Token outputs to insert (with metadata)
|
|
542
|
+
* @returns {Promise<void>}
|
|
543
|
+
*/
|
|
544
|
+
async updateTokenOutputs(outputsToRemove, outputsToAdd) {
|
|
522
545
|
try {
|
|
523
546
|
await this._withTransaction(async (conn) => {
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
547
|
+
// 1. Remove spent outputs and mark as spent.
|
|
548
|
+
if (outputsToRemove && outputsToRemove.length > 0) {
|
|
549
|
+
for (const [txHash, vout] of outputsToRemove) {
|
|
550
|
+
const [rows] = await conn.query(
|
|
551
|
+
"SELECT id FROM brz_token_outputs WHERE user_id = ? AND prev_tx_hash = ? AND prev_tx_vout = ?",
|
|
552
|
+
[this.identity, txHash, vout]
|
|
553
|
+
);
|
|
554
|
+
if (rows.length > 0) {
|
|
555
|
+
const outputId = rows[0].id;
|
|
556
|
+
await conn.query(
|
|
557
|
+
"DELETE FROM brz_token_outputs WHERE user_id = ? AND id = ?",
|
|
558
|
+
[this.identity, outputId]
|
|
559
|
+
);
|
|
560
|
+
await conn.query(
|
|
561
|
+
"INSERT IGNORE INTO brz_token_spent_outputs (user_id, output_id, spent_at) VALUES (?, ?, NOW())",
|
|
562
|
+
[this.identity, outputId]
|
|
563
|
+
);
|
|
564
|
+
}
|
|
565
|
+
}
|
|
533
566
|
}
|
|
534
567
|
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
)
|
|
568
|
+
// 2. Insert new outputs.
|
|
569
|
+
if (outputsToAdd) {
|
|
570
|
+
await this._upsertMetadata(conn, outputsToAdd.metadata);
|
|
571
|
+
|
|
572
|
+
const outputIds = outputsToAdd.outputs.map((o) => o.output.id);
|
|
573
|
+
if (outputIds.length > 0) {
|
|
574
|
+
const placeholders = buildPlaceholders(outputIds.length);
|
|
575
|
+
await conn.query(
|
|
576
|
+
`DELETE FROM brz_token_spent_outputs WHERE user_id = ? AND output_id IN (${placeholders})`,
|
|
577
|
+
[this.identity, ...outputIds]
|
|
578
|
+
);
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
for (const output of outputsToAdd.outputs) {
|
|
582
|
+
await this._insertSingleOutput(
|
|
583
|
+
conn,
|
|
584
|
+
outputsToAdd.metadata.identifier,
|
|
585
|
+
output
|
|
586
|
+
);
|
|
587
|
+
}
|
|
541
588
|
}
|
|
542
589
|
});
|
|
543
590
|
} catch (error) {
|
|
544
591
|
if (error instanceof TokenStoreError) throw error;
|
|
545
592
|
throw new TokenStoreError(
|
|
546
|
-
`Failed to
|
|
593
|
+
`Failed to update token outputs: ${error.message}`,
|
|
547
594
|
error
|
|
548
595
|
);
|
|
549
596
|
}
|
|
@@ -576,7 +623,7 @@ class MysqlTokenStore {
|
|
|
576
623
|
}
|
|
577
624
|
|
|
578
625
|
const [metadataRows] = await conn.query(
|
|
579
|
-
"SELECT * FROM
|
|
626
|
+
"SELECT * FROM brz_token_metadata WHERE user_id = ? AND identifier = ?",
|
|
580
627
|
[this.identity, tokenIdentifier]
|
|
581
628
|
);
|
|
582
629
|
|
|
@@ -593,7 +640,7 @@ class MysqlTokenStore {
|
|
|
593
640
|
o.withdraw_bond_sats, o.withdraw_relative_block_locktime,
|
|
594
641
|
o.token_public_key, o.token_amount, o.token_identifier,
|
|
595
642
|
o.prev_tx_hash, o.prev_tx_vout
|
|
596
|
-
FROM
|
|
643
|
+
FROM brz_token_outputs o
|
|
597
644
|
WHERE o.user_id = ? AND o.token_identifier = ? AND o.reservation_id IS NULL`,
|
|
598
645
|
[this.identity, tokenIdentifier]
|
|
599
646
|
);
|
|
@@ -680,7 +727,7 @@ class MysqlTokenStore {
|
|
|
680
727
|
const reservationId = this._generateId();
|
|
681
728
|
|
|
682
729
|
await conn.query(
|
|
683
|
-
"INSERT INTO
|
|
730
|
+
"INSERT INTO brz_token_reservations (user_id, id, purpose) VALUES (?, ?, ?)",
|
|
684
731
|
[this.identity, reservationId, purpose]
|
|
685
732
|
);
|
|
686
733
|
|
|
@@ -688,7 +735,7 @@ class MysqlTokenStore {
|
|
|
688
735
|
if (selectedIds.length > 0) {
|
|
689
736
|
const placeholders = buildPlaceholders(selectedIds.length);
|
|
690
737
|
await conn.query(
|
|
691
|
-
`UPDATE
|
|
738
|
+
`UPDATE brz_token_outputs SET reservation_id = ? WHERE user_id = ? AND id IN (${placeholders})`,
|
|
692
739
|
[reservationId, this.identity, ...selectedIds]
|
|
693
740
|
);
|
|
694
741
|
}
|
|
@@ -713,11 +760,11 @@ class MysqlTokenStore {
|
|
|
713
760
|
// Clear reservation_id from outputs first — the composite FK uses NO
|
|
714
761
|
// ACTION (a whole-row SET NULL would null user_id, which is NOT NULL).
|
|
715
762
|
await conn.query(
|
|
716
|
-
"UPDATE
|
|
763
|
+
"UPDATE brz_token_outputs SET reservation_id = NULL WHERE user_id = ? AND reservation_id = ?",
|
|
717
764
|
[this.identity, id]
|
|
718
765
|
);
|
|
719
766
|
await conn.query(
|
|
720
|
-
"DELETE FROM
|
|
767
|
+
"DELETE FROM brz_token_reservations WHERE user_id = ? AND id = ?",
|
|
721
768
|
[this.identity, id]
|
|
722
769
|
);
|
|
723
770
|
});
|
|
@@ -734,11 +781,11 @@ class MysqlTokenStore {
|
|
|
734
781
|
try {
|
|
735
782
|
// _withWriteTransaction acquires the GET_LOCK so this serializes
|
|
736
783
|
// against `setTokensOutputs`. Without it, a concurrent setTokensOutputs
|
|
737
|
-
// could read
|
|
784
|
+
// could read brz_token_spent_outputs before our marker commits and re-insert
|
|
738
785
|
// the just-spent output as Available.
|
|
739
786
|
await this._withWriteTransaction(async (conn) => {
|
|
740
787
|
const [reservationRows] = await conn.query(
|
|
741
|
-
"SELECT purpose FROM
|
|
788
|
+
"SELECT purpose FROM brz_token_reservations WHERE user_id = ? AND id = ?",
|
|
742
789
|
[this.identity, id]
|
|
743
790
|
);
|
|
744
791
|
if (reservationRows.length === 0) {
|
|
@@ -747,7 +794,7 @@ class MysqlTokenStore {
|
|
|
747
794
|
const isSwap = reservationRows[0].purpose === "Swap";
|
|
748
795
|
|
|
749
796
|
const [reservedRows] = await conn.query(
|
|
750
|
-
"SELECT id FROM
|
|
797
|
+
"SELECT id FROM brz_token_outputs WHERE user_id = ? AND reservation_id = ?",
|
|
751
798
|
[this.identity, id]
|
|
752
799
|
);
|
|
753
800
|
const reservedOutputIds = reservedRows.map((r) => r.id);
|
|
@@ -762,18 +809,18 @@ class MysqlTokenStore {
|
|
|
762
809
|
}
|
|
763
810
|
// Suppress duplicate-PK errors only.
|
|
764
811
|
await conn.query(
|
|
765
|
-
`INSERT INTO
|
|
812
|
+
`INSERT INTO brz_token_spent_outputs (user_id, output_id) VALUES ${valueClauses}
|
|
766
813
|
ON DUPLICATE KEY UPDATE output_id = output_id`,
|
|
767
814
|
params
|
|
768
815
|
);
|
|
769
816
|
}
|
|
770
817
|
|
|
771
818
|
await conn.query(
|
|
772
|
-
"DELETE FROM
|
|
819
|
+
"DELETE FROM brz_token_outputs WHERE user_id = ? AND reservation_id = ?",
|
|
773
820
|
[this.identity, id]
|
|
774
821
|
);
|
|
775
822
|
await conn.query(
|
|
776
|
-
"DELETE FROM
|
|
823
|
+
"DELETE FROM brz_token_reservations WHERE user_id = ? AND id = ?",
|
|
777
824
|
[this.identity, id]
|
|
778
825
|
);
|
|
779
826
|
|
|
@@ -781,17 +828,17 @@ class MysqlTokenStore {
|
|
|
781
828
|
// (and thus has no row) gets one created lazily.
|
|
782
829
|
if (isSwap) {
|
|
783
830
|
await conn.query(
|
|
784
|
-
`INSERT INTO
|
|
831
|
+
`INSERT INTO brz_token_swap_status (user_id, last_completed_at) VALUES (?, NOW(6))
|
|
785
832
|
ON DUPLICATE KEY UPDATE last_completed_at = VALUES(last_completed_at)`,
|
|
786
833
|
[this.identity]
|
|
787
834
|
);
|
|
788
835
|
}
|
|
789
836
|
|
|
790
837
|
await conn.query(
|
|
791
|
-
`DELETE FROM
|
|
838
|
+
`DELETE FROM brz_token_metadata
|
|
792
839
|
WHERE user_id = ?
|
|
793
840
|
AND identifier NOT IN (
|
|
794
|
-
SELECT DISTINCT token_identifier FROM
|
|
841
|
+
SELECT DISTINCT token_identifier FROM brz_token_outputs WHERE user_id = ?
|
|
795
842
|
)`,
|
|
796
843
|
[this.identity, this.identity]
|
|
797
844
|
);
|
|
@@ -839,11 +886,11 @@ class MysqlTokenStore {
|
|
|
839
886
|
/// user_id (NOT NULL).
|
|
840
887
|
async _cleanupStaleReservations(conn) {
|
|
841
888
|
await conn.query(
|
|
842
|
-
`UPDATE
|
|
889
|
+
`UPDATE brz_token_outputs SET reservation_id = NULL
|
|
843
890
|
WHERE user_id = ?
|
|
844
891
|
AND reservation_id IN (
|
|
845
892
|
SELECT id FROM (
|
|
846
|
-
SELECT id FROM
|
|
893
|
+
SELECT id FROM brz_token_reservations
|
|
847
894
|
WHERE user_id = ?
|
|
848
895
|
AND created_at < DATE_SUB(NOW(6), INTERVAL ? SECOND)
|
|
849
896
|
) AS stale
|
|
@@ -851,7 +898,7 @@ class MysqlTokenStore {
|
|
|
851
898
|
[this.identity, this.identity, RESERVATION_TIMEOUT_SECS]
|
|
852
899
|
);
|
|
853
900
|
await conn.query(
|
|
854
|
-
`DELETE FROM
|
|
901
|
+
`DELETE FROM brz_token_reservations
|
|
855
902
|
WHERE user_id = ? AND created_at < DATE_SUB(NOW(6), INTERVAL ? SECOND)`,
|
|
856
903
|
[this.identity, RESERVATION_TIMEOUT_SECS]
|
|
857
904
|
);
|
|
@@ -859,7 +906,7 @@ class MysqlTokenStore {
|
|
|
859
906
|
|
|
860
907
|
async _upsertMetadata(conn, metadata) {
|
|
861
908
|
await conn.query(
|
|
862
|
-
`INSERT INTO
|
|
909
|
+
`INSERT INTO brz_token_metadata
|
|
863
910
|
(user_id, identifier, issuer_public_key, name, ticker, decimals, max_supply,
|
|
864
911
|
is_freezable, creation_entity_public_key)
|
|
865
912
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
@@ -890,7 +937,7 @@ class MysqlTokenStore {
|
|
|
890
937
|
// conflict only — unlike INSERT IGNORE, FK / NOT NULL / type errors
|
|
891
938
|
// still propagate.
|
|
892
939
|
await conn.query(
|
|
893
|
-
`INSERT INTO
|
|
940
|
+
`INSERT INTO brz_token_outputs
|
|
894
941
|
(user_id, id, token_identifier, owner_public_key, revocation_commitment,
|
|
895
942
|
withdraw_bond_sats, withdraw_relative_block_locktime,
|
|
896
943
|
token_public_key, token_amount, prev_tx_hash, prev_tx_vout, added_at)
|
|
@@ -963,11 +1010,29 @@ function createMysqlPool(config) {
|
|
|
963
1010
|
*/
|
|
964
1011
|
async function createMysqlTokenStore(config, identity, logger = null) {
|
|
965
1012
|
const pool = createMysqlPool(config);
|
|
966
|
-
return createMysqlTokenStoreWithPool(
|
|
1013
|
+
return createMysqlTokenStoreWithPool(
|
|
1014
|
+
pool,
|
|
1015
|
+
identity,
|
|
1016
|
+
config.foreignKeyMode || "Enforced",
|
|
1017
|
+
logger,
|
|
1018
|
+
config.runMigration !== false
|
|
1019
|
+
);
|
|
967
1020
|
}
|
|
968
1021
|
|
|
969
|
-
async function createMysqlTokenStoreWithPool(
|
|
970
|
-
|
|
1022
|
+
async function createMysqlTokenStoreWithPool(
|
|
1023
|
+
pool,
|
|
1024
|
+
identity,
|
|
1025
|
+
foreignKeyMode = "Enforced",
|
|
1026
|
+
logger = null,
|
|
1027
|
+
runMigration = true
|
|
1028
|
+
) {
|
|
1029
|
+
const store = new MysqlTokenStore(
|
|
1030
|
+
pool,
|
|
1031
|
+
identity,
|
|
1032
|
+
foreignKeyMode,
|
|
1033
|
+
logger,
|
|
1034
|
+
runMigration
|
|
1035
|
+
);
|
|
971
1036
|
await store.initialize();
|
|
972
1037
|
return store;
|
|
973
1038
|
}
|