@arkade-os/sdk 0.5.2 → 0.5.4

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.
Files changed (88) hide show
  1. package/README.md +36 -34
  2. package/dist/adapters/expo.cjs +9 -5
  3. package/dist/adapters/expo.d.cts +11 -7
  4. package/dist/adapters/expo.d.ts +11 -7
  5. package/dist/adapters/expo.js +3 -3
  6. package/dist/{asyncStorageTaskQueue-DIn7bTqN.d.ts → asyncStorageTaskQueue-DHMIxY04.d.ts} +2 -2
  7. package/dist/{asyncStorageTaskQueue-BtEc3Qca.d.cts → asyncStorageTaskQueue-DTBa8EH7.d.cts} +2 -2
  8. package/dist/{chunk-LWRMSC4M.js → chunk-6CUP6ZIF.js} +4 -4
  9. package/dist/{chunk-LWRMSC4M.js.map → chunk-6CUP6ZIF.js.map} +1 -1
  10. package/dist/{chunk-HKG26NUT.js → chunk-AG4TFD6F.js} +140 -59
  11. package/dist/chunk-AG4TFD6F.js.map +1 -0
  12. package/dist/{chunk-PVFQFQBY.cjs → chunk-B6VNKGIH.cjs} +10 -10
  13. package/dist/chunk-B6VNKGIH.cjs.map +1 -0
  14. package/dist/{chunk-U5XG7SWA.js → chunk-BTRCN4JJ.js} +22 -19
  15. package/dist/chunk-BTRCN4JJ.js.map +1 -0
  16. package/dist/{chunk-TAIWH3HG.cjs → chunk-DNITZVNG.cjs} +28 -47
  17. package/dist/chunk-DNITZVNG.cjs.map +1 -0
  18. package/dist/{chunk-OM6FJ76H.cjs → chunk-E6OOJEHL.cjs} +49 -49
  19. package/dist/{chunk-OM6FJ76H.cjs.map → chunk-E6OOJEHL.cjs.map} +1 -1
  20. package/dist/{chunk-2OCYL6BJ.cjs → chunk-F3FAE7VJ.cjs} +850 -652
  21. package/dist/chunk-F3FAE7VJ.cjs.map +1 -0
  22. package/dist/{chunk-GGKR4O5X.cjs → chunk-GHUUT54D.cjs} +143 -58
  23. package/dist/chunk-GHUUT54D.cjs.map +1 -0
  24. package/dist/{chunk-MOBDJ7U2.js → chunk-MWVAWFX6.js} +4 -4
  25. package/dist/chunk-MWVAWFX6.js.map +1 -0
  26. package/dist/{chunk-2QRUQXLS.js → chunk-TUOLZBNC.js} +19 -39
  27. package/dist/chunk-TUOLZBNC.js.map +1 -0
  28. package/dist/{chunk-64R7CRKN.cjs → chunk-WXNSISXK.cjs} +37 -34
  29. package/dist/chunk-WXNSISXK.cjs.map +1 -0
  30. package/dist/{chunk-AJWXVQYG.js → chunk-ZJHLLDBP.js} +372 -177
  31. package/dist/chunk-ZJHLLDBP.js.map +1 -0
  32. package/dist/contracts/handlers/index.cjs +9 -9
  33. package/dist/contracts/handlers/index.d.cts +3 -3
  34. package/dist/contracts/handlers/index.d.ts +3 -3
  35. package/dist/contracts/handlers/index.js +2 -2
  36. package/dist/{delegate-CaL8EN4Q.d.cts → delegate-f4_t864Z.d.cts} +1 -1
  37. package/dist/{delegate-Jd4zs88Q.d.ts → delegate-xrSBNybC.d.ts} +1 -1
  38. package/dist/{index-D-xqVzf8.d.ts → index-BJDz15ms.d.ts} +5 -5
  39. package/dist/{index-BwdGzNSn.d.cts → index-BjiVGtp8.d.cts} +5 -5
  40. package/dist/{index-DdKxfC29.d.cts → index-DRwe0UDN.d.cts} +194 -114
  41. package/dist/{index-DdKxfC29.d.ts → index-DRwe0UDN.d.ts} +194 -114
  42. package/dist/index.cjs +333 -313
  43. package/dist/index.d.cts +80 -45
  44. package/dist/index.d.ts +80 -45
  45. package/dist/index.js +4 -4
  46. package/dist/repositories/realm/index.cjs +65 -36
  47. package/dist/repositories/realm/index.cjs.map +1 -1
  48. package/dist/repositories/realm/index.d.cts +7 -3
  49. package/dist/repositories/realm/index.d.ts +7 -3
  50. package/dist/repositories/realm/index.js +35 -6
  51. package/dist/repositories/realm/index.js.map +1 -1
  52. package/dist/repositories/sqlite/index.cjs +176 -110
  53. package/dist/repositories/sqlite/index.cjs.map +1 -1
  54. package/dist/repositories/sqlite/index.d.cts +23 -13
  55. package/dist/repositories/sqlite/index.d.ts +23 -13
  56. package/dist/repositories/sqlite/index.js +148 -83
  57. package/dist/repositories/sqlite/index.js.map +1 -1
  58. package/dist/{taskRunner-ZyGGjtIq.d.ts → taskRunner-BPPU-YHG.d.cts} +4 -4
  59. package/dist/{taskRunner-67YSEpsz.d.cts → taskRunner-CDlNeth0.d.ts} +4 -4
  60. package/dist/wallet/expo/background.cjs +14 -14
  61. package/dist/wallet/expo/background.cjs.map +1 -1
  62. package/dist/wallet/expo/background.d.cts +3 -3
  63. package/dist/wallet/expo/background.d.ts +3 -3
  64. package/dist/wallet/expo/background.js +7 -7
  65. package/dist/wallet/expo/background.js.map +1 -1
  66. package/dist/wallet/expo/index.cjs +18 -15
  67. package/dist/wallet/expo/index.cjs.map +1 -1
  68. package/dist/wallet/expo/index.d.cts +7 -6
  69. package/dist/wallet/expo/index.d.ts +7 -6
  70. package/dist/wallet/expo/index.js +9 -6
  71. package/dist/wallet/expo/index.js.map +1 -1
  72. package/dist/{wallet-bFS7VybL.d.ts → wallet-Oc3Wd5gv.d.ts} +27 -19
  73. package/dist/{wallet-B8LW7cV1.d.cts → wallet-jVBDQl6R.d.cts} +27 -19
  74. package/dist/worker/expo/index.cjs +9 -9
  75. package/dist/worker/expo/index.d.cts +4 -4
  76. package/dist/worker/expo/index.d.ts +4 -4
  77. package/dist/worker/expo/index.js +5 -5
  78. package/package.json +1 -1
  79. package/dist/chunk-2OCYL6BJ.cjs.map +0 -1
  80. package/dist/chunk-2QRUQXLS.js.map +0 -1
  81. package/dist/chunk-64R7CRKN.cjs.map +0 -1
  82. package/dist/chunk-AJWXVQYG.js.map +0 -1
  83. package/dist/chunk-GGKR4O5X.cjs.map +0 -1
  84. package/dist/chunk-HKG26NUT.js.map +0 -1
  85. package/dist/chunk-MOBDJ7U2.js.map +0 -1
  86. package/dist/chunk-PVFQFQBY.cjs.map +0 -1
  87. package/dist/chunk-TAIWH3HG.cjs.map +0 -1
  88. package/dist/chunk-U5XG7SWA.js.map +0 -1
@@ -1,33 +1,70 @@
1
1
  'use strict';
2
2
 
3
- var chunk2OCYL6BJ_cjs = require('../../chunk-2OCYL6BJ.cjs');
4
- require('../../chunk-64R7CRKN.cjs');
5
- require('../../chunk-OM6FJ76H.cjs');
6
- var chunkGGKR4O5X_cjs = require('../../chunk-GGKR4O5X.cjs');
3
+ var chunkF3FAE7VJ_cjs = require('../../chunk-F3FAE7VJ.cjs');
4
+ require('../../chunk-WXNSISXK.cjs');
5
+ require('../../chunk-E6OOJEHL.cjs');
6
+ var chunkGHUUT54D_cjs = require('../../chunk-GHUUT54D.cjs');
7
7
 
8
8
  // src/repositories/sqlite/transaction.ts
9
- var writeChains = /* @__PURE__ */ new WeakMap();
9
+ var executorQueues = /* @__PURE__ */ new WeakMap();
10
+ var STALL_WARN_MS = 1e4;
11
+ function enqueue(queue, operation) {
12
+ let stall;
13
+ if (queue.inTransaction) {
14
+ const site = new Error(
15
+ `SQLite operation waited ${STALL_WARN_MS / 1e3}s behind a transaction. A repository, getSerializedExecutor or runInTransaction call inside a runInTransaction callback deadlocks; use the callback's tx.`
16
+ );
17
+ stall = setTimeout(() => console.warn(site), STALL_WARN_MS);
18
+ }
19
+ const run = queue.tail.then(() => {
20
+ clearTimeout(stall);
21
+ return operation();
22
+ });
23
+ queue.tail = run.catch(() => void 0);
24
+ return run;
25
+ }
26
+ function queueFor(db) {
27
+ const existing = executorQueues.get(db);
28
+ if (existing) return existing;
29
+ const facade = {
30
+ run: (sql, params) => enqueue(queue, () => db.run(sql, params)),
31
+ get: (sql, params) => enqueue(queue, () => db.get(sql, params)),
32
+ all: (sql, params) => enqueue(queue, () => db.all(sql, params))
33
+ };
34
+ const queue = {
35
+ raw: db,
36
+ facade,
37
+ tail: Promise.resolve(),
38
+ inTransaction: false
39
+ };
40
+ executorQueues.set(db, queue);
41
+ executorQueues.set(facade, queue);
42
+ return queue;
43
+ }
44
+ function getSerializedExecutor(db) {
45
+ return queueFor(db).facade;
46
+ }
10
47
  function runInTransaction(db, fn) {
11
- const prev = writeChains.get(db) ?? Promise.resolve();
12
- const run = prev.then(async () => {
13
- await db.run("BEGIN IMMEDIATE");
48
+ const queue = queueFor(db);
49
+ return enqueue(queue, async () => {
50
+ const tx = queue.raw;
51
+ queue.inTransaction = true;
14
52
  try {
15
- await fn();
16
- await db.run("COMMIT");
17
- } catch (e) {
53
+ await tx.run("BEGIN IMMEDIATE");
18
54
  try {
19
- await db.run("ROLLBACK");
20
- } catch {
55
+ await fn(tx);
56
+ await tx.run("COMMIT");
57
+ } catch (e) {
58
+ try {
59
+ await tx.run("ROLLBACK");
60
+ } catch {
61
+ }
62
+ throw e;
21
63
  }
22
- throw e;
64
+ } finally {
65
+ queue.inTransaction = false;
23
66
  }
24
67
  });
25
- writeChains.set(
26
- db,
27
- run.catch(() => {
28
- })
29
- );
30
- return run;
31
68
  }
32
69
 
33
70
  // src/repositories/sqlite/prefix.ts
@@ -40,8 +77,17 @@ function sanitizeTablePrefix(p) {
40
77
  // src/repositories/sqlite/walletRepository.ts
41
78
  var MAX_BOUND_PARAMETERS = 999;
42
79
  var SQLiteWalletRepository = class {
80
+ version = 2;
81
+ atomicWalletState;
82
+ db;
83
+ initPromise = null;
84
+ prefix;
85
+ tables;
43
86
  constructor(db, options) {
44
- this.db = db;
87
+ this.db = getSerializedExecutor(db);
88
+ if (options?.walletStateTransactions === true) {
89
+ this.atomicWalletState = options.persistentWalletState === true ? { ...this.atomicState, persistent: true } : this.atomicState;
90
+ }
45
91
  this.prefix = sanitizeTablePrefix(options?.prefix ?? "ark_");
46
92
  this.tables = {
47
93
  vtxos: `${this.prefix}vtxos`,
@@ -50,11 +96,6 @@ var SQLiteWalletRepository = class {
50
96
  walletState: `${this.prefix}wallet_state`
51
97
  };
52
98
  }
53
- db;
54
- version = 2;
55
- initPromise = null;
56
- prefix;
57
- tables;
58
99
  // ── Lifecycle ──────────────────────────────────────────────────────
59
100
  ensureInit() {
60
101
  if (!this.initPromise) {
@@ -157,16 +198,16 @@ var SQLiteWalletRepository = class {
157
198
  * leave the next startup seeing no `vtxos` table.
158
199
  */
159
200
  async migrateVtxosTable() {
160
- await runInTransaction(this.db, async () => {
161
- const tableExists = await this.db.get(
201
+ await runInTransaction(this.db, async (tx) => {
202
+ const tableExists = await tx.get(
162
203
  `SELECT name FROM sqlite_master WHERE type='table' AND name=?`,
163
204
  [this.tables.vtxos]
164
205
  );
165
206
  if (!tableExists) {
166
- await this.db.run(this.vtxosCreateSql(this.tables.vtxos));
207
+ await tx.run(this.vtxosCreateSql(this.tables.vtxos));
167
208
  return;
168
209
  }
169
- const cols = await this.db.all(
210
+ const cols = await tx.all(
170
211
  `PRAGMA table_info(${this.tables.vtxos})`
171
212
  );
172
213
  const scriptCol = cols.find((c) => c.name === "script");
@@ -180,33 +221,31 @@ var SQLiteWalletRepository = class {
180
221
  let addedCanonicalColumns = false;
181
222
  for (const [name, type] of nullableCanonicalColumns) {
182
223
  if (!cols.some((c) => c.name === name)) {
183
- await this.db.run(
184
- `ALTER TABLE ${this.tables.vtxos} ADD COLUMN ${name} ${type}`
185
- );
224
+ await tx.run(`ALTER TABLE ${this.tables.vtxos} ADD COLUMN ${name} ${type}`);
186
225
  addedCanonicalColumns = true;
187
226
  }
188
227
  }
189
228
  const hasLegacyBlob = cols.some((c) => c.name === "virtual_status_json");
190
229
  if (addedCanonicalColumns && hasLegacyBlob) {
191
- await this.backfillCanonicalVtxoColumns();
230
+ await this.backfillCanonicalVtxoColumns(tx);
192
231
  }
193
232
  if (scriptCol && scriptCol.notnull === 1 && !hasLegacyBlob) {
194
233
  return;
195
234
  }
196
235
  if (!scriptCol) {
197
- await this.db.run(`ALTER TABLE ${this.tables.vtxos} ADD COLUMN script TEXT`);
236
+ await tx.run(`ALTER TABLE ${this.tables.vtxos} ADD COLUMN script TEXT`);
198
237
  }
199
- const nullRows = await this.db.all(`SELECT txid, vout, address FROM ${this.tables.vtxos} WHERE script IS NULL`);
238
+ const nullRows = await tx.all(`SELECT txid, vout, address FROM ${this.tables.vtxos} WHERE script IS NULL`);
200
239
  for (const row of nullRows) {
201
- await this.db.run(
240
+ await tx.run(
202
241
  `UPDATE ${this.tables.vtxos} SET script = ? WHERE txid = ? AND vout = ?`,
203
- [chunk2OCYL6BJ_cjs.scriptFromArkAddress(row.address), row.txid, row.vout]
242
+ [chunkF3FAE7VJ_cjs.scriptFromArkAddress(row.address), row.txid, row.vout]
204
243
  );
205
244
  }
206
245
  const tempName = `${this.tables.vtxos}__migrate_tmp`;
207
- await this.db.run(`DROP TABLE IF EXISTS ${tempName}`);
208
- await this.db.run(this.vtxosCreateSql(tempName));
209
- await this.db.run(`
246
+ await tx.run(`DROP TABLE IF EXISTS ${tempName}`);
247
+ await tx.run(this.vtxosCreateSql(tempName));
248
+ await tx.run(`
210
249
  INSERT INTO ${tempName}
211
250
  (txid, vout, value, address, tap_tree,
212
251
  forfeit_cb, forfeit_s, intent_cb, intent_s,
@@ -222,8 +261,8 @@ var SQLiteWalletRepository = class {
222
261
  spent_by, settled_by, ark_tx_id, extra_witness_json, assets_json, script
223
262
  FROM ${this.tables.vtxos}
224
263
  `);
225
- await this.db.run(`DROP TABLE ${this.tables.vtxos}`);
226
- await this.db.run(`ALTER TABLE ${tempName} RENAME TO ${this.tables.vtxos}`);
264
+ await tx.run(`DROP TABLE ${this.tables.vtxos}`);
265
+ await tx.run(`ALTER TABLE ${tempName} RENAME TO ${this.tables.vtxos}`);
227
266
  });
228
267
  }
229
268
  /**
@@ -235,15 +274,15 @@ var SQLiteWalletRepository = class {
235
274
  * is missing or corrupt are left alone: a migration must not be stopped by one bad row, and
236
275
  * the next sync repairs it.
237
276
  */
238
- async backfillCanonicalVtxoColumns() {
239
- const rows = await this.db.all(
277
+ async backfillCanonicalVtxoColumns(tx) {
278
+ const rows = await tx.all(
240
279
  `SELECT txid, vout, virtual_status_json FROM ${this.tables.vtxos}
241
280
  WHERE virtual_status_json IS NOT NULL AND is_swept IS NULL`
242
281
  );
243
282
  for (const row of rows) {
244
- const facts = chunk2OCYL6BJ_cjs.legacyVtxoFacts(row.virtual_status_json);
283
+ const facts = chunkF3FAE7VJ_cjs.legacyVtxoFacts(row.virtual_status_json);
245
284
  if (!facts) continue;
246
- await this.db.run(
285
+ await tx.run(
247
286
  `UPDATE ${this.tables.vtxos}
248
287
  SET is_swept = ?, is_preconfirmed = ?, commitment_txids_json = ?,
249
288
  expires_at = ?, expires_at_height = ?,
@@ -333,7 +372,7 @@ var SQLiteWalletRepository = class {
333
372
  expires_at, expires_at_height,
334
373
  spent_by, settled_by, ark_tx_id, extra_witness_json, assets_json, script`,
335
374
  vtxos.map((vtxo) => {
336
- const s = chunk2OCYL6BJ_cjs.serializeVtxo(vtxo);
375
+ const s = chunkF3FAE7VJ_cjs.serializeVtxo(vtxo);
337
376
  return [
338
377
  s.txid,
339
378
  s.vout,
@@ -345,7 +384,7 @@ var SQLiteWalletRepository = class {
345
384
  s.intentTapLeafScript.cb,
346
385
  s.intentTapLeafScript.s,
347
386
  JSON.stringify(s.status),
348
- chunk2OCYL6BJ_cjs.createdAtToIso(s.createdAt),
387
+ chunkF3FAE7VJ_cjs.createdAtToIso(s.createdAt),
349
388
  s.isUnrolled ? 1 : 0,
350
389
  s.isSpent === void 0 ? null : s.isSpent ? 1 : 0,
351
390
  s.isSwept === void 0 ? null : s.isSwept ? 1 : 0,
@@ -368,7 +407,7 @@ var SQLiteWalletRepository = class {
368
407
  await this.db.run(`DELETE FROM ${this.tables.vtxos} WHERE address = ?`, [address]);
369
408
  }
370
409
  async getVtxosForScriptPage(script, page, options) {
371
- chunk2OCYL6BJ_cjs.assertPageRequest(page);
410
+ chunkF3FAE7VJ_cjs.assertPageRequest(page);
372
411
  await this.ensureInit();
373
412
  const after = page.after;
374
413
  const rows = await this.db.all(
@@ -386,15 +425,15 @@ var SQLiteWalletRepository = class {
386
425
  page.limit + 1
387
426
  ] : [script, page.limit + 1]
388
427
  );
389
- const result = chunk2OCYL6BJ_cjs.pageResult(
428
+ const result = chunkF3FAE7VJ_cjs.pageResult(
390
429
  rows.map((row) => ({ address: row.address, vtxo: vtxoRowToDomain(row) })),
391
430
  page.limit,
392
431
  (row) => ({ address: row.address, txid: row.vtxo.txid, vout: row.vtxo.vout })
393
432
  );
394
- return options?.unspentOnly ? { ...result, items: result.items.filter((row) => !chunkGGKR4O5X_cjs.isVtxoSpent(row.vtxo)) } : result;
433
+ return options?.unspentOnly ? { ...result, items: result.items.filter((row) => !chunkGHUUT54D_cjs.isVtxoSpent(row.vtxo)) } : result;
395
434
  }
396
435
  async saveVtxosForScript(key, vtxos) {
397
- return this.saveVtxos(chunk2OCYL6BJ_cjs.checkSaveVtxosForScript("SQLiteWalletRepository", key, vtxos), vtxos);
436
+ return this.saveVtxos(chunkF3FAE7VJ_cjs.checkSaveVtxosForScript("SQLiteWalletRepository", key, vtxos), vtxos);
398
437
  }
399
438
  async deleteVtxosForScript(script) {
400
439
  await this.ensureInit();
@@ -405,21 +444,21 @@ var SQLiteWalletRepository = class {
405
444
  return this.pageByAddress(this.tables.utxos, address, page, utxoRowToDomain);
406
445
  }
407
446
  async pageByAddress(table, address, page, deserialize) {
408
- chunk2OCYL6BJ_cjs.assertPageRequest(page);
447
+ chunkF3FAE7VJ_cjs.assertPageRequest(page);
409
448
  await this.ensureInit();
410
449
  const rows = await this.db.all(
411
450
  `SELECT * FROM ${table} WHERE address = ? AND (txid, vout) > (?, ?)
412
451
  ORDER BY txid, vout LIMIT ?`,
413
452
  [address, page.after?.txid ?? "", page.after?.vout ?? -1, page.limit + 1]
414
453
  );
415
- const result = chunk2OCYL6BJ_cjs.pageResult(rows, page.limit, ({ txid, vout }) => ({ txid, vout }));
454
+ const result = chunkF3FAE7VJ_cjs.pageResult(rows, page.limit, ({ txid, vout }) => ({ txid, vout }));
416
455
  return { items: result.items.map(deserialize), nextCursor: result.nextCursor };
417
456
  }
418
457
  async saveUtxos(addressOrBatch, utxos) {
419
458
  await this.ensureInit();
420
- const rows = chunk2OCYL6BJ_cjs.utxoEntries(addressOrBatch, utxos).flatMap(
459
+ const rows = chunkF3FAE7VJ_cjs.utxoEntries(addressOrBatch, utxos).flatMap(
421
460
  ([address, list]) => list.map((utxo) => {
422
- const s = chunk2OCYL6BJ_cjs.serializeUtxo(utxo);
461
+ const s = chunkF3FAE7VJ_cjs.serializeUtxo(utxo);
423
462
  return [
424
463
  s.txid,
425
464
  s.vout,
@@ -449,8 +488,8 @@ var SQLiteWalletRepository = class {
449
488
  }
450
489
  // ── Transaction history ────────────────────────────────────────────
451
490
  async getTransactionHistoryPage(filter, page) {
452
- chunk2OCYL6BJ_cjs.assertPageRequest(page);
453
- chunk2OCYL6BJ_cjs.assertHistoryPageFilter(filter);
491
+ chunkF3FAE7VJ_cjs.assertPageRequest(page);
492
+ chunkF3FAE7VJ_cjs.assertHistoryPageFilter(filter);
454
493
  await this.ensureInit();
455
494
  const conditions = ["address = ?"];
456
495
  const params = [filter.address];
@@ -474,7 +513,7 @@ var SQLiteWalletRepository = class {
474
513
  ORDER BY created_at, boarding_txid, commitment_txid, ark_txid LIMIT ?`,
475
514
  [...params, page.limit + 1]
476
515
  );
477
- return chunk2OCYL6BJ_cjs.pageResult(rows.map(txRowToDomain), page.limit, (tx) => ({
516
+ return chunkF3FAE7VJ_cjs.pageResult(rows.map(txRowToDomain), page.limit, (tx) => ({
478
517
  createdAt: tx.createdAt,
479
518
  key: tx.key
480
519
  }));
@@ -494,7 +533,7 @@ var SQLiteWalletRepository = class {
494
533
  tx.amount,
495
534
  tx.settled ? 1 : 0,
496
535
  tx.createdAt,
497
- tx.assets ? JSON.stringify(chunk2OCYL6BJ_cjs.serializeAssets(tx.assets)) : null
536
+ tx.assets ? JSON.stringify(chunkF3FAE7VJ_cjs.serializeAssets(tx.assets)) : null
498
537
  ])
499
538
  );
500
539
  }
@@ -503,6 +542,32 @@ var SQLiteWalletRepository = class {
503
542
  await this.db.run(`DELETE FROM ${this.tables.transactions} WHERE address = ?`, [address]);
504
543
  }
505
544
  // ── Wallet state ───────────────────────────────────────────────────
545
+ atomicState = {
546
+ version: 1,
547
+ update: async (updater) => {
548
+ await this.ensureInit();
549
+ await runInTransaction(this.db, async (tx) => {
550
+ const row = await tx.get(
551
+ `SELECT * FROM ${this.tables.walletState} WHERE key = ?`,
552
+ ["state"]
553
+ );
554
+ const current = row ? {
555
+ settings: row.settings_json ? JSON.parse(row.settings_json) : void 0,
556
+ lastSyncTime: row.last_sync_time ?? void 0
557
+ } : {};
558
+ const state = chunkF3FAE7VJ_cjs.applyWalletStateUpdate(current, updater);
559
+ await tx.run(
560
+ `INSERT OR REPLACE INTO ${this.tables.walletState}
561
+ (key, settings_json, last_sync_time) VALUES (?, ?, ?)`,
562
+ [
563
+ "state",
564
+ state.settings ? JSON.stringify(state.settings) : null,
565
+ state.lastSyncTime ?? null
566
+ ]
567
+ );
568
+ });
569
+ }
570
+ };
506
571
  async getWalletState() {
507
572
  await this.ensureInit();
508
573
  const row = await this.db.get(
@@ -563,9 +628,9 @@ function vtxoRowToDomain(row) {
563
628
  // Post-migration every row has `script`, but the backfill is
564
629
  // idempotent: derive from `address` if the legacy column is still
565
630
  // null (e.g. the migration hasn't run yet on this handle).
566
- script: row.script ?? chunk2OCYL6BJ_cjs.scriptFromArkAddress(row.address)
631
+ script: row.script ?? chunkF3FAE7VJ_cjs.scriptFromArkAddress(row.address)
567
632
  };
568
- return chunk2OCYL6BJ_cjs.deserializeVtxo(serialized);
633
+ return chunkF3FAE7VJ_cjs.deserializeVtxo(serialized);
569
634
  }
570
635
  function utxoRowToDomain(row) {
571
636
  const serialized = {
@@ -584,7 +649,7 @@ function utxoRowToDomain(row) {
584
649
  status: JSON.parse(row.status_json),
585
650
  extraWitness: row.extra_witness_json ? JSON.parse(row.extra_witness_json) : void 0
586
651
  };
587
- return chunk2OCYL6BJ_cjs.deserializeUtxo(serialized);
652
+ return chunkF3FAE7VJ_cjs.deserializeUtxo(serialized);
588
653
  }
589
654
  function txRowToDomain(row) {
590
655
  const tx = {
@@ -599,7 +664,7 @@ function txRowToDomain(row) {
599
664
  createdAt: row.created_at
600
665
  };
601
666
  if (row.assets_json) {
602
- tx.assets = chunk2OCYL6BJ_cjs.deserializeAssets(JSON.parse(row.assets_json));
667
+ tx.assets = chunkF3FAE7VJ_cjs.deserializeAssets(JSON.parse(row.assets_json));
603
668
  }
604
669
  return tx;
605
670
  }
@@ -607,16 +672,16 @@ function txRowToDomain(row) {
607
672
  // src/repositories/sqlite/contractRepository.ts
608
673
  var WATCH_STATE = "IFNULL(watch, 'watched')";
609
674
  var SQLiteContractRepository = class {
610
- constructor(db, options) {
611
- this.db = db;
612
- this.prefix = sanitizeTablePrefix(options?.prefix ?? "ark_");
613
- this.table = `${this.prefix}contracts`;
614
- }
615
- db;
616
675
  version = 3;
676
+ db;
617
677
  initPromise = null;
618
678
  prefix;
619
679
  table;
680
+ constructor(db, options) {
681
+ this.db = getSerializedExecutor(db);
682
+ this.prefix = sanitizeTablePrefix(options?.prefix ?? "ark_");
683
+ this.table = `${this.prefix}contracts`;
684
+ }
620
685
  // ── Lifecycle ──────────────────────────────────────────────────────
621
686
  ensureInit() {
622
687
  if (!this.initPromise) {
@@ -667,9 +732,9 @@ var SQLiteContractRepository = class {
667
732
  }
668
733
  // ── Contract management ────────────────────────────────────────────
669
734
  async getContractsPage(filter, page) {
670
- chunk2OCYL6BJ_cjs.assertPageRequest(page);
735
+ chunkF3FAE7VJ_cjs.assertPageRequest(page);
671
736
  await this.ensureInit();
672
- if (chunk2OCYL6BJ_cjs.contractFilterMatchesNothing(filter)) return { items: [] };
737
+ if (chunkF3FAE7VJ_cjs.contractFilterMatchesNothing(filter)) return { items: [] };
673
738
  const conditions = [];
674
739
  const params = [];
675
740
  if (filter) {
@@ -687,7 +752,7 @@ var SQLiteContractRepository = class {
687
752
  `SELECT * FROM ${this.table}${where} ORDER BY script LIMIT ?`,
688
753
  [...params, page.limit + 1]
689
754
  );
690
- return chunk2OCYL6BJ_cjs.pageResult(rows.map(contractRowToDomain), page.limit, (contract) => contract.script);
755
+ return chunkF3FAE7VJ_cjs.pageResult(rows.map(contractRowToDomain), page.limit, (contract) => contract.script);
691
756
  }
692
757
  async saveContract(contract) {
693
758
  await this.ensureInit();
@@ -751,16 +816,16 @@ function contractRowToDomain(row) {
751
816
 
752
817
  // src/repositories/sqlite/intentRepository.ts
753
818
  var SQLiteIntentRepository = class {
754
- constructor(db, options) {
755
- this.db = db;
756
- this.prefix = sanitizeTablePrefix(options?.prefix ?? "ark_");
757
- this.t = `${this.prefix}intents`;
758
- }
759
- db;
760
819
  version = 1;
820
+ db;
761
821
  initPromise = null;
762
822
  prefix;
763
823
  t;
824
+ constructor(db, options) {
825
+ this.db = getSerializedExecutor(db);
826
+ this.prefix = sanitizeTablePrefix(options?.prefix ?? "ark_");
827
+ this.t = `${this.prefix}intents`;
828
+ }
764
829
  ensureInit() {
765
830
  if (!this.initPromise) this.initPromise = this.init();
766
831
  return this.initPromise;
@@ -794,15 +859,15 @@ var SQLiteIntentRepository = class {
794
859
  }
795
860
  async clear() {
796
861
  await this.ensureInit();
797
- await runInTransaction(this.db, async () => {
798
- await this.db.run(`DELETE FROM ${this.t}`);
862
+ await runInTransaction(this.db, async (tx) => {
863
+ await tx.run(`DELETE FROM ${this.t}`);
799
864
  });
800
865
  }
801
866
  async saveIntent(intent) {
802
867
  await this.ensureInit();
803
868
  const now = Date.now();
804
- await runInTransaction(this.db, async () => {
805
- await this.db.run(
869
+ await runInTransaction(this.db, async (tx) => {
870
+ await tx.run(
806
871
  `INSERT INTO ${this.t}
807
872
  (intent_tx_id, intent_id, state, valid_from, valid_until,
808
873
  created_at, updated_at, register_proof, register_proof_message,
@@ -850,7 +915,7 @@ var SQLiteIntentRepository = class {
850
915
  });
851
916
  }
852
917
  async getIntentsPage(filter, page) {
853
- chunk2OCYL6BJ_cjs.assertPageRequest(page);
918
+ chunkF3FAE7VJ_cjs.assertPageRequest(page);
854
919
  await this.ensureInit();
855
920
  if (filter?.states?.length === 0) return { items: [] };
856
921
  const stateSql = filter?.states ? ` AND state IN (${filter.states.map(() => "?").join(", ")})` : "";
@@ -867,19 +932,19 @@ var SQLiteIntentRepository = class {
867
932
  for (const row of batch) {
868
933
  after = row.intent_tx_id;
869
934
  const intent = rowToIntent(row);
870
- if (!filter || chunk2OCYL6BJ_cjs.intentMatchesFilter(intent, filter)) rows.push(intent);
935
+ if (!filter || chunkF3FAE7VJ_cjs.intentMatchesFilter(intent, filter)) rows.push(intent);
871
936
  if (rows.length > page.limit) break;
872
937
  }
873
938
  if (batch.length < batchSize) break;
874
939
  }
875
- return chunk2OCYL6BJ_cjs.pageResult(rows, page.limit, (intent) => intent.intentTxId);
940
+ return chunkF3FAE7VJ_cjs.pageResult(rows, page.limit, (intent) => intent.intentTxId);
876
941
  }
877
942
  async getLockedVtxoOutpoints() {
878
943
  await this.ensureInit();
879
944
  const rows = await this.db.all(`SELECT * FROM ${this.t}`);
880
945
  const out = [];
881
946
  for (const r of rows) {
882
- if (chunk2OCYL6BJ_cjs.isTerminalIntentState(r.state)) continue;
947
+ if (chunkF3FAE7VJ_cjs.isTerminalIntentState(r.state)) continue;
883
948
  for (const o of JSON.parse(r.intent_vtxos_json)) out.push(o);
884
949
  }
885
950
  return out;
@@ -911,18 +976,18 @@ function rowToIntent(r) {
911
976
 
912
977
  // src/repositories/sqlite/virtualTxRepository.ts
913
978
  var SQLiteVirtualTxRepository = class {
914
- constructor(db, options) {
915
- this.db = db;
916
- this.prefix = sanitizeTablePrefix(options?.prefix ?? "ark_");
917
- this.tTx = `${this.prefix}virtual_txs`;
918
- this.tBranch = `${this.prefix}vtxo_branches`;
919
- }
920
- db;
921
979
  version = 1;
980
+ db;
922
981
  initPromise = null;
923
982
  prefix;
924
983
  tTx;
925
984
  tBranch;
985
+ constructor(db, options) {
986
+ this.db = getSerializedExecutor(db);
987
+ this.prefix = sanitizeTablePrefix(options?.prefix ?? "ark_");
988
+ this.tTx = `${this.prefix}virtual_txs`;
989
+ this.tBranch = `${this.prefix}vtxo_branches`;
990
+ }
926
991
  ensureInit() {
927
992
  if (!this.initPromise) this.initPromise = this.init();
928
993
  return this.initPromise;
@@ -947,17 +1012,17 @@ var SQLiteVirtualTxRepository = class {
947
1012
  }
948
1013
  async clear() {
949
1014
  await this.ensureInit();
950
- await runInTransaction(this.db, async () => {
951
- await this.db.run(`DELETE FROM ${this.tTx}`);
952
- await this.db.run(`DELETE FROM ${this.tBranch}`);
1015
+ await runInTransaction(this.db, async (tx) => {
1016
+ await tx.run(`DELETE FROM ${this.tTx}`);
1017
+ await tx.run(`DELETE FROM ${this.tBranch}`);
953
1018
  });
954
1019
  }
955
1020
  async upsertVirtualTxs(txs) {
956
1021
  if (txs.length === 0) return;
957
1022
  await this.ensureInit();
958
- await runInTransaction(this.db, async () => {
1023
+ await runInTransaction(this.db, async (tx) => {
959
1024
  const placeholders = txs.map(() => "?").join(", ");
960
- const existing = await this.db.all(
1025
+ const existing = await tx.all(
961
1026
  `SELECT * FROM ${this.tTx} WHERE txid IN (${placeholders})`,
962
1027
  txs.map((t) => t.txid)
963
1028
  );
@@ -966,8 +1031,8 @@ var SQLiteVirtualTxRepository = class {
966
1031
  const prev = prevByTxid.get(t.txid);
967
1032
  const psbt = t.psbt ?? prev?.psbt ?? null;
968
1033
  const expires = t.expiresAt ?? prev?.expires_at ?? null;
969
- const type = chunk2OCYL6BJ_cjs.mergeChainedTxType(t.type, prev?.type);
970
- await this.db.run(
1034
+ const type = chunkF3FAE7VJ_cjs.mergeChainedTxType(t.type, prev?.type);
1035
+ await tx.run(
971
1036
  `INSERT OR REPLACE INTO ${this.tTx} (txid, psbt, expires_at, type) VALUES (?, ?, ?, ?)`,
972
1037
  [t.txid, psbt, expires, type]
973
1038
  );
@@ -982,13 +1047,13 @@ var SQLiteVirtualTxRepository = class {
982
1047
  }
983
1048
  async setBranch(vtxo, branch) {
984
1049
  await this.ensureInit();
985
- await runInTransaction(this.db, async () => {
986
- await this.db.run(`DELETE FROM ${this.tBranch} WHERE vtxo_txid = ? AND vtxo_vout = ?`, [
1050
+ await runInTransaction(this.db, async (tx) => {
1051
+ await tx.run(`DELETE FROM ${this.tBranch} WHERE vtxo_txid = ? AND vtxo_vout = ?`, [
987
1052
  vtxo.txid,
988
1053
  vtxo.vout
989
1054
  ]);
990
1055
  for (const b of branch) {
991
- await this.db.run(
1056
+ await tx.run(
992
1057
  `INSERT OR REPLACE INTO ${this.tBranch} (vtxo_txid, vtxo_vout, virtual_txid, position) VALUES (?, ?, ?, ?)`,
993
1058
  [b.vtxoTxid, b.vtxoVout, b.virtualTxid, b.position]
994
1059
  );
@@ -1017,18 +1082,18 @@ var SQLiteVirtualTxRepository = class {
1017
1082
  }
1018
1083
  async pruneForSpentVtxo(vtxo) {
1019
1084
  await this.ensureInit();
1020
- await runInTransaction(this.db, async () => {
1021
- const removed = await this.db.all(
1085
+ await runInTransaction(this.db, async (tx) => {
1086
+ const removed = await tx.all(
1022
1087
  `SELECT DISTINCT virtual_txid FROM ${this.tBranch} WHERE vtxo_txid = ? AND vtxo_vout = ?`,
1023
1088
  [vtxo.txid, vtxo.vout]
1024
1089
  );
1025
- await this.db.run(`DELETE FROM ${this.tBranch} WHERE vtxo_txid = ? AND vtxo_vout = ?`, [
1090
+ await tx.run(`DELETE FROM ${this.tBranch} WHERE vtxo_txid = ? AND vtxo_vout = ?`, [
1026
1091
  vtxo.txid,
1027
1092
  vtxo.vout
1028
1093
  ]);
1029
1094
  if (removed.length === 0) return;
1030
1095
  const placeholders = removed.map(() => "?").join(", ");
1031
- await this.db.run(
1096
+ await tx.run(
1032
1097
  `DELETE FROM ${this.tTx}
1033
1098
  WHERE txid IN (${placeholders})
1034
1099
  AND NOT EXISTS (
@@ -1052,12 +1117,13 @@ function rowToTx(r) {
1052
1117
 
1053
1118
  Object.defineProperty(exports, "ChainedTxType", {
1054
1119
  enumerable: true,
1055
- get: function () { return chunk2OCYL6BJ_cjs.ChainedTxType; }
1120
+ get: function () { return chunkF3FAE7VJ_cjs.ChainedTxType; }
1056
1121
  });
1057
1122
  exports.SQLiteContractRepository = SQLiteContractRepository;
1058
1123
  exports.SQLiteIntentRepository = SQLiteIntentRepository;
1059
1124
  exports.SQLiteVirtualTxRepository = SQLiteVirtualTxRepository;
1060
1125
  exports.SQLiteWalletRepository = SQLiteWalletRepository;
1126
+ exports.getSerializedExecutor = getSerializedExecutor;
1061
1127
  exports.runInTransaction = runInTransaction;
1062
1128
  exports.sanitizeTablePrefix = sanitizeTablePrefix;
1063
1129
  //# sourceMappingURL=index.cjs.map