@breeztech/breez-sdk-spark 0.15.1 → 0.16.1-dev1
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 +511 -215
- package/bundler/breez_sdk_spark_wasm.js +1 -1
- package/bundler/breez_sdk_spark_wasm_bg.js +567 -414
- package/bundler/breez_sdk_spark_wasm_bg.wasm +0 -0
- package/bundler/breez_sdk_spark_wasm_bg.wasm.d.ts +55 -46
- package/bundler/storage/index.js +205 -15
- package/deno/breez_sdk_spark_wasm.d.ts +511 -215
- package/deno/breez_sdk_spark_wasm.js +567 -414
- package/deno/breez_sdk_spark_wasm_bg.wasm +0 -0
- package/deno/breez_sdk_spark_wasm_bg.wasm.d.ts +55 -46
- package/nodejs/breez_sdk_spark_wasm.d.ts +511 -215
- package/nodejs/breez_sdk_spark_wasm.js +578 -421
- package/nodejs/breez_sdk_spark_wasm_bg.wasm +0 -0
- package/nodejs/breez_sdk_spark_wasm_bg.wasm.d.ts +55 -46
- package/nodejs/index.js +10 -10
- package/nodejs/index.mjs +12 -8
- package/nodejs/mysql-session-store/errors.cjs +13 -0
- package/nodejs/{mysql-session-manager → mysql-session-store}/index.cjs +24 -21
- package/nodejs/{mysql-session-manager → mysql-session-store}/migrations.cjs +17 -11
- package/nodejs/mysql-session-store/package.json +9 -0
- package/nodejs/mysql-storage/index.cjs +229 -111
- package/nodejs/mysql-storage/migrations.cjs +37 -2
- package/nodejs/mysql-token-store/index.cjs +99 -79
- package/nodejs/mysql-token-store/migrations.cjs +59 -2
- package/nodejs/mysql-tree-store/index.cjs +15 -9
- package/nodejs/mysql-tree-store/migrations.cjs +16 -2
- package/nodejs/package.json +2 -2
- package/nodejs/postgres-session-store/errors.cjs +13 -0
- package/nodejs/{postgres-session-manager → postgres-session-store}/index.cjs +23 -23
- package/nodejs/{postgres-session-manager → postgres-session-store}/migrations.cjs +14 -14
- package/nodejs/postgres-session-store/package.json +9 -0
- package/nodejs/postgres-storage/index.cjs +174 -107
- package/nodejs/postgres-storage/migrations.cjs +24 -0
- package/nodejs/postgres-token-store/index.cjs +89 -64
- package/nodejs/postgres-token-store/migrations.cjs +44 -0
- package/nodejs/storage/index.cjs +167 -113
- package/nodejs/storage/migrations.cjs +23 -0
- package/package.json +6 -1
- package/ssr/index.js +52 -28
- package/web/breez_sdk_spark_wasm.d.ts +566 -261
- package/web/breez_sdk_spark_wasm.js +567 -414
- package/web/breez_sdk_spark_wasm_bg.wasm +0 -0
- package/web/breez_sdk_spark_wasm_bg.wasm.d.ts +55 -46
- package/web/passkey-prf-provider/index.d.ts +203 -0
- package/web/passkey-prf-provider/index.js +733 -0
- package/web/storage/index.js +205 -15
- package/nodejs/mysql-session-manager/errors.cjs +0 -13
- package/nodejs/mysql-session-manager/package.json +0 -9
- package/nodejs/postgres-session-manager/errors.cjs +0 -13
- package/nodejs/postgres-session-manager/package.json +0 -9
|
@@ -16,6 +16,8 @@
|
|
|
16
16
|
* → `conn.beginTransaction()`/`conn.commit()`/`conn.rollback()`.
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
+
const crypto = require("crypto");
|
|
20
|
+
|
|
19
21
|
let mysql;
|
|
20
22
|
try {
|
|
21
23
|
const mainModule = require.main;
|
|
@@ -38,6 +40,8 @@ try {
|
|
|
38
40
|
const { StorageError } = require("./errors.cjs");
|
|
39
41
|
const { MysqlMigrationManager } = require("./migrations.cjs");
|
|
40
42
|
|
|
43
|
+
const PAYMENT_UPDATE_LOCK_TIMEOUT_SECS = 10;
|
|
44
|
+
|
|
41
45
|
/**
|
|
42
46
|
* Base query for payment lookups. All columns are accessed by name in _rowToPayment.
|
|
43
47
|
* parent_payment_id is only used by getPaymentsByParentIds.
|
|
@@ -51,7 +55,8 @@ const SELECT_PAYMENT_SQL = `
|
|
|
51
55
|
p.timestamp,
|
|
52
56
|
p.method,
|
|
53
57
|
p.withdraw_tx_id,
|
|
54
|
-
|
|
58
|
+
pd.tx_id AS deposit_tx_id,
|
|
59
|
+
pd.vout AS deposit_vout,
|
|
55
60
|
p.spark,
|
|
56
61
|
l.invoice AS lightning_invoice,
|
|
57
62
|
l.payment_hash AS lightning_payment_hash,
|
|
@@ -79,6 +84,7 @@ const SELECT_PAYMENT_SQL = `
|
|
|
79
84
|
LEFT JOIN brz_payment_details_lightning l ON p.id = l.payment_id AND p.user_id = l.user_id
|
|
80
85
|
LEFT JOIN brz_payment_details_token t ON p.id = t.payment_id AND p.user_id = t.user_id
|
|
81
86
|
LEFT JOIN brz_payment_details_spark s ON p.id = s.payment_id AND p.user_id = s.user_id
|
|
87
|
+
LEFT JOIN brz_payment_details_deposit pd ON p.id = pd.payment_id AND p.user_id = pd.user_id
|
|
82
88
|
LEFT JOIN brz_payment_metadata pm ON p.id = pm.payment_id AND p.user_id = pm.user_id
|
|
83
89
|
LEFT JOIN brz_lnurl_receive_metadata lrm ON l.payment_hash = lrm.payment_hash AND l.user_id = lrm.user_id`;
|
|
84
90
|
|
|
@@ -360,130 +366,237 @@ class MysqlStorage {
|
|
|
360
366
|
}
|
|
361
367
|
}
|
|
362
368
|
|
|
363
|
-
async
|
|
369
|
+
async applyPaymentUpdate(payment) {
|
|
370
|
+
if (!payment) {
|
|
371
|
+
throw new StorageError("Payment cannot be null or undefined");
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
let conn = null;
|
|
375
|
+
const lockName = this._paymentUpdateLockName(payment.id);
|
|
376
|
+
let acquired = false;
|
|
377
|
+
let shouldEmit = false;
|
|
378
|
+
let operationError = null;
|
|
379
|
+
let releaseError = null;
|
|
380
|
+
|
|
364
381
|
try {
|
|
365
|
-
|
|
366
|
-
|
|
382
|
+
conn = await this.pool.getConnection();
|
|
383
|
+
const [lockRows] = await conn.query("SELECT GET_LOCK(?, ?) AS acquired", [
|
|
384
|
+
lockName,
|
|
385
|
+
PAYMENT_UPDATE_LOCK_TIMEOUT_SECS,
|
|
386
|
+
]);
|
|
387
|
+
acquired = Number(lockRows?.[0]?.acquired) === 1;
|
|
388
|
+
if (!acquired) {
|
|
389
|
+
throw new StorageError(`Timed out acquiring payment update lock '${lockName}'`);
|
|
367
390
|
}
|
|
368
391
|
|
|
369
|
-
await
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
const
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
await conn.query(
|
|
377
|
-
`INSERT INTO brz_payments (user_id, id, payment_type, status, amount, fees, timestamp, method, withdraw_tx_id, deposit_tx_id, spark)
|
|
378
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
379
|
-
ON DUPLICATE KEY UPDATE
|
|
380
|
-
payment_type=VALUES(payment_type),
|
|
381
|
-
status=VALUES(status),
|
|
382
|
-
amount=VALUES(amount),
|
|
383
|
-
fees=VALUES(fees),
|
|
384
|
-
timestamp=VALUES(timestamp),
|
|
385
|
-
method=VALUES(method),
|
|
386
|
-
withdraw_tx_id=VALUES(withdraw_tx_id),
|
|
387
|
-
deposit_tx_id=VALUES(deposit_tx_id),
|
|
388
|
-
spark=VALUES(spark)`,
|
|
389
|
-
[
|
|
390
|
-
this.identity,
|
|
391
|
-
payment.id,
|
|
392
|
-
payment.paymentType,
|
|
393
|
-
payment.status,
|
|
394
|
-
payment.amount.toString(),
|
|
395
|
-
payment.fees.toString(),
|
|
396
|
-
payment.timestamp,
|
|
397
|
-
payment.method ? JSON.stringify(payment.method) : null,
|
|
398
|
-
withdrawTxId,
|
|
399
|
-
depositTxId,
|
|
400
|
-
spark,
|
|
401
|
-
]
|
|
392
|
+
await conn.query("SET TRANSACTION ISOLATION LEVEL READ COMMITTED");
|
|
393
|
+
await conn.beginTransaction();
|
|
394
|
+
try {
|
|
395
|
+
const [rows] = await conn.query(
|
|
396
|
+
"SELECT status FROM brz_payments WHERE user_id = ? AND id = ? FOR UPDATE",
|
|
397
|
+
[this.identity, payment.id]
|
|
402
398
|
);
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
) {
|
|
409
|
-
await
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
htlc_details=COALESCE(VALUES(htlc_details), htlc_details)`,
|
|
415
|
-
[
|
|
416
|
-
this.identity,
|
|
417
|
-
payment.id,
|
|
418
|
-
payment.details.invoiceDetails
|
|
419
|
-
? JSON.stringify(payment.details.invoiceDetails)
|
|
420
|
-
: null,
|
|
421
|
-
payment.details.htlcDetails
|
|
422
|
-
? JSON.stringify(payment.details.htlcDetails)
|
|
423
|
-
: null,
|
|
424
|
-
]
|
|
399
|
+
const stored = rows.length > 0
|
|
400
|
+
? this._normalizePaymentStatus(rows[0].status)
|
|
401
|
+
: null;
|
|
402
|
+
const next = this._normalizePaymentStatus(payment.status);
|
|
403
|
+
|
|
404
|
+
if (stored == null) {
|
|
405
|
+
await this._runPaymentUpsert(conn, payment);
|
|
406
|
+
shouldEmit = true;
|
|
407
|
+
} else if (stored === next) {
|
|
408
|
+
console.debug(
|
|
409
|
+
`Skipping redundant payment event: id=${payment.id} status=${next}`
|
|
425
410
|
);
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
if (
|
|
429
|
-
|
|
430
|
-
`
|
|
431
|
-
(user_id, payment_id, invoice, payment_hash, destination_pubkey, description, preimage, htlc_status, htlc_expiry_time)
|
|
432
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
433
|
-
ON DUPLICATE KEY UPDATE
|
|
434
|
-
invoice=VALUES(invoice),
|
|
435
|
-
payment_hash=VALUES(payment_hash),
|
|
436
|
-
destination_pubkey=VALUES(destination_pubkey),
|
|
437
|
-
description=VALUES(description),
|
|
438
|
-
preimage=COALESCE(VALUES(preimage), preimage),
|
|
439
|
-
htlc_status=COALESCE(VALUES(htlc_status), htlc_status),
|
|
440
|
-
htlc_expiry_time=COALESCE(VALUES(htlc_expiry_time), htlc_expiry_time)`,
|
|
441
|
-
[
|
|
442
|
-
this.identity,
|
|
443
|
-
payment.id,
|
|
444
|
-
payment.details.invoice,
|
|
445
|
-
payment.details.htlcDetails.paymentHash,
|
|
446
|
-
payment.details.destinationPubkey,
|
|
447
|
-
payment.details.description,
|
|
448
|
-
payment.details.htlcDetails?.preimage,
|
|
449
|
-
payment.details.htlcDetails?.status ?? null,
|
|
450
|
-
payment.details.htlcDetails?.expiryTime ?? 0,
|
|
451
|
-
]
|
|
411
|
+
await this._runPaymentUpsert(conn, payment);
|
|
412
|
+
shouldEmit = false;
|
|
413
|
+
} else if (this._isFinalPaymentStatus(stored)) {
|
|
414
|
+
console.warn(
|
|
415
|
+
`Skipping payment update (would replace terminal status): id=${payment.id} stored=${stored} new=${next}`
|
|
452
416
|
);
|
|
417
|
+
shouldEmit = false;
|
|
418
|
+
} else {
|
|
419
|
+
await this._runPaymentUpsert(conn, payment);
|
|
420
|
+
shouldEmit = true;
|
|
453
421
|
}
|
|
454
422
|
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
ON DUPLICATE KEY UPDATE
|
|
461
|
-
metadata=VALUES(metadata),
|
|
462
|
-
tx_hash=VALUES(tx_hash),
|
|
463
|
-
tx_type=VALUES(tx_type),
|
|
464
|
-
invoice_details=COALESCE(VALUES(invoice_details), invoice_details)`,
|
|
465
|
-
[
|
|
466
|
-
this.identity,
|
|
467
|
-
payment.id,
|
|
468
|
-
JSON.stringify(payment.details.metadata),
|
|
469
|
-
payment.details.txHash,
|
|
470
|
-
payment.details.txType,
|
|
471
|
-
payment.details.invoiceDetails
|
|
472
|
-
? JSON.stringify(payment.details.invoiceDetails)
|
|
473
|
-
: null,
|
|
474
|
-
]
|
|
475
|
-
);
|
|
476
|
-
}
|
|
477
|
-
});
|
|
423
|
+
await conn.commit();
|
|
424
|
+
} catch (error) {
|
|
425
|
+
await conn.rollback().catch(() => {});
|
|
426
|
+
throw error;
|
|
427
|
+
}
|
|
478
428
|
} catch (error) {
|
|
479
|
-
|
|
429
|
+
operationError = error;
|
|
430
|
+
} finally {
|
|
431
|
+
if (conn && acquired) {
|
|
432
|
+
try {
|
|
433
|
+
await conn.query("SELECT RELEASE_LOCK(?)", [lockName]);
|
|
434
|
+
} catch (error) {
|
|
435
|
+
releaseError = error;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
if (conn) {
|
|
439
|
+
conn.release();
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
if (operationError) {
|
|
444
|
+
if (operationError instanceof StorageError) {
|
|
445
|
+
throw operationError;
|
|
446
|
+
}
|
|
480
447
|
throw new StorageError(
|
|
481
|
-
`Failed to
|
|
482
|
-
|
|
448
|
+
`Failed to apply payment update '${payment.id}': ${operationError.message}`,
|
|
449
|
+
operationError
|
|
483
450
|
);
|
|
484
451
|
}
|
|
452
|
+
|
|
453
|
+
if (releaseError) {
|
|
454
|
+
throw new StorageError(
|
|
455
|
+
`Failed to release payment update lock '${lockName}': ${releaseError.message}`,
|
|
456
|
+
releaseError
|
|
457
|
+
);
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
return shouldEmit;
|
|
485
461
|
}
|
|
486
462
|
|
|
463
|
+
async _runPaymentUpsert(conn, payment) {
|
|
464
|
+
const withdrawTxId =
|
|
465
|
+
payment.details?.type === "withdraw" ? payment.details.txId : null;
|
|
466
|
+
const spark = payment.details?.type === "spark" ? 1 : null;
|
|
467
|
+
|
|
468
|
+
await conn.query(
|
|
469
|
+
`INSERT INTO brz_payments (user_id, id, payment_type, status, amount, fees, timestamp, method, withdraw_tx_id, spark)
|
|
470
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
471
|
+
ON DUPLICATE KEY UPDATE
|
|
472
|
+
payment_type=VALUES(payment_type),
|
|
473
|
+
status=VALUES(status),
|
|
474
|
+
amount=VALUES(amount),
|
|
475
|
+
fees=VALUES(fees),
|
|
476
|
+
timestamp=VALUES(timestamp),
|
|
477
|
+
method=VALUES(method),
|
|
478
|
+
withdraw_tx_id=VALUES(withdraw_tx_id),
|
|
479
|
+
spark=VALUES(spark)`,
|
|
480
|
+
[
|
|
481
|
+
this.identity,
|
|
482
|
+
payment.id,
|
|
483
|
+
payment.paymentType,
|
|
484
|
+
payment.status,
|
|
485
|
+
payment.amount.toString(),
|
|
486
|
+
payment.fees.toString(),
|
|
487
|
+
payment.timestamp,
|
|
488
|
+
payment.method ? JSON.stringify(payment.method) : null,
|
|
489
|
+
withdrawTxId,
|
|
490
|
+
spark,
|
|
491
|
+
]
|
|
492
|
+
);
|
|
493
|
+
|
|
494
|
+
if (payment.details?.type === "deposit") {
|
|
495
|
+
await conn.query(
|
|
496
|
+
`INSERT INTO brz_payment_details_deposit (user_id, payment_id, tx_id, vout)
|
|
497
|
+
VALUES (?, ?, ?, ?)
|
|
498
|
+
ON DUPLICATE KEY UPDATE
|
|
499
|
+
tx_id=VALUES(tx_id),
|
|
500
|
+
vout=VALUES(vout)`,
|
|
501
|
+
[this.identity, payment.id, payment.details.txId, payment.details.vout]
|
|
502
|
+
);
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
if (
|
|
506
|
+
payment.details?.type === "spark" &&
|
|
507
|
+
(payment.details.invoiceDetails != null ||
|
|
508
|
+
payment.details.htlcDetails != null)
|
|
509
|
+
) {
|
|
510
|
+
await conn.query(
|
|
511
|
+
`INSERT INTO brz_payment_details_spark (user_id, payment_id, invoice_details, htlc_details)
|
|
512
|
+
VALUES (?, ?, ?, ?)
|
|
513
|
+
ON DUPLICATE KEY UPDATE
|
|
514
|
+
invoice_details=COALESCE(VALUES(invoice_details), invoice_details),
|
|
515
|
+
htlc_details=COALESCE(VALUES(htlc_details), htlc_details)`,
|
|
516
|
+
[
|
|
517
|
+
this.identity,
|
|
518
|
+
payment.id,
|
|
519
|
+
payment.details.invoiceDetails
|
|
520
|
+
? JSON.stringify(payment.details.invoiceDetails)
|
|
521
|
+
: null,
|
|
522
|
+
payment.details.htlcDetails
|
|
523
|
+
? JSON.stringify(payment.details.htlcDetails)
|
|
524
|
+
: null,
|
|
525
|
+
]
|
|
526
|
+
);
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
if (payment.details?.type === "lightning") {
|
|
530
|
+
await conn.query(
|
|
531
|
+
`INSERT INTO brz_payment_details_lightning
|
|
532
|
+
(user_id, payment_id, invoice, payment_hash, destination_pubkey, description, preimage, htlc_status, htlc_expiry_time)
|
|
533
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
534
|
+
ON DUPLICATE KEY UPDATE
|
|
535
|
+
invoice=VALUES(invoice),
|
|
536
|
+
payment_hash=VALUES(payment_hash),
|
|
537
|
+
destination_pubkey=VALUES(destination_pubkey),
|
|
538
|
+
description=VALUES(description),
|
|
539
|
+
preimage=COALESCE(VALUES(preimage), preimage),
|
|
540
|
+
htlc_status=COALESCE(VALUES(htlc_status), htlc_status),
|
|
541
|
+
htlc_expiry_time=COALESCE(VALUES(htlc_expiry_time), htlc_expiry_time)`,
|
|
542
|
+
[
|
|
543
|
+
this.identity,
|
|
544
|
+
payment.id,
|
|
545
|
+
payment.details.invoice,
|
|
546
|
+
payment.details.htlcDetails.paymentHash,
|
|
547
|
+
payment.details.destinationPubkey,
|
|
548
|
+
payment.details.description,
|
|
549
|
+
payment.details.htlcDetails?.preimage,
|
|
550
|
+
payment.details.htlcDetails?.status ?? null,
|
|
551
|
+
payment.details.htlcDetails?.expiryTime ?? 0,
|
|
552
|
+
]
|
|
553
|
+
);
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
if (payment.details?.type === "token") {
|
|
557
|
+
await conn.query(
|
|
558
|
+
`INSERT INTO brz_payment_details_token
|
|
559
|
+
(user_id, payment_id, metadata, tx_hash, tx_type, invoice_details)
|
|
560
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
561
|
+
ON DUPLICATE KEY UPDATE
|
|
562
|
+
metadata=VALUES(metadata),
|
|
563
|
+
tx_hash=VALUES(tx_hash),
|
|
564
|
+
tx_type=VALUES(tx_type),
|
|
565
|
+
invoice_details=COALESCE(VALUES(invoice_details), invoice_details)`,
|
|
566
|
+
[
|
|
567
|
+
this.identity,
|
|
568
|
+
payment.id,
|
|
569
|
+
JSON.stringify(payment.details.metadata),
|
|
570
|
+
payment.details.txHash,
|
|
571
|
+
payment.details.txType,
|
|
572
|
+
payment.details.invoiceDetails
|
|
573
|
+
? JSON.stringify(payment.details.invoiceDetails)
|
|
574
|
+
: null,
|
|
575
|
+
]
|
|
576
|
+
);
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
_paymentUpdateLockName(paymentId) {
|
|
581
|
+
return crypto
|
|
582
|
+
.createHash("sha256")
|
|
583
|
+
.update("brz_payment_update")
|
|
584
|
+
.update(this.identity)
|
|
585
|
+
.update(Buffer.from(paymentId))
|
|
586
|
+
.digest("hex")
|
|
587
|
+
.slice(0, 32);
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
_normalizePaymentStatus(status) {
|
|
591
|
+
return typeof status === "string" ? status.toLowerCase() : status;
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
_isFinalPaymentStatus(status) {
|
|
595
|
+
const normalized = this._normalizePaymentStatus(status);
|
|
596
|
+
return normalized === "completed" || normalized === "failed";
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
|
|
487
600
|
async getPaymentById(id) {
|
|
488
601
|
try {
|
|
489
602
|
if (!id) {
|
|
@@ -773,6 +886,7 @@ class MysqlStorage {
|
|
|
773
886
|
details = {
|
|
774
887
|
type: "deposit",
|
|
775
888
|
txId: row.deposit_tx_id,
|
|
889
|
+
vout: Number(row.deposit_vout),
|
|
776
890
|
};
|
|
777
891
|
} else if (toBool(row.spark)) {
|
|
778
892
|
details = {
|
|
@@ -1332,6 +1446,10 @@ function createMysqlPool(config) {
|
|
|
1332
1446
|
connectTimeout: (config.createTimeoutSecs || 0) * 1000 || 10000,
|
|
1333
1447
|
idleTimeout: (config.recycleTimeoutSecs || 0) * 1000 || 10000,
|
|
1334
1448
|
waitForConnections: true,
|
|
1449
|
+
// Serialize JS `Date` parameters as UTC strings rather than host-local
|
|
1450
|
+
// time. Paired with explicit `UTC_TIMESTAMP(6)` on the server side, this
|
|
1451
|
+
// keeps timestamp comparisons consistent regardless of the host TZ.
|
|
1452
|
+
timezone: "Z",
|
|
1335
1453
|
});
|
|
1336
1454
|
}
|
|
1337
1455
|
|
|
@@ -89,7 +89,7 @@ class MysqlMigrationManager {
|
|
|
89
89
|
await conn.query(`
|
|
90
90
|
CREATE TABLE IF NOT EXISTS brz_schema_migrations (
|
|
91
91
|
version INT PRIMARY KEY,
|
|
92
|
-
applied_at DATETIME(6) NOT NULL DEFAULT
|
|
92
|
+
applied_at DATETIME(6) NOT NULL DEFAULT (UTC_TIMESTAMP(6))
|
|
93
93
|
)
|
|
94
94
|
`);
|
|
95
95
|
|
|
@@ -121,7 +121,7 @@ class MysqlMigrationManager {
|
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
await conn.query(
|
|
124
|
-
"INSERT INTO brz_schema_migrations (version) VALUES (
|
|
124
|
+
"INSERT INTO brz_schema_migrations (version, applied_at) VALUES (?, UTC_TIMESTAMP(6))",
|
|
125
125
|
[version]
|
|
126
126
|
);
|
|
127
127
|
}
|
|
@@ -497,6 +497,41 @@ class MysqlMigrationManager {
|
|
|
497
497
|
ON brz_sync_incoming(user_id, revision)`,
|
|
498
498
|
],
|
|
499
499
|
},
|
|
500
|
+
{
|
|
501
|
+
// Pin the migration-tracking table's `applied_at` default to UTC.
|
|
502
|
+
// The migration manager already passes `UTC_TIMESTAMP(6)` explicitly
|
|
503
|
+
// on INSERT, but aligning the default keeps `SHOW CREATE TABLE`
|
|
504
|
+
// output consistent with the token-store / tree-store migrations
|
|
505
|
+
// table and avoids future mistakes if a callsite omits the column.
|
|
506
|
+
name: "Pin schema-migrations applied_at default to UTC",
|
|
507
|
+
sql: [
|
|
508
|
+
`ALTER TABLE brz_schema_migrations MODIFY COLUMN applied_at DATETIME(6) NOT NULL DEFAULT (UTC_TIMESTAMP(6))`,
|
|
509
|
+
],
|
|
510
|
+
},
|
|
511
|
+
{
|
|
512
|
+
// Move deposit details into their own table so vout can be NOT NULL and
|
|
513
|
+
// the schema matches brz_payment_details_lightning / _token / _spark. We
|
|
514
|
+
// can't safely backfill the new table from the dropped deposit_tx_id
|
|
515
|
+
// column: we never stored the original SSP output_index, and vout=0 is a
|
|
516
|
+
// valid output index — defaulting would silently mislabel. Drop the
|
|
517
|
+
// column and leave the brz_payments row in place. The read path sees an
|
|
518
|
+
// unjoined deposit row as `details: None` until the resync re-fetches the
|
|
519
|
+
// SSP user_request and the upsert inserts the new details row.
|
|
520
|
+
name: "Move deposit details into brz_payment_details_deposit table",
|
|
521
|
+
sql: [
|
|
522
|
+
`CREATE TABLE IF NOT EXISTS brz_payment_details_deposit (
|
|
523
|
+
user_id VARBINARY(33) NOT NULL,
|
|
524
|
+
payment_id VARCHAR(255) NOT NULL,
|
|
525
|
+
tx_id VARCHAR(255) NOT NULL,
|
|
526
|
+
vout INT UNSIGNED NOT NULL,
|
|
527
|
+
PRIMARY KEY (user_id, payment_id)
|
|
528
|
+
)`,
|
|
529
|
+
`ALTER TABLE brz_payments DROP COLUMN deposit_tx_id`,
|
|
530
|
+
`UPDATE brz_settings
|
|
531
|
+
SET value = JSON_SET(value, '$.offset', 0)
|
|
532
|
+
WHERE \`key\` = 'sync_offset' AND value IS NOT NULL`,
|
|
533
|
+
],
|
|
534
|
+
},
|
|
500
535
|
];
|
|
501
536
|
}
|
|
502
537
|
}
|