@breeztech/breez-sdk-spark 0.9.1 → 0.11.0-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 +618 -538
- package/bundler/breez_sdk_spark_wasm_bg.js +146 -46
- package/bundler/breez_sdk_spark_wasm_bg.wasm +0 -0
- package/bundler/breez_sdk_spark_wasm_bg.wasm.d.ts +9 -3
- package/bundler/storage/index.js +229 -49
- package/deno/breez_sdk_spark_wasm.d.ts +618 -538
- package/deno/breez_sdk_spark_wasm.js +141 -46
- package/deno/breez_sdk_spark_wasm_bg.wasm +0 -0
- package/deno/breez_sdk_spark_wasm_bg.wasm.d.ts +9 -3
- package/nodejs/breez_sdk_spark_wasm.d.ts +618 -538
- package/nodejs/breez_sdk_spark_wasm.js +146 -46
- package/nodejs/breez_sdk_spark_wasm_bg.wasm +0 -0
- package/nodejs/breez_sdk_spark_wasm_bg.wasm.d.ts +9 -3
- package/nodejs/index.js +12 -2
- package/nodejs/package.json +1 -0
- package/nodejs/postgres-storage/errors.cjs +19 -0
- package/nodejs/postgres-storage/index.cjs +1379 -0
- package/nodejs/postgres-storage/migrations.cjs +241 -0
- package/nodejs/postgres-storage/package.json +9 -0
- package/nodejs/storage/index.cjs +100 -6
- package/nodejs/storage/migrations.cjs +25 -0
- package/package.json +3 -2
- package/web/breez_sdk_spark_wasm.d.ts +627 -541
- package/web/breez_sdk_spark_wasm.js +141 -46
- package/web/breez_sdk_spark_wasm_bg.wasm +0 -0
- package/web/breez_sdk_spark_wasm_bg.wasm.d.ts +9 -3
- package/web/storage/index.js +229 -49
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Database Migration Manager for Breez SDK PostgreSQL Storage
|
|
3
|
+
*
|
|
4
|
+
* Uses a schema_migrations table + pg_advisory_xact_lock to safely run
|
|
5
|
+
* migrations from concurrent processes.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const { StorageError } = require("./errors.cjs");
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Advisory lock ID for migrations.
|
|
12
|
+
* Derived from ASCII bytes of "MIGR" (0x4D49_4752).
|
|
13
|
+
*/
|
|
14
|
+
const MIGRATION_LOCK_ID = "1296388946"; // 0x4D494752 as decimal string
|
|
15
|
+
|
|
16
|
+
class PostgresMigrationManager {
|
|
17
|
+
constructor(logger = null) {
|
|
18
|
+
this.logger = logger;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Run all pending migrations inside a single transaction with an advisory lock.
|
|
23
|
+
* @param {import('pg').Pool} pool
|
|
24
|
+
*/
|
|
25
|
+
async migrate(pool) {
|
|
26
|
+
const client = await pool.connect();
|
|
27
|
+
try {
|
|
28
|
+
await client.query("BEGIN");
|
|
29
|
+
|
|
30
|
+
// Transaction-level advisory lock — automatically released on COMMIT/ROLLBACK
|
|
31
|
+
await client.query(`SELECT pg_advisory_xact_lock(${MIGRATION_LOCK_ID})`);
|
|
32
|
+
|
|
33
|
+
// Create the migrations tracking table if needed
|
|
34
|
+
await client.query(`
|
|
35
|
+
CREATE TABLE IF NOT EXISTS schema_migrations (
|
|
36
|
+
version INTEGER PRIMARY KEY,
|
|
37
|
+
applied_at TIMESTAMPTZ DEFAULT NOW()
|
|
38
|
+
)
|
|
39
|
+
`);
|
|
40
|
+
|
|
41
|
+
// Get current version
|
|
42
|
+
const versionResult = await client.query(
|
|
43
|
+
"SELECT COALESCE(MAX(version), 0) AS version FROM schema_migrations"
|
|
44
|
+
);
|
|
45
|
+
const currentVersion = versionResult.rows[0].version;
|
|
46
|
+
|
|
47
|
+
const migrations = this._getMigrations();
|
|
48
|
+
|
|
49
|
+
if (currentVersion >= migrations.length) {
|
|
50
|
+
this._log("info", `Database is up to date (version ${currentVersion})`);
|
|
51
|
+
await client.query("COMMIT");
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
this._log(
|
|
56
|
+
"info",
|
|
57
|
+
`Migrating database from version ${currentVersion} to ${migrations.length}`
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
for (let i = currentVersion; i < migrations.length; i++) {
|
|
61
|
+
const migration = migrations[i];
|
|
62
|
+
const version = i + 1;
|
|
63
|
+
this._log("debug", `Running migration ${version}: ${migration.name}`);
|
|
64
|
+
|
|
65
|
+
for (const sql of migration.sql) {
|
|
66
|
+
await client.query(sql);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
await client.query(
|
|
70
|
+
"INSERT INTO schema_migrations (version) VALUES ($1)",
|
|
71
|
+
[version]
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
await client.query("COMMIT");
|
|
76
|
+
this._log("info", "Database migration completed successfully");
|
|
77
|
+
} catch (error) {
|
|
78
|
+
await client.query("ROLLBACK").catch(() => {});
|
|
79
|
+
throw new StorageError(
|
|
80
|
+
`Migration failed: ${error.message}`,
|
|
81
|
+
error
|
|
82
|
+
);
|
|
83
|
+
} finally {
|
|
84
|
+
client.release();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
_log(level, message) {
|
|
89
|
+
if (this.logger && typeof this.logger.log === "function") {
|
|
90
|
+
this.logger.log({ line: message, level });
|
|
91
|
+
} else if (level === "error") {
|
|
92
|
+
console.error(`[PostgresMigrationManager] ${message}`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Single migration creating all tables at their final schema.
|
|
98
|
+
* This mirrors the Rust-native PostgresStorage schema but uses camelCase
|
|
99
|
+
* enum values (as produced by the WASM bridge).
|
|
100
|
+
*/
|
|
101
|
+
_getMigrations() {
|
|
102
|
+
return [
|
|
103
|
+
{
|
|
104
|
+
name: "Create all tables at final schema",
|
|
105
|
+
sql: [
|
|
106
|
+
// -- Core tables --
|
|
107
|
+
`CREATE TABLE IF NOT EXISTS payments (
|
|
108
|
+
id TEXT PRIMARY KEY,
|
|
109
|
+
payment_type TEXT NOT NULL,
|
|
110
|
+
status TEXT NOT NULL,
|
|
111
|
+
amount TEXT NOT NULL,
|
|
112
|
+
fees TEXT NOT NULL,
|
|
113
|
+
timestamp BIGINT NOT NULL,
|
|
114
|
+
method TEXT,
|
|
115
|
+
withdraw_tx_id TEXT,
|
|
116
|
+
deposit_tx_id TEXT,
|
|
117
|
+
spark BOOLEAN
|
|
118
|
+
)`,
|
|
119
|
+
|
|
120
|
+
`CREATE TABLE IF NOT EXISTS settings (
|
|
121
|
+
key TEXT PRIMARY KEY,
|
|
122
|
+
value TEXT NOT NULL
|
|
123
|
+
)`,
|
|
124
|
+
|
|
125
|
+
`CREATE TABLE IF NOT EXISTS unclaimed_deposits (
|
|
126
|
+
txid TEXT NOT NULL,
|
|
127
|
+
vout INTEGER NOT NULL,
|
|
128
|
+
amount_sats BIGINT,
|
|
129
|
+
claim_error JSONB,
|
|
130
|
+
refund_tx TEXT,
|
|
131
|
+
refund_tx_id TEXT,
|
|
132
|
+
PRIMARY KEY (txid, vout)
|
|
133
|
+
)`,
|
|
134
|
+
|
|
135
|
+
`CREATE TABLE IF NOT EXISTS payment_metadata (
|
|
136
|
+
payment_id TEXT PRIMARY KEY,
|
|
137
|
+
parent_payment_id TEXT,
|
|
138
|
+
lnurl_pay_info JSONB,
|
|
139
|
+
lnurl_withdraw_info JSONB,
|
|
140
|
+
lnurl_description TEXT,
|
|
141
|
+
conversion_info JSONB
|
|
142
|
+
)`,
|
|
143
|
+
|
|
144
|
+
`CREATE TABLE IF NOT EXISTS payment_details_lightning (
|
|
145
|
+
payment_id TEXT PRIMARY KEY,
|
|
146
|
+
invoice TEXT NOT NULL,
|
|
147
|
+
payment_hash TEXT NOT NULL,
|
|
148
|
+
destination_pubkey TEXT NOT NULL,
|
|
149
|
+
description TEXT,
|
|
150
|
+
preimage TEXT,
|
|
151
|
+
htlc_status TEXT NOT NULL,
|
|
152
|
+
htlc_expiry_time BIGINT NOT NULL
|
|
153
|
+
)`,
|
|
154
|
+
|
|
155
|
+
`CREATE TABLE IF NOT EXISTS payment_details_token (
|
|
156
|
+
payment_id TEXT PRIMARY KEY,
|
|
157
|
+
metadata JSONB NOT NULL,
|
|
158
|
+
tx_hash TEXT NOT NULL,
|
|
159
|
+
tx_type TEXT NOT NULL,
|
|
160
|
+
invoice_details JSONB
|
|
161
|
+
)`,
|
|
162
|
+
|
|
163
|
+
`CREATE TABLE IF NOT EXISTS payment_details_spark (
|
|
164
|
+
payment_id TEXT PRIMARY KEY,
|
|
165
|
+
invoice_details JSONB,
|
|
166
|
+
htlc_details JSONB
|
|
167
|
+
)`,
|
|
168
|
+
|
|
169
|
+
`CREATE TABLE IF NOT EXISTS lnurl_receive_metadata (
|
|
170
|
+
payment_hash TEXT PRIMARY KEY,
|
|
171
|
+
nostr_zap_request TEXT,
|
|
172
|
+
nostr_zap_receipt TEXT,
|
|
173
|
+
sender_comment TEXT,
|
|
174
|
+
preimage TEXT
|
|
175
|
+
)`,
|
|
176
|
+
|
|
177
|
+
// -- Sync tables --
|
|
178
|
+
`CREATE TABLE IF NOT EXISTS sync_revision (
|
|
179
|
+
id INTEGER PRIMARY KEY DEFAULT 1,
|
|
180
|
+
revision BIGINT NOT NULL DEFAULT 0,
|
|
181
|
+
CHECK (id = 1)
|
|
182
|
+
)`,
|
|
183
|
+
`INSERT INTO sync_revision (id, revision) VALUES (1, 0) ON CONFLICT (id) DO NOTHING`,
|
|
184
|
+
|
|
185
|
+
`CREATE TABLE IF NOT EXISTS sync_outgoing (
|
|
186
|
+
record_type TEXT NOT NULL,
|
|
187
|
+
data_id TEXT NOT NULL,
|
|
188
|
+
schema_version TEXT NOT NULL,
|
|
189
|
+
commit_time BIGINT NOT NULL,
|
|
190
|
+
updated_fields_json JSONB NOT NULL,
|
|
191
|
+
revision BIGINT NOT NULL
|
|
192
|
+
)`,
|
|
193
|
+
|
|
194
|
+
`CREATE TABLE IF NOT EXISTS sync_state (
|
|
195
|
+
record_type TEXT NOT NULL,
|
|
196
|
+
data_id TEXT NOT NULL,
|
|
197
|
+
schema_version TEXT NOT NULL,
|
|
198
|
+
commit_time BIGINT NOT NULL,
|
|
199
|
+
data JSONB NOT NULL,
|
|
200
|
+
revision BIGINT NOT NULL,
|
|
201
|
+
PRIMARY KEY (record_type, data_id)
|
|
202
|
+
)`,
|
|
203
|
+
|
|
204
|
+
`CREATE TABLE IF NOT EXISTS sync_incoming (
|
|
205
|
+
record_type TEXT NOT NULL,
|
|
206
|
+
data_id TEXT NOT NULL,
|
|
207
|
+
schema_version TEXT NOT NULL,
|
|
208
|
+
commit_time BIGINT NOT NULL,
|
|
209
|
+
data JSONB NOT NULL,
|
|
210
|
+
revision BIGINT NOT NULL,
|
|
211
|
+
PRIMARY KEY (record_type, data_id, revision)
|
|
212
|
+
)`,
|
|
213
|
+
|
|
214
|
+
// -- Indexes --
|
|
215
|
+
`CREATE INDEX IF NOT EXISTS idx_payments_timestamp ON payments(timestamp)`,
|
|
216
|
+
`CREATE INDEX IF NOT EXISTS idx_payments_payment_type ON payments(payment_type)`,
|
|
217
|
+
`CREATE INDEX IF NOT EXISTS idx_payments_status ON payments(status)`,
|
|
218
|
+
`CREATE INDEX IF NOT EXISTS idx_payment_details_lightning_invoice ON payment_details_lightning(invoice)`,
|
|
219
|
+
`CREATE INDEX IF NOT EXISTS idx_payment_details_lightning_payment_hash ON payment_details_lightning(payment_hash)`,
|
|
220
|
+
`CREATE INDEX IF NOT EXISTS idx_payment_metadata_parent ON payment_metadata(parent_payment_id)`,
|
|
221
|
+
`CREATE INDEX IF NOT EXISTS idx_sync_outgoing_data_id_record_type ON sync_outgoing(record_type, data_id)`,
|
|
222
|
+
`CREATE INDEX IF NOT EXISTS idx_sync_incoming_revision ON sync_incoming(revision)`,
|
|
223
|
+
],
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
name: "Create contacts table",
|
|
227
|
+
sql: [
|
|
228
|
+
`CREATE TABLE IF NOT EXISTS contacts (
|
|
229
|
+
id TEXT PRIMARY KEY,
|
|
230
|
+
name TEXT NOT NULL,
|
|
231
|
+
payment_identifier TEXT NOT NULL,
|
|
232
|
+
created_at BIGINT NOT NULL,
|
|
233
|
+
updated_at BIGINT NOT NULL
|
|
234
|
+
)`,
|
|
235
|
+
],
|
|
236
|
+
},
|
|
237
|
+
];
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
module.exports = { PostgresMigrationManager };
|
package/nodejs/storage/index.cjs
CHANGED
|
@@ -62,6 +62,7 @@ const SELECT_PAYMENT_SQL = `
|
|
|
62
62
|
lrm.nostr_zap_request AS lnurl_nostr_zap_request,
|
|
63
63
|
lrm.nostr_zap_receipt AS lnurl_nostr_zap_receipt,
|
|
64
64
|
lrm.sender_comment AS lnurl_sender_comment,
|
|
65
|
+
lrm.payment_hash AS lnurl_payment_hash,
|
|
65
66
|
pm.parent_payment_id
|
|
66
67
|
FROM payments p
|
|
67
68
|
LEFT JOIN payment_details_lightning l ON p.id = l.payment_id
|
|
@@ -259,6 +260,19 @@ class SqliteStorage {
|
|
|
259
260
|
paymentDetailsClauses.push("t.tx_type = ?");
|
|
260
261
|
params.push(paymentDetailsFilter.txType);
|
|
261
262
|
}
|
|
263
|
+
// Filter by LNURL preimage status
|
|
264
|
+
if (
|
|
265
|
+
paymentDetailsFilter.type === "lightning" &&
|
|
266
|
+
paymentDetailsFilter.hasLnurlPreimage !== undefined
|
|
267
|
+
) {
|
|
268
|
+
if (paymentDetailsFilter.hasLnurlPreimage) {
|
|
269
|
+
paymentDetailsClauses.push("lrm.preimage IS NOT NULL");
|
|
270
|
+
} else {
|
|
271
|
+
paymentDetailsClauses.push(
|
|
272
|
+
"lrm.payment_hash IS NOT NULL AND l.preimage IS NOT NULL AND lrm.preimage IS NULL"
|
|
273
|
+
);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
262
276
|
|
|
263
277
|
|
|
264
278
|
if (paymentDetailsClauses.length > 0) {
|
|
@@ -406,8 +420,8 @@ class SqliteStorage {
|
|
|
406
420
|
destinationPubkey: payment.details.destinationPubkey,
|
|
407
421
|
description: payment.details.description,
|
|
408
422
|
preimage: payment.details.htlcDetails?.preimage,
|
|
409
|
-
htlcStatus: payment.details.htlcDetails?.status
|
|
410
|
-
htlcExpiryTime: payment.details.htlcDetails?.expiryTime
|
|
423
|
+
htlcStatus: payment.details.htlcDetails?.status ?? null,
|
|
424
|
+
htlcExpiryTime: payment.details.htlcDetails?.expiryTime ?? 0,
|
|
411
425
|
});
|
|
412
426
|
}
|
|
413
427
|
|
|
@@ -681,7 +695,7 @@ class SqliteStorage {
|
|
|
681
695
|
setLnurlMetadata(metadata) {
|
|
682
696
|
try {
|
|
683
697
|
const stmt = this.db.prepare(
|
|
684
|
-
"INSERT OR REPLACE INTO lnurl_receive_metadata (payment_hash, nostr_zap_request, nostr_zap_receipt, sender_comment) VALUES (?, ?, ?, ?)"
|
|
698
|
+
"INSERT OR REPLACE INTO lnurl_receive_metadata (payment_hash, nostr_zap_request, nostr_zap_receipt, sender_comment, preimage) VALUES (?, ?, ?, ?, ?)"
|
|
685
699
|
);
|
|
686
700
|
|
|
687
701
|
const transaction = this.db.transaction(() => {
|
|
@@ -690,7 +704,8 @@ class SqliteStorage {
|
|
|
690
704
|
item.paymentHash,
|
|
691
705
|
item.nostrZapRequest || null,
|
|
692
706
|
item.nostrZapReceipt || null,
|
|
693
|
-
item.senderComment || null
|
|
707
|
+
item.senderComment || null,
|
|
708
|
+
item.preimage || null
|
|
694
709
|
);
|
|
695
710
|
}
|
|
696
711
|
});
|
|
@@ -721,7 +736,7 @@ class SqliteStorage {
|
|
|
721
736
|
? {
|
|
722
737
|
paymentHash: row.lightning_payment_hash,
|
|
723
738
|
preimage: row.lightning_preimage || null,
|
|
724
|
-
expiryTime: row.lightning_htlc_expiry_time
|
|
739
|
+
expiryTime: row.lightning_htlc_expiry_time ?? 0,
|
|
725
740
|
status: row.lightning_htlc_status,
|
|
726
741
|
}
|
|
727
742
|
: (() => { throw new StorageError(`htlc_status is required for Lightning payment ${row.id}`); })(),
|
|
@@ -749,7 +764,7 @@ class SqliteStorage {
|
|
|
749
764
|
}
|
|
750
765
|
}
|
|
751
766
|
|
|
752
|
-
if (row.
|
|
767
|
+
if (row.lnurl_payment_hash) {
|
|
753
768
|
details.lnurlReceiveMetadata = {
|
|
754
769
|
nostrZapRequest: row.lnurl_nostr_zap_request || null,
|
|
755
770
|
nostrZapReceipt: row.lnurl_nostr_zap_receipt || null,
|
|
@@ -815,6 +830,7 @@ class SqliteStorage {
|
|
|
815
830
|
timestamp: row.timestamp,
|
|
816
831
|
method,
|
|
817
832
|
details,
|
|
833
|
+
conversionDetails: null,
|
|
818
834
|
};
|
|
819
835
|
}
|
|
820
836
|
|
|
@@ -1239,6 +1255,84 @@ class SqliteStorage {
|
|
|
1239
1255
|
);
|
|
1240
1256
|
}
|
|
1241
1257
|
}
|
|
1258
|
+
|
|
1259
|
+
// ===== Contact Operations =====
|
|
1260
|
+
|
|
1261
|
+
listContacts(request) {
|
|
1262
|
+
try {
|
|
1263
|
+
const offset = request.offset !== null && request.offset !== undefined ? request.offset : 0;
|
|
1264
|
+
const limit = request.limit !== null && request.limit !== undefined ? request.limit : 4294967295;
|
|
1265
|
+
|
|
1266
|
+
const stmt = this.db.prepare(`
|
|
1267
|
+
SELECT id, name, payment_identifier AS paymentIdentifier, created_at AS createdAt, updated_at AS updatedAt
|
|
1268
|
+
FROM contacts
|
|
1269
|
+
ORDER BY name ASC
|
|
1270
|
+
LIMIT ? OFFSET ?
|
|
1271
|
+
`);
|
|
1272
|
+
const rows = stmt.all(limit, offset);
|
|
1273
|
+
|
|
1274
|
+
return Promise.resolve(rows);
|
|
1275
|
+
} catch (error) {
|
|
1276
|
+
return Promise.reject(
|
|
1277
|
+
new StorageError(`Failed to list contacts: ${error.message}`, error)
|
|
1278
|
+
);
|
|
1279
|
+
}
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1282
|
+
getContact(id) {
|
|
1283
|
+
try {
|
|
1284
|
+
const stmt = this.db.prepare(`
|
|
1285
|
+
SELECT id, name, payment_identifier AS paymentIdentifier, created_at AS createdAt, updated_at AS updatedAt
|
|
1286
|
+
FROM contacts
|
|
1287
|
+
WHERE id = ?
|
|
1288
|
+
`);
|
|
1289
|
+
const row = stmt.get(id);
|
|
1290
|
+
return Promise.resolve(row || null);
|
|
1291
|
+
} catch (error) {
|
|
1292
|
+
return Promise.reject(
|
|
1293
|
+
new StorageError(`Failed to get contact: ${error.message}`, error)
|
|
1294
|
+
);
|
|
1295
|
+
}
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1298
|
+
insertContact(contact) {
|
|
1299
|
+
try {
|
|
1300
|
+
const stmt = this.db.prepare(`
|
|
1301
|
+
INSERT INTO contacts (id, name, payment_identifier, created_at, updated_at)
|
|
1302
|
+
VALUES (?, ?, ?, ?, ?)
|
|
1303
|
+
ON CONFLICT(id) DO UPDATE SET
|
|
1304
|
+
name = excluded.name,
|
|
1305
|
+
payment_identifier = excluded.payment_identifier,
|
|
1306
|
+
updated_at = excluded.updated_at
|
|
1307
|
+
`);
|
|
1308
|
+
|
|
1309
|
+
stmt.run(
|
|
1310
|
+
contact.id,
|
|
1311
|
+
contact.name,
|
|
1312
|
+
contact.paymentIdentifier,
|
|
1313
|
+
contact.createdAt,
|
|
1314
|
+
contact.updatedAt
|
|
1315
|
+
);
|
|
1316
|
+
|
|
1317
|
+
return Promise.resolve();
|
|
1318
|
+
} catch (error) {
|
|
1319
|
+
return Promise.reject(
|
|
1320
|
+
new StorageError(`Failed to insert contact: ${error.message}`, error)
|
|
1321
|
+
);
|
|
1322
|
+
}
|
|
1323
|
+
}
|
|
1324
|
+
|
|
1325
|
+
deleteContact(id) {
|
|
1326
|
+
try {
|
|
1327
|
+
const stmt = this.db.prepare("DELETE FROM contacts WHERE id = ?");
|
|
1328
|
+
stmt.run(id);
|
|
1329
|
+
return Promise.resolve();
|
|
1330
|
+
} catch (error) {
|
|
1331
|
+
return Promise.reject(
|
|
1332
|
+
new StorageError(`Failed to delete contact: ${error.message}`, error)
|
|
1333
|
+
);
|
|
1334
|
+
}
|
|
1335
|
+
}
|
|
1242
1336
|
}
|
|
1243
1337
|
|
|
1244
1338
|
async function createDefaultStorage(dataDir, logger = null) {
|
|
@@ -344,6 +344,13 @@ class MigrationManager {
|
|
|
344
344
|
`DELETE FROM sync_state`,
|
|
345
345
|
`UPDATE sync_revision SET revision = 0`,
|
|
346
346
|
`DELETE FROM settings WHERE key = 'sync_initial_complete'`
|
|
347
|
+
],
|
|
348
|
+
},
|
|
349
|
+
{
|
|
350
|
+
name: "Add preimage column to lnurl_receive_metadata for LUD-21 and NIP-57",
|
|
351
|
+
sql: [
|
|
352
|
+
`ALTER TABLE lnurl_receive_metadata ADD COLUMN preimage TEXT`,
|
|
353
|
+
`DELETE FROM settings WHERE key = 'lnurl_metadata_updated_after'`
|
|
347
354
|
]
|
|
348
355
|
},
|
|
349
356
|
{
|
|
@@ -367,6 +374,24 @@ class MigrationManager {
|
|
|
367
374
|
WHERE key = 'sync_offset' AND json_valid(value)`,
|
|
368
375
|
]
|
|
369
376
|
},
|
|
377
|
+
{
|
|
378
|
+
name: "Clear cached lightning address for LnurlInfo schema change",
|
|
379
|
+
sql: `DELETE FROM settings WHERE key = 'lightning_address'`
|
|
380
|
+
},
|
|
381
|
+
{
|
|
382
|
+
name: "Add index on payment_hash for JOIN with lnurl_receive_metadata",
|
|
383
|
+
sql: `CREATE INDEX IF NOT EXISTS idx_payment_details_lightning_payment_hash ON payment_details_lightning(payment_hash)`
|
|
384
|
+
},
|
|
385
|
+
{
|
|
386
|
+
name: "Create contacts table",
|
|
387
|
+
sql: `CREATE TABLE contacts (
|
|
388
|
+
id TEXT PRIMARY KEY,
|
|
389
|
+
name TEXT NOT NULL,
|
|
390
|
+
payment_identifier TEXT NOT NULL,
|
|
391
|
+
created_at INTEGER NOT NULL,
|
|
392
|
+
updated_at INTEGER NOT NULL
|
|
393
|
+
)`
|
|
394
|
+
},
|
|
370
395
|
];
|
|
371
396
|
}
|
|
372
397
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@breeztech/breez-sdk-spark",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0-dev1",
|
|
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)",
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
"node": ">=22"
|
|
35
35
|
},
|
|
36
36
|
"optionalDependencies": {
|
|
37
|
-
"better-sqlite3": "^12.2.0"
|
|
37
|
+
"better-sqlite3": "^12.2.0",
|
|
38
|
+
"pg": "^8.18.0"
|
|
38
39
|
}
|
|
39
40
|
}
|