@breeztech/breez-sdk-spark 0.27.1 → 0.27.3-dev
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 +9 -8
- package/bundler/breez_sdk_spark_wasm.d.ts +141 -16
- package/bundler/breez_sdk_spark_wasm.js +1 -1
- package/bundler/breez_sdk_spark_wasm_bg.js +190 -40
- package/bundler/breez_sdk_spark_wasm_bg.wasm +0 -0
- package/bundler/breez_sdk_spark_wasm_bg.wasm.d.ts +23 -11
- package/bundler/index.js +6 -13
- package/bundler/storage/index.js +89 -17
- package/deno/breez_sdk_spark_wasm.d.ts +141 -16
- package/deno/breez_sdk_spark_wasm.js +190 -40
- package/deno/breez_sdk_spark_wasm_bg.wasm +0 -0
- package/deno/breez_sdk_spark_wasm_bg.wasm.d.ts +23 -11
- package/nodejs/breez_sdk_spark_wasm.d.ts +141 -16
- package/nodejs/breez_sdk_spark_wasm.js +194 -40
- package/nodejs/breez_sdk_spark_wasm_bg.wasm +0 -0
- package/nodejs/breez_sdk_spark_wasm_bg.wasm.d.ts +23 -11
- package/nodejs/index.d.mts +3 -0
- package/nodejs/index.js +30 -120
- package/nodejs/index.mjs +4 -0
- package/nodejs/mysql-session-store/index.cjs +24 -7
- package/nodejs/mysql-session-store/migrations.cjs +6 -0
- package/nodejs/mysql-storage/index.cjs +36 -19
- package/nodejs/mysql-storage/migrations.cjs +24 -9
- package/nodejs/mysql-token-store/index.cjs +28 -18
- package/nodejs/postgres-session-store/index.cjs +25 -7
- package/nodejs/postgres-session-store/migrations.cjs +12 -9
- package/nodejs/postgres-storage/index.cjs +36 -19
- package/nodejs/postgres-storage/migrations.cjs +24 -9
- package/nodejs/postgres-token-store/index.cjs +32 -18
- package/nodejs/postgres-token-store/migrations.cjs +5 -9
- package/nodejs/postgres-tree-store/migrations.cjs +5 -9
- package/nodejs/storage/index.cjs +35 -14
- package/nodejs/storage/migrations.cjs +25 -15
- package/nodejs/tree-store/index.cjs +1 -1
- package/nodejs/tree-store/migrations.cjs +6 -13
- package/package.json +27 -6
- package/ssr/index.js +24 -0
- package/web/breez_sdk_spark_wasm.d.ts +164 -27
- package/web/breez_sdk_spark_wasm.js +190 -40
- package/web/breez_sdk_spark_wasm_bg.wasm +0 -0
- package/web/breez_sdk_spark_wasm_bg.wasm.d.ts +23 -11
- package/web/index.js +6 -13
- package/web/passkey-prf-provider/index.js +1 -0
- package/web/storage/index.js +89 -17
- package/breez-sdk-spark.tgz +0 -0
- package/itest/.gitignore +0 -2
- package/itest/database-drivers.test.js +0 -45
- package/itest/helpers/assert.test.js +0 -70
- package/itest/helpers/faucet.js +0 -68
- package/itest/helpers/lnurl-fixture.js +0 -229
- package/itest/helpers/scenario.js +0 -444
- package/itest/package-lock.json +0 -519
- package/itest/package.json +0 -18
- package/itest/scenarios.test.js +0 -47
- package/itest/smoke.test.js +0 -184
|
@@ -54,20 +54,20 @@ class PostgresMigrationManager {
|
|
|
54
54
|
const migrations = this._getMigrations(identity);
|
|
55
55
|
|
|
56
56
|
if (currentVersion >= migrations.length) {
|
|
57
|
-
this._log("
|
|
57
|
+
this._log("INFO", `Database is up to date (version ${currentVersion})`);
|
|
58
58
|
await client.query("COMMIT");
|
|
59
59
|
return;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
this._log(
|
|
63
|
-
"
|
|
63
|
+
"INFO",
|
|
64
64
|
`Migrating database from version ${currentVersion} to ${migrations.length}`
|
|
65
65
|
);
|
|
66
66
|
|
|
67
67
|
for (let i = currentVersion; i < migrations.length; i++) {
|
|
68
68
|
const migration = migrations[i];
|
|
69
69
|
const version = i + 1;
|
|
70
|
-
this._log("
|
|
70
|
+
this._log("DEBUG", `Running migration ${version}: ${migration.name}`);
|
|
71
71
|
|
|
72
72
|
for (const sql of migration.sql) {
|
|
73
73
|
await client.query(sql);
|
|
@@ -80,7 +80,7 @@ class PostgresMigrationManager {
|
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
await client.query("COMMIT");
|
|
83
|
-
this._log("
|
|
83
|
+
this._log("INFO", "Database migration completed successfully");
|
|
84
84
|
} catch (error) {
|
|
85
85
|
await client.query("ROLLBACK").catch(() => {});
|
|
86
86
|
throw new StorageError(
|
|
@@ -219,11 +219,7 @@ class PostgresMigrationManager {
|
|
|
219
219
|
}
|
|
220
220
|
|
|
221
221
|
_log(level, message) {
|
|
222
|
-
|
|
223
|
-
this.logger.log({ line: message, level });
|
|
224
|
-
} else if (level === "error") {
|
|
225
|
-
console.error(`[PostgresMigrationManager] ${message}`);
|
|
226
|
-
}
|
|
222
|
+
this.logger?.log({ line: message, level });
|
|
227
223
|
}
|
|
228
224
|
|
|
229
225
|
/**
|
|
@@ -612,6 +608,25 @@ class PostgresMigrationManager {
|
|
|
612
608
|
)`,
|
|
613
609
|
],
|
|
614
610
|
},
|
|
611
|
+
{
|
|
612
|
+
// With the sync offset at 0, the SDK re-fetches every transfer on its
|
|
613
|
+
// next sync and fills in both columns for past withdrawals.
|
|
614
|
+
name: "Add withdrawal destination address and output index",
|
|
615
|
+
sql: [
|
|
616
|
+
`ALTER TABLE brz_payments ADD COLUMN withdraw_vout BIGINT`,
|
|
617
|
+
`ALTER TABLE brz_payments ADD COLUMN withdraw_destination_address TEXT`,
|
|
618
|
+
`UPDATE brz_settings
|
|
619
|
+
SET value = jsonb_set(value::jsonb, '{offset}', '0')::text
|
|
620
|
+
WHERE key = 'sync_offset' AND value IS NOT NULL`,
|
|
621
|
+
],
|
|
622
|
+
},
|
|
623
|
+
{
|
|
624
|
+
name: "Add lightning address to brz_lnurl_receive_metadata and force its re-sync",
|
|
625
|
+
sql: [
|
|
626
|
+
`ALTER TABLE brz_lnurl_receive_metadata ADD COLUMN lightning_address TEXT`,
|
|
627
|
+
`DELETE FROM brz_settings WHERE key = 'lnurl_metadata_updated_after'`,
|
|
628
|
+
],
|
|
629
|
+
},
|
|
615
630
|
];
|
|
616
631
|
}
|
|
617
632
|
}
|
|
@@ -383,7 +383,7 @@ class PostgresTokenStore {
|
|
|
383
383
|
const metadata = _metadataFor(tokenOutputs.metadata, tokenIdentifier);
|
|
384
384
|
if (!metadata) {
|
|
385
385
|
this._log(
|
|
386
|
-
"
|
|
386
|
+
"WARN",
|
|
387
387
|
`Skipping outputs of token ${tokenIdentifier}: no metadata provided`
|
|
388
388
|
);
|
|
389
389
|
continue;
|
|
@@ -629,31 +629,26 @@ class PostgresTokenStore {
|
|
|
629
629
|
}
|
|
630
630
|
|
|
631
631
|
// 2. Insert new outputs, grouped by the token each one names.
|
|
632
|
-
|
|
632
|
+
const spentOutpoints = await this._spentOutpointsAmong(
|
|
633
|
+
client,
|
|
633
634
|
outputsToAdd?.outputs
|
|
635
|
+
);
|
|
636
|
+
const unspentOutputs = (outputsToAdd?.outputs ?? []).filter(
|
|
637
|
+
(o) => !spentOutpoints.has(`${o.prevTxHash}:${o.prevTxVout}`)
|
|
638
|
+
);
|
|
639
|
+
for (const [tokenIdentifier, outputs] of _groupOutputsByToken(
|
|
640
|
+
unspentOutputs
|
|
634
641
|
)) {
|
|
635
642
|
const metadata = _metadataFor(outputsToAdd.metadata, tokenIdentifier);
|
|
636
643
|
if (!metadata) {
|
|
637
644
|
this._log(
|
|
638
|
-
"
|
|
645
|
+
"WARN",
|
|
639
646
|
`Skipping outputs of token ${tokenIdentifier}: no metadata provided`
|
|
640
647
|
);
|
|
641
648
|
continue;
|
|
642
649
|
}
|
|
643
650
|
await this._upsertMetadata(client, metadata);
|
|
644
651
|
|
|
645
|
-
// Clear spent status for outputs being (re-)added.
|
|
646
|
-
const txHashes = outputs.map((o) => o.prevTxHash);
|
|
647
|
-
const vouts = outputs.map((o) => o.prevTxVout);
|
|
648
|
-
await client.query(
|
|
649
|
-
`DELETE FROM brz_token_spent_outputs
|
|
650
|
-
WHERE user_id = $1
|
|
651
|
-
AND (prev_tx_hash, prev_tx_vout) IN (
|
|
652
|
-
SELECT * FROM UNNEST($2::text[], $3::int[])
|
|
653
|
-
)`,
|
|
654
|
-
[this.identity, txHashes, vouts]
|
|
655
|
-
);
|
|
656
|
-
|
|
657
652
|
for (const output of outputs) {
|
|
658
653
|
await this._insertSingleOutput(client, tokenIdentifier, output);
|
|
659
654
|
}
|
|
@@ -1010,9 +1005,7 @@ class PostgresTokenStore {
|
|
|
1010
1005
|
// ===== Private Helpers =====
|
|
1011
1006
|
|
|
1012
1007
|
_log(level, message) {
|
|
1013
|
-
|
|
1014
|
-
this.logger.log({ line: message, level });
|
|
1015
|
-
}
|
|
1008
|
+
this.logger?.log({ line: message, level });
|
|
1016
1009
|
}
|
|
1017
1010
|
|
|
1018
1011
|
/**
|
|
@@ -1205,6 +1198,27 @@ class PostgresTokenStore {
|
|
|
1205
1198
|
);
|
|
1206
1199
|
}
|
|
1207
1200
|
|
|
1201
|
+
async _spentOutpointsAmong(client, outputs) {
|
|
1202
|
+
if (!outputs || outputs.length === 0) {
|
|
1203
|
+
return new Set();
|
|
1204
|
+
}
|
|
1205
|
+
const result = await client.query(
|
|
1206
|
+
`SELECT prev_tx_hash, prev_tx_vout FROM brz_token_spent_outputs
|
|
1207
|
+
WHERE user_id = $1
|
|
1208
|
+
AND (prev_tx_hash, prev_tx_vout) IN (
|
|
1209
|
+
SELECT * FROM UNNEST($2::text[], $3::int[])
|
|
1210
|
+
)`,
|
|
1211
|
+
[
|
|
1212
|
+
this.identity,
|
|
1213
|
+
outputs.map((o) => o.prevTxHash),
|
|
1214
|
+
outputs.map((o) => o.prevTxVout),
|
|
1215
|
+
]
|
|
1216
|
+
);
|
|
1217
|
+
return new Set(
|
|
1218
|
+
result.rows.map((r) => `${r.prev_tx_hash}:${r.prev_tx_vout}`)
|
|
1219
|
+
);
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1208
1222
|
/**
|
|
1209
1223
|
* Insert a single output.
|
|
1210
1224
|
*/
|
|
@@ -58,20 +58,20 @@ class TokenStoreMigrationManager {
|
|
|
58
58
|
const migrations = this._getMigrations(identity);
|
|
59
59
|
|
|
60
60
|
if (currentVersion >= migrations.length) {
|
|
61
|
-
this._log("
|
|
61
|
+
this._log("INFO", `Token store database is up to date (version ${currentVersion})`);
|
|
62
62
|
await client.query("COMMIT");
|
|
63
63
|
return;
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
this._log(
|
|
67
|
-
"
|
|
67
|
+
"INFO",
|
|
68
68
|
`Migrating token store database from version ${currentVersion} to ${migrations.length}`
|
|
69
69
|
);
|
|
70
70
|
|
|
71
71
|
for (let i = currentVersion; i < migrations.length; i++) {
|
|
72
72
|
const migration = migrations[i];
|
|
73
73
|
const version = i + 1;
|
|
74
|
-
this._log("
|
|
74
|
+
this._log("DEBUG", `Running token store migration ${version}: ${migration.name}`);
|
|
75
75
|
|
|
76
76
|
for (const sql of migration.sql) {
|
|
77
77
|
await client.query(sql);
|
|
@@ -84,7 +84,7 @@ class TokenStoreMigrationManager {
|
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
await client.query("COMMIT");
|
|
87
|
-
this._log("
|
|
87
|
+
this._log("INFO", "Token store database migration completed successfully");
|
|
88
88
|
} catch (error) {
|
|
89
89
|
await client.query("ROLLBACK").catch(() => {});
|
|
90
90
|
throw new TokenStoreError(
|
|
@@ -187,11 +187,7 @@ class TokenStoreMigrationManager {
|
|
|
187
187
|
}
|
|
188
188
|
|
|
189
189
|
_log(level, message) {
|
|
190
|
-
|
|
191
|
-
this.logger.log({ line: message, level });
|
|
192
|
-
} else if (level === "error") {
|
|
193
|
-
console.error(`[TokenStoreMigrationManager] ${message}`);
|
|
194
|
-
}
|
|
190
|
+
this.logger?.log({ line: message, level });
|
|
195
191
|
}
|
|
196
192
|
|
|
197
193
|
/**
|
|
@@ -58,20 +58,20 @@ class TreeStoreMigrationManager {
|
|
|
58
58
|
const migrations = this._getMigrations(identity);
|
|
59
59
|
|
|
60
60
|
if (currentVersion >= migrations.length) {
|
|
61
|
-
this._log("
|
|
61
|
+
this._log("INFO", `Tree store database is up to date (version ${currentVersion})`);
|
|
62
62
|
await client.query("COMMIT");
|
|
63
63
|
return;
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
this._log(
|
|
67
|
-
"
|
|
67
|
+
"INFO",
|
|
68
68
|
`Migrating tree store database from version ${currentVersion} to ${migrations.length}`
|
|
69
69
|
);
|
|
70
70
|
|
|
71
71
|
for (let i = currentVersion; i < migrations.length; i++) {
|
|
72
72
|
const migration = migrations[i];
|
|
73
73
|
const version = i + 1;
|
|
74
|
-
this._log("
|
|
74
|
+
this._log("DEBUG", `Running tree store migration ${version}: ${migration.name}`);
|
|
75
75
|
|
|
76
76
|
for (const sql of migration.sql) {
|
|
77
77
|
await client.query(sql);
|
|
@@ -84,7 +84,7 @@ class TreeStoreMigrationManager {
|
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
await client.query("COMMIT");
|
|
87
|
-
this._log("
|
|
87
|
+
this._log("INFO", "Tree store database migration completed successfully");
|
|
88
88
|
} catch (error) {
|
|
89
89
|
await client.query("ROLLBACK").catch(() => {});
|
|
90
90
|
throw new TreeStoreError(
|
|
@@ -179,11 +179,7 @@ class TreeStoreMigrationManager {
|
|
|
179
179
|
}
|
|
180
180
|
|
|
181
181
|
_log(level, message) {
|
|
182
|
-
|
|
183
|
-
this.logger.log({ line: message, level });
|
|
184
|
-
} else if (level === "error") {
|
|
185
|
-
console.error(`[TreeStoreMigrationManager] ${message}`);
|
|
186
|
-
}
|
|
182
|
+
this.logger?.log({ line: message, level });
|
|
187
183
|
}
|
|
188
184
|
|
|
189
185
|
/**
|
package/nodejs/storage/index.cjs
CHANGED
|
@@ -18,7 +18,7 @@ try {
|
|
|
18
18
|
Database = require("better-sqlite3");
|
|
19
19
|
} catch (fallbackError) {
|
|
20
20
|
throw new Error(
|
|
21
|
-
`better-sqlite3 not found. Please install it in your project: npm install better-sqlite3@^
|
|
21
|
+
`better-sqlite3 not found. Please install it in your project: npm install better-sqlite3@^12.2.0\n` +
|
|
22
22
|
`Original error: ${error.message}\nFallback error: ${fallbackError.message}`
|
|
23
23
|
);
|
|
24
24
|
}
|
|
@@ -49,6 +49,8 @@ const SELECT_PAYMENT_SQL = `
|
|
|
49
49
|
p.timestamp,
|
|
50
50
|
p.method,
|
|
51
51
|
p.withdraw_tx_id,
|
|
52
|
+
p.withdraw_vout,
|
|
53
|
+
p.withdraw_destination_address,
|
|
52
54
|
pd.tx_id AS deposit_tx_id,
|
|
53
55
|
pd.vout AS deposit_vout,
|
|
54
56
|
p.spark,
|
|
@@ -72,6 +74,7 @@ const SELECT_PAYMENT_SQL = `
|
|
|
72
74
|
lrm.nostr_zap_request AS lnurl_nostr_zap_request,
|
|
73
75
|
lrm.nostr_zap_receipt AS lnurl_nostr_zap_receipt,
|
|
74
76
|
lrm.sender_comment AS lnurl_sender_comment,
|
|
77
|
+
lrm.lightning_address AS lnurl_lightning_address,
|
|
75
78
|
lrm.payment_hash AS lnurl_payment_hash,
|
|
76
79
|
pm.parent_payment_id
|
|
77
80
|
FROM payments p
|
|
@@ -367,13 +370,15 @@ class SqliteStorage {
|
|
|
367
370
|
this._runPaymentUpsert(payment);
|
|
368
371
|
shouldEmit = true;
|
|
369
372
|
} else if (stored === next) {
|
|
370
|
-
|
|
373
|
+
this._log(
|
|
374
|
+
"DEBUG",
|
|
371
375
|
`Skipping redundant payment event: id=${payment.id} status=${next}`
|
|
372
376
|
);
|
|
373
377
|
this._runPaymentUpsert(payment);
|
|
374
378
|
shouldEmit = false;
|
|
375
379
|
} else if (this._isFinalPaymentStatus(stored)) {
|
|
376
|
-
|
|
380
|
+
this._log(
|
|
381
|
+
"WARN",
|
|
377
382
|
`Skipping payment update (would replace terminal status): id=${payment.id} stored=${stored} new=${next}`
|
|
378
383
|
);
|
|
379
384
|
shouldEmit = false;
|
|
@@ -395,8 +400,8 @@ class SqliteStorage {
|
|
|
395
400
|
|
|
396
401
|
_runPaymentUpsert(payment) {
|
|
397
402
|
const paymentInsert = this.db.prepare(
|
|
398
|
-
`INSERT INTO payments (id, payment_type, status, amount, fees, timestamp, method, withdraw_tx_id, spark)
|
|
399
|
-
VALUES (@id, @paymentType, @status, @amount, @fees, @timestamp, @method, @withdrawTxId, @spark)
|
|
403
|
+
`INSERT INTO payments (id, payment_type, status, amount, fees, timestamp, method, withdraw_tx_id, withdraw_vout, withdraw_destination_address, spark)
|
|
404
|
+
VALUES (@id, @paymentType, @status, @amount, @fees, @timestamp, @method, @withdrawTxId, @withdrawVout, @withdrawDestinationAddress, @spark)
|
|
400
405
|
ON CONFLICT(id) DO UPDATE SET
|
|
401
406
|
payment_type=excluded.payment_type,
|
|
402
407
|
status=excluded.status,
|
|
@@ -405,6 +410,8 @@ class SqliteStorage {
|
|
|
405
410
|
timestamp=excluded.timestamp,
|
|
406
411
|
method=excluded.method,
|
|
407
412
|
withdraw_tx_id=excluded.withdraw_tx_id,
|
|
413
|
+
withdraw_vout=excluded.withdraw_vout,
|
|
414
|
+
withdraw_destination_address=excluded.withdraw_destination_address,
|
|
408
415
|
spark=excluded.spark`
|
|
409
416
|
);
|
|
410
417
|
const depositInsert = this.db.prepare(
|
|
@@ -447,6 +454,7 @@ class SqliteStorage {
|
|
|
447
454
|
htlc_details=COALESCE(excluded.htlc_details, payment_details_spark.htlc_details)`
|
|
448
455
|
);
|
|
449
456
|
|
|
457
|
+
const withdraw = payment.details?.type === "withdraw" ? payment.details : null;
|
|
450
458
|
paymentInsert.run({
|
|
451
459
|
id: payment.id,
|
|
452
460
|
paymentType: payment.paymentType,
|
|
@@ -455,8 +463,9 @@ class SqliteStorage {
|
|
|
455
463
|
fees: payment.fees.toString(),
|
|
456
464
|
timestamp: payment.timestamp,
|
|
457
465
|
method: payment.method ? toJson(payment.method) : null,
|
|
458
|
-
withdrawTxId:
|
|
459
|
-
|
|
466
|
+
withdrawTxId: withdraw?.txId ?? null,
|
|
467
|
+
withdrawVout: withdraw?.vout ?? null,
|
|
468
|
+
withdrawDestinationAddress: withdraw?.destinationAddress ?? null,
|
|
460
469
|
spark: payment.details?.type === "spark" ? 1 : null,
|
|
461
470
|
});
|
|
462
471
|
|
|
@@ -510,6 +519,10 @@ class SqliteStorage {
|
|
|
510
519
|
}
|
|
511
520
|
}
|
|
512
521
|
|
|
522
|
+
_log(level, line) {
|
|
523
|
+
this.logger?.log({ line, level });
|
|
524
|
+
}
|
|
525
|
+
|
|
513
526
|
_normalizePaymentStatus(status) {
|
|
514
527
|
return typeof status === "string" ? status.toLowerCase() : status;
|
|
515
528
|
}
|
|
@@ -580,7 +593,7 @@ class SqliteStorage {
|
|
|
580
593
|
/**
|
|
581
594
|
* Gets payments that have any of the specified parent payment IDs.
|
|
582
595
|
* @param {string[]} parentPaymentIds - Array of parent payment IDs
|
|
583
|
-
* @returns {Promise<Object>} Map of parentPaymentId -> array of
|
|
596
|
+
* @returns {Promise<Object>} Map of parentPaymentId -> array of Payment objects
|
|
584
597
|
*/
|
|
585
598
|
getPaymentsByParentIds(parentPaymentIds) {
|
|
586
599
|
try {
|
|
@@ -1015,7 +1028,7 @@ class SqliteStorage {
|
|
|
1015
1028
|
setLnurlMetadata(metadata) {
|
|
1016
1029
|
try {
|
|
1017
1030
|
const stmt = this.db.prepare(
|
|
1018
|
-
"INSERT OR REPLACE INTO lnurl_receive_metadata (payment_hash, nostr_zap_request, nostr_zap_receipt, sender_comment) VALUES (?, ?, ?, ?)"
|
|
1031
|
+
"INSERT OR REPLACE INTO lnurl_receive_metadata (payment_hash, nostr_zap_request, nostr_zap_receipt, sender_comment, lightning_address) VALUES (?, ?, ?, ?, ?)"
|
|
1019
1032
|
);
|
|
1020
1033
|
|
|
1021
1034
|
const transaction = this.db.transaction(() => {
|
|
@@ -1024,7 +1037,8 @@ class SqliteStorage {
|
|
|
1024
1037
|
item.paymentHash,
|
|
1025
1038
|
item.nostrZapRequest || null,
|
|
1026
1039
|
item.nostrZapReceipt || null,
|
|
1027
|
-
item.senderComment || null
|
|
1040
|
+
item.senderComment || null,
|
|
1041
|
+
item.lightningAddress || null
|
|
1028
1042
|
);
|
|
1029
1043
|
}
|
|
1030
1044
|
});
|
|
@@ -1088,6 +1102,7 @@ class SqliteStorage {
|
|
|
1088
1102
|
nostrZapRequest: row.lnurl_nostr_zap_request || null,
|
|
1089
1103
|
nostrZapReceipt: row.lnurl_nostr_zap_receipt || null,
|
|
1090
1104
|
senderComment: row.lnurl_sender_comment || null,
|
|
1105
|
+
lightningAddress: row.lnurl_lightning_address || null,
|
|
1091
1106
|
};
|
|
1092
1107
|
}
|
|
1093
1108
|
|
|
@@ -1102,10 +1117,16 @@ class SqliteStorage {
|
|
|
1102
1117
|
}
|
|
1103
1118
|
}
|
|
1104
1119
|
} else if (row.withdraw_tx_id) {
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1120
|
+
// A withdrawal stored before the SDK kept these values has no details
|
|
1121
|
+
// until the next sync rewrites it.
|
|
1122
|
+
if (row.withdraw_vout != null && row.withdraw_destination_address != null) {
|
|
1123
|
+
details = {
|
|
1124
|
+
type: "withdraw",
|
|
1125
|
+
txId: row.withdraw_tx_id,
|
|
1126
|
+
vout: row.withdraw_vout,
|
|
1127
|
+
destinationAddress: row.withdraw_destination_address,
|
|
1128
|
+
};
|
|
1129
|
+
}
|
|
1109
1130
|
} else if (row.deposit_tx_id) {
|
|
1110
1131
|
details = {
|
|
1111
1132
|
type: "deposit",
|
|
@@ -21,12 +21,12 @@ class MigrationManager {
|
|
|
21
21
|
targetVersion = targetVersion ?? this.migrations.length;
|
|
22
22
|
|
|
23
23
|
if (currentVersion >= targetVersion) {
|
|
24
|
-
this._log("
|
|
24
|
+
this._log("INFO", `Database is up to date (version ${currentVersion})`);
|
|
25
25
|
return;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
this._log(
|
|
29
|
-
"
|
|
29
|
+
"INFO",
|
|
30
30
|
`Migrating database from version ${currentVersion} to ${targetVersion}`
|
|
31
31
|
);
|
|
32
32
|
|
|
@@ -34,7 +34,7 @@ class MigrationManager {
|
|
|
34
34
|
const transaction = this.db.transaction(() => {
|
|
35
35
|
for (let i = currentVersion; i < targetVersion; i++) {
|
|
36
36
|
const migration = this.migrations[i];
|
|
37
|
-
this._log("
|
|
37
|
+
this._log("DEBUG", `Running migration ${i + 1}: ${migration.name}`);
|
|
38
38
|
|
|
39
39
|
if (Array.isArray(migration.sql)) {
|
|
40
40
|
migration.sql.forEach((sql) => this.db.exec(sql));
|
|
@@ -46,7 +46,7 @@ class MigrationManager {
|
|
|
46
46
|
});
|
|
47
47
|
|
|
48
48
|
transaction();
|
|
49
|
-
this._log("
|
|
49
|
+
this._log("INFO", `Database migration completed successfully`);
|
|
50
50
|
} catch (error) {
|
|
51
51
|
throw new this.StorageError(
|
|
52
52
|
`Migration failed at version ${currentVersion}: ${error.message}`,
|
|
@@ -64,7 +64,7 @@ class MigrationManager {
|
|
|
64
64
|
return row.user_version || 0;
|
|
65
65
|
} catch (error) {
|
|
66
66
|
this._log(
|
|
67
|
-
"
|
|
67
|
+
"WARN",
|
|
68
68
|
`Failed to get database version, assuming 0: ${error.message}`
|
|
69
69
|
);
|
|
70
70
|
return 0;
|
|
@@ -79,16 +79,7 @@ class MigrationManager {
|
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
_log(level, message) {
|
|
82
|
-
|
|
83
|
-
this.logger.log({
|
|
84
|
-
line: message,
|
|
85
|
-
level: level,
|
|
86
|
-
});
|
|
87
|
-
} else if (level === "error") {
|
|
88
|
-
// Fallback to console.error for errors only
|
|
89
|
-
console.error(`[MigrationManager] ${message}`);
|
|
90
|
-
}
|
|
91
|
-
// For info/debug/warn levels, only log if logger is provided
|
|
82
|
+
this.logger?.log({ line: message, level });
|
|
92
83
|
}
|
|
93
84
|
|
|
94
85
|
/**
|
|
@@ -559,6 +550,25 @@ class MigrationManager {
|
|
|
559
550
|
)`,
|
|
560
551
|
],
|
|
561
552
|
},
|
|
553
|
+
{
|
|
554
|
+
// With the sync offset at 0, the SDK re-fetches every transfer on its
|
|
555
|
+
// next sync and fills in both columns for past withdrawals.
|
|
556
|
+
name: "Add withdrawal destination address and output index",
|
|
557
|
+
sql: [
|
|
558
|
+
`ALTER TABLE payments ADD COLUMN withdraw_vout INTEGER`,
|
|
559
|
+
`ALTER TABLE payments ADD COLUMN withdraw_destination_address TEXT`,
|
|
560
|
+
`UPDATE settings
|
|
561
|
+
SET value = json_set(value, '$.offset', 0)
|
|
562
|
+
WHERE key = 'sync_offset' AND json_valid(value)`,
|
|
563
|
+
],
|
|
564
|
+
},
|
|
565
|
+
{
|
|
566
|
+
name: "Add lightning address to lnurl_receive_metadata and force its re-sync",
|
|
567
|
+
sql: [
|
|
568
|
+
`ALTER TABLE lnurl_receive_metadata ADD COLUMN lightning_address TEXT`,
|
|
569
|
+
`DELETE FROM settings WHERE key = 'lnurl_metadata_updated_after'`,
|
|
570
|
+
],
|
|
571
|
+
},
|
|
562
572
|
];
|
|
563
573
|
}
|
|
564
574
|
}
|
|
@@ -49,7 +49,7 @@ try {
|
|
|
49
49
|
Database = require("better-sqlite3");
|
|
50
50
|
} catch (fallbackError) {
|
|
51
51
|
throw new Error(
|
|
52
|
-
`better-sqlite3 not found. Please install it in your project: npm install better-sqlite3@^
|
|
52
|
+
`better-sqlite3 not found. Please install it in your project: npm install better-sqlite3@^12.2.0\n` +
|
|
53
53
|
`Original error: ${error.message}\nFallback error: ${fallbackError.message}`
|
|
54
54
|
);
|
|
55
55
|
}
|
|
@@ -26,12 +26,12 @@ class TreeStoreMigrationManager {
|
|
|
26
26
|
targetVersion = targetVersion ?? this.migrations.length;
|
|
27
27
|
|
|
28
28
|
if (currentVersion >= targetVersion) {
|
|
29
|
-
this._log("
|
|
29
|
+
this._log("INFO", `Tree store is up to date (version ${currentVersion})`);
|
|
30
30
|
return;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
this._log(
|
|
34
|
-
"
|
|
34
|
+
"INFO",
|
|
35
35
|
`Migrating tree store from version ${currentVersion} to ${targetVersion}`
|
|
36
36
|
);
|
|
37
37
|
|
|
@@ -39,7 +39,7 @@ class TreeStoreMigrationManager {
|
|
|
39
39
|
const transaction = this.db.transaction(() => {
|
|
40
40
|
for (let i = currentVersion; i < targetVersion; i++) {
|
|
41
41
|
const migration = this.migrations[i];
|
|
42
|
-
this._log("
|
|
42
|
+
this._log("DEBUG", `Running migration ${i + 1}: ${migration.name}`);
|
|
43
43
|
|
|
44
44
|
if (Array.isArray(migration.sql)) {
|
|
45
45
|
migration.sql.forEach((sql) => this.db.exec(sql));
|
|
@@ -51,7 +51,7 @@ class TreeStoreMigrationManager {
|
|
|
51
51
|
});
|
|
52
52
|
|
|
53
53
|
transaction();
|
|
54
|
-
this._log("
|
|
54
|
+
this._log("INFO", `Tree store migration completed successfully`);
|
|
55
55
|
} catch (error) {
|
|
56
56
|
throw new this.TreeStoreError(
|
|
57
57
|
`Migration failed at version ${currentVersion}: ${error.message}`,
|
|
@@ -83,7 +83,7 @@ class TreeStoreMigrationManager {
|
|
|
83
83
|
return row.version || 0;
|
|
84
84
|
} catch (error) {
|
|
85
85
|
this._log(
|
|
86
|
-
"
|
|
86
|
+
"WARN",
|
|
87
87
|
`Failed to get tree store version, assuming 0: ${error.message}`
|
|
88
88
|
);
|
|
89
89
|
return 0;
|
|
@@ -100,14 +100,7 @@ class TreeStoreMigrationManager {
|
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
_log(level, message) {
|
|
103
|
-
|
|
104
|
-
this.logger.log({
|
|
105
|
-
line: message,
|
|
106
|
-
level: level,
|
|
107
|
-
});
|
|
108
|
-
} else if (level === "error") {
|
|
109
|
-
console.error(`[TreeStoreMigrationManager] ${message}`);
|
|
110
|
-
}
|
|
103
|
+
this.logger?.log({ line: message, level });
|
|
111
104
|
}
|
|
112
105
|
|
|
113
106
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@breeztech/breez-sdk-spark",
|
|
3
|
-
"version": "0.27.
|
|
3
|
+
"version": "0.27.3-dev",
|
|
4
4
|
"description": "Breez Spark SDK",
|
|
5
5
|
"repository": "https://github.com/breez/spark-sdk",
|
|
6
6
|
"author": "Breez <contact@breez.technology> (https://github.com/breez)",
|
|
@@ -14,13 +14,23 @@
|
|
|
14
14
|
"deno",
|
|
15
15
|
"nodejs",
|
|
16
16
|
"web",
|
|
17
|
-
"ssr"
|
|
18
|
-
"!examples"
|
|
17
|
+
"ssr"
|
|
19
18
|
],
|
|
19
|
+
"types": "./nodejs/index.d.ts",
|
|
20
20
|
"exports": {
|
|
21
21
|
"./bundler": "./bundler/index.js",
|
|
22
22
|
"./deno": "./deno/breez_sdk_spark_wasm.js",
|
|
23
|
-
"./nodejs":
|
|
23
|
+
"./nodejs": {
|
|
24
|
+
"import": {
|
|
25
|
+
"types": "./nodejs/index.d.mts",
|
|
26
|
+
"default": "./nodejs/index.mjs"
|
|
27
|
+
},
|
|
28
|
+
"require": {
|
|
29
|
+
"types": "./nodejs/index.d.ts",
|
|
30
|
+
"default": "./nodejs/index.js"
|
|
31
|
+
},
|
|
32
|
+
"default": "./nodejs/index.js"
|
|
33
|
+
},
|
|
24
34
|
"./web": "./web/index.js",
|
|
25
35
|
"./ssr": "./ssr/index.js",
|
|
26
36
|
"./passkey-prf-provider": {
|
|
@@ -30,10 +40,21 @@
|
|
|
30
40
|
},
|
|
31
41
|
".": {
|
|
32
42
|
"node": {
|
|
33
|
-
"import":
|
|
34
|
-
|
|
43
|
+
"import": {
|
|
44
|
+
"types": "./nodejs/index.d.mts",
|
|
45
|
+
"default": "./nodejs/index.mjs"
|
|
46
|
+
},
|
|
47
|
+
"require": {
|
|
48
|
+
"types": "./nodejs/index.d.ts",
|
|
49
|
+
"default": "./nodejs/index.js"
|
|
50
|
+
},
|
|
51
|
+
"default": "./nodejs/index.js"
|
|
35
52
|
},
|
|
36
53
|
"deno": "./deno/breez_sdk_spark_wasm.js",
|
|
54
|
+
"require": {
|
|
55
|
+
"types": "./nodejs/index.d.ts",
|
|
56
|
+
"default": "./web/index.js"
|
|
57
|
+
},
|
|
37
58
|
"default": "./web/index.js"
|
|
38
59
|
}
|
|
39
60
|
},
|
package/ssr/index.js
CHANGED
|
@@ -48,6 +48,11 @@ export function createTurnkeySigningOnlySigner(...args) {
|
|
|
48
48
|
return _module.createTurnkeySigningOnlySigner(...args);
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
+
export function defaultBridgingConfig(...args) {
|
|
52
|
+
if (!_module) _notInitialized('defaultBridgingConfig');
|
|
53
|
+
return _module.defaultBridgingConfig(...args);
|
|
54
|
+
}
|
|
55
|
+
|
|
51
56
|
export function defaultConfig(...args) {
|
|
52
57
|
if (!_module) _notInitialized('defaultConfig');
|
|
53
58
|
return _module.defaultConfig(...args);
|
|
@@ -98,6 +103,11 @@ export function mysqlStorage(...args) {
|
|
|
98
103
|
return _module.mysqlStorage(...args);
|
|
99
104
|
}
|
|
100
105
|
|
|
106
|
+
export function newBridgingClient(...args) {
|
|
107
|
+
if (!_module) _notInitialized('newBridgingClient');
|
|
108
|
+
return _module.newBridgingClient(...args);
|
|
109
|
+
}
|
|
110
|
+
|
|
101
111
|
export function newRestChainService(...args) {
|
|
102
112
|
if (!_module) _notInitialized('newRestChainService');
|
|
103
113
|
return _module.newRestChainService(...args);
|
|
@@ -152,6 +162,20 @@ export class BreezSdk {
|
|
|
152
162
|
}
|
|
153
163
|
}
|
|
154
164
|
|
|
165
|
+
export class BridgingClient {
|
|
166
|
+
constructor(...args) {
|
|
167
|
+
if (!_module) _notInitialized('new BridgingClient');
|
|
168
|
+
return new _module.BridgingClient(...args);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export class ConsoleLogger {
|
|
173
|
+
constructor(...args) {
|
|
174
|
+
if (!_module) _notInitialized('new ConsoleLogger');
|
|
175
|
+
return new _module.ConsoleLogger(...args);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
155
179
|
export class DefaultCpfpSigner {
|
|
156
180
|
constructor(...args) {
|
|
157
181
|
if (!_module) _notInitialized('new DefaultCpfpSigner');
|