@arkade-os/sdk 0.5.0-rc.11 → 0.5.0-rc.13
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 +43 -12
- package/dist/adapters/expo.cjs +5 -5
- package/dist/adapters/expo.d.cts +2 -2
- package/dist/adapters/expo.d.ts +2 -2
- package/dist/adapters/expo.js +3 -3
- package/dist/{asyncStorageTaskQueue-DBaZsltv.d.cts → asyncStorageTaskQueue-0EeSeCAt.d.cts} +1 -1
- package/dist/{asyncStorageTaskQueue-uAG3XLyg.d.ts → asyncStorageTaskQueue-DV94jhwq.d.ts} +1 -1
- package/dist/{chunk-WSQAWSEH.js → chunk-3JLYJ5KZ.js} +75 -237
- package/dist/chunk-3JLYJ5KZ.js.map +1 -0
- package/dist/{chunk-VMLLYEYM.js → chunk-4EU2Q6YT.js} +12 -14
- package/dist/chunk-4EU2Q6YT.js.map +1 -0
- package/dist/{chunk-IA32YGLH.cjs → chunk-7BACS4XK.cjs} +10 -10
- package/dist/chunk-7BACS4XK.cjs.map +1 -0
- package/dist/{chunk-5OBGYL6U.cjs → chunk-7NK6XFC3.cjs} +120 -194
- package/dist/chunk-7NK6XFC3.cjs.map +1 -0
- package/dist/{chunk-CQPQ7D4U.cjs → chunk-BFQX2KS3.cjs} +87 -248
- package/dist/chunk-BFQX2KS3.cjs.map +1 -0
- package/dist/{chunk-DD6MTNAS.js → chunk-D7JLTHSZ.js} +5 -5
- package/dist/chunk-D7JLTHSZ.js.map +1 -0
- package/dist/{chunk-CMLSTGOC.js → chunk-EJYWGTZ7.js} +119 -194
- package/dist/chunk-EJYWGTZ7.js.map +1 -0
- package/dist/{chunk-T2ILYGWE.cjs → chunk-FDQQOF3F.cjs} +327 -1080
- package/dist/chunk-FDQQOF3F.cjs.map +1 -0
- package/dist/{chunk-MGDXN74N.cjs → chunk-I4YBVHAK.cjs} +2357 -3374
- package/dist/chunk-I4YBVHAK.cjs.map +1 -0
- package/dist/{chunk-M2ZUPLKQ.js → chunk-IV2252XM.js} +1946 -2977
- package/dist/chunk-IV2252XM.js.map +1 -0
- package/dist/{chunk-OMJRW2D5.js → chunk-JOUPIZ32.js} +263 -1036
- package/dist/chunk-JOUPIZ32.js.map +1 -0
- package/dist/{chunk-PWEBQNIE.cjs → chunk-RDQSVIXD.cjs} +22 -24
- package/dist/chunk-RDQSVIXD.cjs.map +1 -0
- package/dist/contracts/handlers/index.cjs +9 -9
- package/dist/contracts/handlers/index.d.cts +3 -3
- package/dist/contracts/handlers/index.d.ts +3 -3
- package/dist/contracts/handlers/index.js +2 -2
- package/dist/{delegate-DFwlkVYR.d.cts → delegate-BgpUJW5B.d.cts} +1 -1
- package/dist/{delegate-D3YHDERL.d.ts → delegate-BuagcGnG.d.ts} +1 -1
- package/dist/{index-DTvUv5lD.d.cts → index-CKmB14Yu.d.cts} +1145 -2263
- package/dist/{index-DTvUv5lD.d.ts → index-CKmB14Yu.d.ts} +1145 -2263
- package/dist/index-D0BuYwhF.d.cts +637 -0
- package/dist/index-DbzyrqK7.d.ts +637 -0
- package/dist/index.cjs +341 -297
- package/dist/index.d.cts +379 -788
- package/dist/index.d.ts +379 -788
- package/dist/index.js +4 -4
- package/dist/repositories/realm/index.cjs +142 -101
- package/dist/repositories/realm/index.cjs.map +1 -1
- package/dist/repositories/realm/index.d.cts +13 -11
- package/dist/repositories/realm/index.d.ts +13 -11
- package/dist/repositories/realm/index.js +130 -89
- package/dist/repositories/realm/index.js.map +1 -1
- package/dist/repositories/sqlite/index.cjs +158 -118
- package/dist/repositories/sqlite/index.cjs.map +1 -1
- package/dist/repositories/sqlite/index.d.cts +14 -13
- package/dist/repositories/sqlite/index.d.ts +14 -13
- package/dist/repositories/sqlite/index.js +147 -107
- package/dist/repositories/sqlite/index.js.map +1 -1
- package/dist/{taskRunner-B5bl0YRt.d.ts → taskRunner-BX-pB0sv.d.ts} +1 -1
- package/dist/{taskRunner--sKy9Inv.d.cts → taskRunner-DJrFFyus.d.cts} +1 -1
- package/dist/wallet/expo/background.cjs +14 -14
- package/dist/wallet/expo/background.cjs.map +1 -1
- package/dist/wallet/expo/background.d.cts +8 -14
- package/dist/wallet/expo/background.d.ts +8 -14
- package/dist/wallet/expo/background.js +6 -6
- package/dist/wallet/expo/background.js.map +1 -1
- package/dist/wallet/expo/index.cjs +14 -14
- package/dist/wallet/expo/index.cjs.map +1 -1
- package/dist/wallet/expo/index.d.cts +5 -5
- package/dist/wallet/expo/index.d.ts +5 -5
- package/dist/wallet/expo/index.js +5 -5
- package/dist/wallet/expo/index.js.map +1 -1
- package/dist/wallet-BsL2G3Qb.d.cts +1542 -0
- package/dist/wallet-DXNiCmq8.d.ts +1542 -0
- package/dist/worker/expo/index.cjs +9 -9
- package/dist/worker/expo/index.d.cts +4 -4
- package/dist/worker/expo/index.d.ts +4 -4
- package/dist/worker/expo/index.js +5 -5
- package/package.json +3 -2
- package/dist/chunk-5OBGYL6U.cjs.map +0 -1
- package/dist/chunk-CMLSTGOC.js.map +0 -1
- package/dist/chunk-CQPQ7D4U.cjs.map +0 -1
- package/dist/chunk-DD6MTNAS.js.map +0 -1
- package/dist/chunk-IA32YGLH.cjs.map +0 -1
- package/dist/chunk-M2ZUPLKQ.js.map +0 -1
- package/dist/chunk-MGDXN74N.cjs.map +0 -1
- package/dist/chunk-OMJRW2D5.js.map +0 -1
- package/dist/chunk-PWEBQNIE.cjs.map +0 -1
- package/dist/chunk-T2ILYGWE.cjs.map +0 -1
- package/dist/chunk-VMLLYEYM.js.map +0 -1
- package/dist/chunk-WSQAWSEH.js.map +0 -1
- package/dist/hdWalletCapable-C350s3bP.d.ts +0 -2206
- package/dist/hdWalletCapable-rrOmXcbT.d.cts +0 -2206
- package/dist/index-C0ZyGoyP.d.cts +0 -850
- package/dist/index-DASN1cVk.d.ts +0 -850
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { scriptFromArkAddress, legacyVtxoFacts, serializeVtxo,
|
|
2
|
-
export { ChainedTxType } from '../../chunk-
|
|
3
|
-
import '../../chunk-
|
|
4
|
-
import '../../chunk-
|
|
5
|
-
import '../../chunk-
|
|
1
|
+
import { scriptFromArkAddress, legacyVtxoFacts, serializeVtxo, createdAtToIso, assertPageRequest, pageResult, checkSaveVtxosForScript, serializeUtxo, assertHistoryPageFilter, serializeAssets, deserializeVtxo, deserializeUtxo, deserializeAssets, contractFilterMatchesNothing, intentMatchesFilter, isTerminalIntentState, mergeChainedTxType } from '../../chunk-IV2252XM.js';
|
|
2
|
+
export { ChainedTxType } from '../../chunk-IV2252XM.js';
|
|
3
|
+
import '../../chunk-3JLYJ5KZ.js';
|
|
4
|
+
import '../../chunk-JOUPIZ32.js';
|
|
5
|
+
import { isVtxoSpent } from '../../chunk-EJYWGTZ7.js';
|
|
6
6
|
|
|
7
7
|
// src/repositories/sqlite/transaction.ts
|
|
8
8
|
var writeChains = /* @__PURE__ */ new WeakMap();
|
|
@@ -29,11 +29,18 @@ function runInTransaction(db, fn) {
|
|
|
29
29
|
return run;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
// src/repositories/sqlite/prefix.ts
|
|
33
|
+
var SAFE_PREFIX = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
|
|
34
|
+
function sanitizeTablePrefix(p) {
|
|
35
|
+
if (!SAFE_PREFIX.test(p)) throw new Error(`Invalid table prefix "${p}"`);
|
|
36
|
+
return p;
|
|
37
|
+
}
|
|
38
|
+
|
|
32
39
|
// src/repositories/sqlite/walletRepository.ts
|
|
33
40
|
var SQLiteWalletRepository = class {
|
|
34
41
|
constructor(db, options) {
|
|
35
42
|
this.db = db;
|
|
36
|
-
this.prefix =
|
|
43
|
+
this.prefix = sanitizeTablePrefix(options?.prefix ?? "ark_");
|
|
37
44
|
this.tables = {
|
|
38
45
|
vtxos: `${this.prefix}vtxos`,
|
|
39
46
|
utxos: `${this.prefix}utxos`,
|
|
@@ -42,7 +49,7 @@ var SQLiteWalletRepository = class {
|
|
|
42
49
|
};
|
|
43
50
|
}
|
|
44
51
|
db;
|
|
45
|
-
version =
|
|
52
|
+
version = 2;
|
|
46
53
|
initPromise = null;
|
|
47
54
|
prefix;
|
|
48
55
|
tables;
|
|
@@ -98,23 +105,42 @@ var SQLiteWalletRepository = class {
|
|
|
98
105
|
await this.db.run(
|
|
99
106
|
`CREATE INDEX IF NOT EXISTS idx_${this.prefix}vtxos_script ON ${this.tables.vtxos} (script)`
|
|
100
107
|
);
|
|
108
|
+
await this.db.run(
|
|
109
|
+
`CREATE INDEX IF NOT EXISTS idx_${this.prefix}vtxos_script_page ON ${this.tables.vtxos} (script, address, txid, vout)`
|
|
110
|
+
);
|
|
111
|
+
await this.db.run(
|
|
112
|
+
`CREATE INDEX IF NOT EXISTS idx_${this.prefix}vtxos_address_page ON ${this.tables.vtxos} (address, txid, vout)`
|
|
113
|
+
);
|
|
114
|
+
await this.db.run(`DROP INDEX IF EXISTS idx_${this.prefix}vtxos_live_script`);
|
|
115
|
+
await this.db.run(
|
|
116
|
+
`CREATE INDEX IF NOT EXISTS idx_${this.prefix}vtxos_live_script_page ON ${this.tables.vtxos} (script, address, txid, vout)
|
|
117
|
+
WHERE ${UNSPENT_VTXO_PREDICATE}`
|
|
118
|
+
);
|
|
101
119
|
await this.db.run(
|
|
102
120
|
`CREATE INDEX IF NOT EXISTS idx_${this.prefix}utxos_address ON ${this.tables.utxos} (address)`
|
|
103
121
|
);
|
|
122
|
+
await this.db.run(
|
|
123
|
+
`CREATE INDEX IF NOT EXISTS idx_${this.prefix}utxos_address_page ON ${this.tables.utxos} (address, txid, vout)`
|
|
124
|
+
);
|
|
104
125
|
await this.db.run(
|
|
105
126
|
`CREATE INDEX IF NOT EXISTS idx_${this.prefix}transactions_address ON ${this.tables.transactions} (address)`
|
|
106
127
|
);
|
|
128
|
+
await this.db.run(
|
|
129
|
+
`CREATE INDEX IF NOT EXISTS idx_${this.prefix}transactions_history ON ${this.tables.transactions} (address, created_at, boarding_txid, commitment_txid, ark_txid)`
|
|
130
|
+
);
|
|
107
131
|
}
|
|
108
132
|
/**
|
|
109
133
|
* Bring the `vtxos` table to the current schema (v1 = `script` NOT NULL).
|
|
110
134
|
*
|
|
111
|
-
*
|
|
135
|
+
* Four cases:
|
|
112
136
|
* - Fresh install: create the v1 schema directly.
|
|
113
137
|
* - Legacy install without a `script` column: add it, backfill from
|
|
114
138
|
* `address`, then rebuild the table with NOT NULL (SQLite cannot add
|
|
115
139
|
* the NOT NULL constraint in place).
|
|
116
140
|
* - Legacy install with a nullable `script` column: backfill the NULLs
|
|
117
141
|
* and rebuild.
|
|
142
|
+
* - 0.4.x install: `script` is already NOT NULL but `virtual_status_json
|
|
143
|
+
* NOT NULL` is still there, and `saveVtxos` no longer writes it.
|
|
118
144
|
*
|
|
119
145
|
* The backfill derives `script` from the Ark address, matching what the
|
|
120
146
|
* indexer would have returned — new rows from the indexer always carry a
|
|
@@ -158,10 +184,11 @@ var SQLiteWalletRepository = class {
|
|
|
158
184
|
addedCanonicalColumns = true;
|
|
159
185
|
}
|
|
160
186
|
}
|
|
161
|
-
|
|
187
|
+
const hasLegacyBlob = cols.some((c) => c.name === "virtual_status_json");
|
|
188
|
+
if (addedCanonicalColumns && hasLegacyBlob) {
|
|
162
189
|
await this.backfillCanonicalVtxoColumns();
|
|
163
190
|
}
|
|
164
|
-
if (scriptCol && scriptCol.notnull === 1) {
|
|
191
|
+
if (scriptCol && scriptCol.notnull === 1 && !hasLegacyBlob) {
|
|
165
192
|
return;
|
|
166
193
|
}
|
|
167
194
|
if (!scriptCol) {
|
|
@@ -273,13 +300,8 @@ var SQLiteWalletRepository = class {
|
|
|
273
300
|
await this.db.run(`DELETE FROM ${this.tables.walletState}`);
|
|
274
301
|
}
|
|
275
302
|
// ── VTXO management ────────────────────────────────────────────────
|
|
276
|
-
async
|
|
277
|
-
|
|
278
|
-
const rows = await this.db.all(
|
|
279
|
-
`SELECT * FROM ${this.tables.vtxos} WHERE address = ?`,
|
|
280
|
-
[address]
|
|
281
|
-
);
|
|
282
|
-
return rows.map(vtxoRowToDomain);
|
|
303
|
+
async getVtxosPage(address, page) {
|
|
304
|
+
return this.pageByAddress(this.tables.vtxos, address, page, vtxoRowToDomain);
|
|
283
305
|
}
|
|
284
306
|
async saveVtxos(address, vtxos) {
|
|
285
307
|
await this.ensureInit();
|
|
@@ -310,13 +332,13 @@ var SQLiteWalletRepository = class {
|
|
|
310
332
|
s.intentTapLeafScript.cb,
|
|
311
333
|
s.intentTapLeafScript.s,
|
|
312
334
|
JSON.stringify(s.status),
|
|
313
|
-
|
|
335
|
+
createdAtToIso(s.createdAt),
|
|
314
336
|
s.isUnrolled ? 1 : 0,
|
|
315
337
|
s.isSpent === void 0 ? null : s.isSpent ? 1 : 0,
|
|
316
338
|
s.isSwept === void 0 ? null : s.isSwept ? 1 : 0,
|
|
317
339
|
s.isPreconfirmed === void 0 ? null : s.isPreconfirmed ? 1 : 0,
|
|
318
340
|
s.commitmentTxIds ? JSON.stringify(s.commitmentTxIds) : null,
|
|
319
|
-
s.expiresAt === void 0 ? null :
|
|
341
|
+
s.expiresAt === void 0 ? null : new Date(s.expiresAt).toISOString(),
|
|
320
342
|
s.expiresAtHeight ?? null,
|
|
321
343
|
s.spentBy ?? null,
|
|
322
344
|
s.settledBy ?? null,
|
|
@@ -332,39 +354,53 @@ var SQLiteWalletRepository = class {
|
|
|
332
354
|
await this.ensureInit();
|
|
333
355
|
await this.db.run(`DELETE FROM ${this.tables.vtxos} WHERE address = ?`, [address]);
|
|
334
356
|
}
|
|
335
|
-
async
|
|
357
|
+
async getVtxosForScriptPage(script, page, options) {
|
|
358
|
+
assertPageRequest(page);
|
|
336
359
|
await this.ensureInit();
|
|
360
|
+
const after = page.after;
|
|
337
361
|
const rows = await this.db.all(
|
|
338
|
-
`SELECT * FROM ${this.tables.vtxos} WHERE script =
|
|
339
|
-
|
|
362
|
+
`SELECT * FROM ${this.tables.vtxos} WHERE script = ?
|
|
363
|
+
${options?.unspentOnly ? `AND ${UNSPENT_VTXO_PREDICATE}` : ""}
|
|
364
|
+
${after ? "AND (address > ? OR (address = ? AND (txid > ? OR (txid = ? AND vout > ?))))" : ""}
|
|
365
|
+
ORDER BY address, txid, vout LIMIT ?`,
|
|
366
|
+
after ? [
|
|
367
|
+
script,
|
|
368
|
+
after.address,
|
|
369
|
+
after.address,
|
|
370
|
+
after.txid,
|
|
371
|
+
after.txid,
|
|
372
|
+
after.vout,
|
|
373
|
+
page.limit + 1
|
|
374
|
+
] : [script, page.limit + 1]
|
|
340
375
|
);
|
|
341
|
-
|
|
376
|
+
const result = pageResult(
|
|
377
|
+
rows.map((row) => ({ address: row.address, vtxo: vtxoRowToDomain(row) })),
|
|
378
|
+
page.limit,
|
|
379
|
+
(row) => ({ address: row.address, txid: row.vtxo.txid, vout: row.vtxo.vout })
|
|
380
|
+
);
|
|
381
|
+
return options?.unspentOnly ? { ...result, items: result.items.filter((row) => !isVtxoSpent(row.vtxo)) } : result;
|
|
342
382
|
}
|
|
343
383
|
async saveVtxosForScript(key, vtxos) {
|
|
344
|
-
|
|
345
|
-
throw new Error("SQLiteWalletRepository requires an address");
|
|
346
|
-
}
|
|
347
|
-
for (const vtxo of vtxos) {
|
|
348
|
-
if (!isVtxoForScript(vtxo, key.script)) {
|
|
349
|
-
throw new Error(
|
|
350
|
-
`VTXO ${vtxo.txid}:${vtxo.vout} script mismatch: expected ${key.script}, got ${vtxo.script}`
|
|
351
|
-
);
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
return this.saveVtxos(key.address, vtxos);
|
|
384
|
+
return this.saveVtxos(checkSaveVtxosForScript("SQLiteWalletRepository", key, vtxos), vtxos);
|
|
355
385
|
}
|
|
356
386
|
async deleteVtxosForScript(script) {
|
|
357
387
|
await this.ensureInit();
|
|
358
388
|
await this.db.run(`DELETE FROM ${this.tables.vtxos} WHERE script = ?`, [script]);
|
|
359
389
|
}
|
|
360
390
|
// ── UTXO management ────────────────────────────────────────────────
|
|
361
|
-
async
|
|
391
|
+
async getUtxosPage(address, page) {
|
|
392
|
+
return this.pageByAddress(this.tables.utxos, address, page, utxoRowToDomain);
|
|
393
|
+
}
|
|
394
|
+
async pageByAddress(table, address, page, deserialize) {
|
|
395
|
+
assertPageRequest(page);
|
|
362
396
|
await this.ensureInit();
|
|
363
397
|
const rows = await this.db.all(
|
|
364
|
-
`SELECT * FROM ${
|
|
365
|
-
|
|
398
|
+
`SELECT * FROM ${table} WHERE address = ? AND (txid, vout) > (?, ?)
|
|
399
|
+
ORDER BY txid, vout LIMIT ?`,
|
|
400
|
+
[address, page.after?.txid ?? "", page.after?.vout ?? -1, page.limit + 1]
|
|
366
401
|
);
|
|
367
|
-
|
|
402
|
+
const result = pageResult(rows, page.limit, ({ txid, vout }) => ({ txid, vout }));
|
|
403
|
+
return { items: result.items.map(deserialize), nextCursor: result.nextCursor };
|
|
368
404
|
}
|
|
369
405
|
async saveUtxos(address, utxos) {
|
|
370
406
|
await this.ensureInit();
|
|
@@ -399,13 +435,36 @@ var SQLiteWalletRepository = class {
|
|
|
399
435
|
await this.db.run(`DELETE FROM ${this.tables.utxos} WHERE address = ?`, [address]);
|
|
400
436
|
}
|
|
401
437
|
// ── Transaction history ────────────────────────────────────────────
|
|
402
|
-
async
|
|
438
|
+
async getTransactionHistoryPage(filter, page) {
|
|
439
|
+
assertPageRequest(page);
|
|
440
|
+
assertHistoryPageFilter(filter);
|
|
403
441
|
await this.ensureInit();
|
|
442
|
+
const conditions = ["address = ?"];
|
|
443
|
+
const params = [filter.address];
|
|
444
|
+
if (filter.since !== void 0) {
|
|
445
|
+
conditions.push("created_at >= ?");
|
|
446
|
+
params.push(filter.since);
|
|
447
|
+
}
|
|
448
|
+
if (page.after !== void 0) {
|
|
449
|
+
conditions.push(
|
|
450
|
+
"(created_at, boarding_txid, commitment_txid, ark_txid) > (?, ?, ?, ?)"
|
|
451
|
+
);
|
|
452
|
+
params.push(
|
|
453
|
+
page.after.createdAt,
|
|
454
|
+
page.after.key.boardingTxid,
|
|
455
|
+
page.after.key.commitmentTxid,
|
|
456
|
+
page.after.key.arkTxid
|
|
457
|
+
);
|
|
458
|
+
}
|
|
404
459
|
const rows = await this.db.all(
|
|
405
|
-
`SELECT * FROM ${this.tables.transactions} WHERE
|
|
406
|
-
|
|
460
|
+
`SELECT * FROM ${this.tables.transactions} WHERE ${conditions.join(" AND ")}
|
|
461
|
+
ORDER BY created_at, boarding_txid, commitment_txid, ark_txid LIMIT ?`,
|
|
462
|
+
[...params, page.limit + 1]
|
|
407
463
|
);
|
|
408
|
-
return rows.map(txRowToDomain)
|
|
464
|
+
return pageResult(rows.map(txRowToDomain), page.limit, (tx) => ({
|
|
465
|
+
createdAt: tx.createdAt,
|
|
466
|
+
key: tx.key
|
|
467
|
+
}));
|
|
409
468
|
}
|
|
410
469
|
async saveTransactions(address, txs) {
|
|
411
470
|
await this.ensureInit();
|
|
@@ -463,15 +522,7 @@ var SQLiteWalletRepository = class {
|
|
|
463
522
|
);
|
|
464
523
|
}
|
|
465
524
|
};
|
|
466
|
-
var
|
|
467
|
-
function sanitizePrefix(prefix) {
|
|
468
|
-
if (!SAFE_PREFIX.test(prefix)) {
|
|
469
|
-
throw new Error(
|
|
470
|
-
`Invalid table prefix "${prefix}": only letters, digits, and underscores are allowed`
|
|
471
|
-
);
|
|
472
|
-
}
|
|
473
|
-
return prefix;
|
|
474
|
-
}
|
|
525
|
+
var UNSPENT_VTXO_PREDICATE = "(is_spent IS NULL OR is_spent = 0) AND (spent_by IS NULL OR spent_by = '') AND (settled_by IS NULL OR settled_by = '')";
|
|
475
526
|
function vtxoRowToDomain(row) {
|
|
476
527
|
const serialized = {
|
|
477
528
|
txid: row.txid,
|
|
@@ -548,11 +599,11 @@ function txRowToDomain(row) {
|
|
|
548
599
|
var SQLiteContractRepository = class {
|
|
549
600
|
constructor(db, options) {
|
|
550
601
|
this.db = db;
|
|
551
|
-
this.prefix =
|
|
602
|
+
this.prefix = sanitizeTablePrefix(options?.prefix ?? "ark_");
|
|
552
603
|
this.table = `${this.prefix}contracts`;
|
|
553
604
|
}
|
|
554
605
|
db;
|
|
555
|
-
version =
|
|
606
|
+
version = 3;
|
|
556
607
|
initPromise = null;
|
|
557
608
|
prefix;
|
|
558
609
|
table;
|
|
@@ -599,8 +650,10 @@ var SQLiteContractRepository = class {
|
|
|
599
650
|
await this.db.run(`DELETE FROM ${this.table}`);
|
|
600
651
|
}
|
|
601
652
|
// ── Contract management ────────────────────────────────────────────
|
|
602
|
-
async
|
|
653
|
+
async getContractsPage(filter, page) {
|
|
654
|
+
assertPageRequest(page);
|
|
603
655
|
await this.ensureInit();
|
|
656
|
+
if (contractFilterMatchesNothing(filter)) return { items: [] };
|
|
604
657
|
const conditions = [];
|
|
605
658
|
const params = [];
|
|
606
659
|
if (filter) {
|
|
@@ -609,12 +662,16 @@ var SQLiteContractRepository = class {
|
|
|
609
662
|
this.addFilterCondition(conditions, params, "type", filter.type);
|
|
610
663
|
this.addWatchCondition(conditions, params, filter.watch);
|
|
611
664
|
}
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
665
|
+
if (page.after !== void 0) {
|
|
666
|
+
conditions.push("script > ?");
|
|
667
|
+
params.push(page.after);
|
|
615
668
|
}
|
|
616
|
-
const
|
|
617
|
-
|
|
669
|
+
const where = conditions.length ? ` WHERE ${conditions.join(" AND ")}` : "";
|
|
670
|
+
const rows = await this.db.all(
|
|
671
|
+
`SELECT * FROM ${this.table}${where} ORDER BY script LIMIT ?`,
|
|
672
|
+
[...params, page.limit + 1]
|
|
673
|
+
);
|
|
674
|
+
return pageResult(rows.map(contractRowToDomain), page.limit, (contract) => contract.script);
|
|
618
675
|
}
|
|
619
676
|
async saveContract(contract) {
|
|
620
677
|
await this.ensureInit();
|
|
@@ -668,15 +725,6 @@ var SQLiteContractRepository = class {
|
|
|
668
725
|
params.push(...wanted);
|
|
669
726
|
}
|
|
670
727
|
};
|
|
671
|
-
var SAFE_PREFIX2 = /^[a-zA-Z0-9_]+$/;
|
|
672
|
-
function sanitizePrefix2(prefix) {
|
|
673
|
-
if (!SAFE_PREFIX2.test(prefix)) {
|
|
674
|
-
throw new Error(
|
|
675
|
-
`Invalid table prefix "${prefix}": only letters, digits, and underscores are allowed`
|
|
676
|
-
);
|
|
677
|
-
}
|
|
678
|
-
return prefix;
|
|
679
|
-
}
|
|
680
728
|
function contractRowToDomain(row) {
|
|
681
729
|
const contract = {
|
|
682
730
|
script: row.script,
|
|
@@ -699,15 +747,10 @@ function contractRowToDomain(row) {
|
|
|
699
747
|
}
|
|
700
748
|
|
|
701
749
|
// src/repositories/sqlite/intentRepository.ts
|
|
702
|
-
var SAFE_PREFIX3 = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
|
|
703
|
-
function sanitizePrefix3(p) {
|
|
704
|
-
if (!SAFE_PREFIX3.test(p)) throw new Error(`Invalid table prefix "${p}"`);
|
|
705
|
-
return p;
|
|
706
|
-
}
|
|
707
750
|
var SQLiteIntentRepository = class {
|
|
708
751
|
constructor(db, options) {
|
|
709
752
|
this.db = db;
|
|
710
|
-
this.prefix =
|
|
753
|
+
this.prefix = sanitizeTablePrefix(options?.prefix ?? "ark_");
|
|
711
754
|
this.t = `${this.prefix}intents`;
|
|
712
755
|
}
|
|
713
756
|
db;
|
|
@@ -746,19 +789,16 @@ var SQLiteIntentRepository = class {
|
|
|
746
789
|
`CREATE INDEX IF NOT EXISTS idx_${this.prefix}intent_state ON ${this.t} (state)`
|
|
747
790
|
);
|
|
748
791
|
}
|
|
749
|
-
withTx(fn) {
|
|
750
|
-
return runInTransaction(this.db, fn);
|
|
751
|
-
}
|
|
752
792
|
async clear() {
|
|
753
793
|
await this.ensureInit();
|
|
754
|
-
await this.
|
|
794
|
+
await runInTransaction(this.db, async () => {
|
|
755
795
|
await this.db.run(`DELETE FROM ${this.t}`);
|
|
756
796
|
});
|
|
757
797
|
}
|
|
758
798
|
async saveIntent(intent) {
|
|
759
799
|
await this.ensureInit();
|
|
760
800
|
const now = Date.now();
|
|
761
|
-
await this.
|
|
801
|
+
await runInTransaction(this.db, async () => {
|
|
762
802
|
await this.db.run(
|
|
763
803
|
`INSERT INTO ${this.t}
|
|
764
804
|
(intent_tx_id, intent_id, state, valid_from, valid_until,
|
|
@@ -806,15 +846,30 @@ var SQLiteIntentRepository = class {
|
|
|
806
846
|
);
|
|
807
847
|
});
|
|
808
848
|
}
|
|
809
|
-
async
|
|
849
|
+
async getIntentsPage(filter, page) {
|
|
850
|
+
assertPageRequest(page);
|
|
810
851
|
await this.ensureInit();
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
852
|
+
if (filter?.states?.length === 0) return { items: [] };
|
|
853
|
+
const stateSql = filter?.states ? ` AND state IN (${filter.states.map(() => "?").join(", ")})` : "";
|
|
854
|
+
const stateParams = filter?.states ?? [];
|
|
855
|
+
const batchSize = Math.max(64, page.limit + 1);
|
|
856
|
+
const rows = [];
|
|
857
|
+
let after = page.after;
|
|
858
|
+
while (rows.length <= page.limit) {
|
|
859
|
+
const batch = await this.db.all(
|
|
860
|
+
`SELECT * FROM ${this.t} WHERE intent_tx_id > ?${stateSql} ORDER BY intent_tx_id LIMIT ?`,
|
|
861
|
+
[after ?? "", ...stateParams, batchSize]
|
|
862
|
+
);
|
|
863
|
+
if (batch.length === 0) break;
|
|
864
|
+
for (const row of batch) {
|
|
865
|
+
after = row.intent_tx_id;
|
|
866
|
+
const intent = rowToIntent(row);
|
|
867
|
+
if (!filter || intentMatchesFilter(intent, filter)) rows.push(intent);
|
|
868
|
+
if (rows.length > page.limit) break;
|
|
869
|
+
}
|
|
870
|
+
if (batch.length < batchSize) break;
|
|
871
|
+
}
|
|
872
|
+
return pageResult(rows, page.limit, (intent) => intent.intentTxId);
|
|
818
873
|
}
|
|
819
874
|
async getLockedVtxoOutpoints() {
|
|
820
875
|
await this.ensureInit();
|
|
@@ -852,15 +907,10 @@ function rowToIntent(r) {
|
|
|
852
907
|
}
|
|
853
908
|
|
|
854
909
|
// src/repositories/sqlite/virtualTxRepository.ts
|
|
855
|
-
var SAFE_PREFIX4 = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
|
|
856
|
-
function sanitizePrefix4(p) {
|
|
857
|
-
if (!SAFE_PREFIX4.test(p)) throw new Error(`Invalid table prefix "${p}"`);
|
|
858
|
-
return p;
|
|
859
|
-
}
|
|
860
910
|
var SQLiteVirtualTxRepository = class {
|
|
861
911
|
constructor(db, options) {
|
|
862
912
|
this.db = db;
|
|
863
|
-
this.prefix =
|
|
913
|
+
this.prefix = sanitizeTablePrefix(options?.prefix ?? "ark_");
|
|
864
914
|
this.tTx = `${this.prefix}virtual_txs`;
|
|
865
915
|
this.tBranch = `${this.prefix}vtxo_branches`;
|
|
866
916
|
}
|
|
@@ -892,12 +942,9 @@ var SQLiteVirtualTxRepository = class {
|
|
|
892
942
|
`CREATE INDEX IF NOT EXISTS idx_${this.prefix}branch_vtxid ON ${this.tBranch} (virtual_txid)`
|
|
893
943
|
);
|
|
894
944
|
}
|
|
895
|
-
tx(fn) {
|
|
896
|
-
return runInTransaction(this.db, fn);
|
|
897
|
-
}
|
|
898
945
|
async clear() {
|
|
899
946
|
await this.ensureInit();
|
|
900
|
-
await this.
|
|
947
|
+
await runInTransaction(this.db, async () => {
|
|
901
948
|
await this.db.run(`DELETE FROM ${this.tTx}`);
|
|
902
949
|
await this.db.run(`DELETE FROM ${this.tBranch}`);
|
|
903
950
|
});
|
|
@@ -905,7 +952,7 @@ var SQLiteVirtualTxRepository = class {
|
|
|
905
952
|
async upsertVirtualTxs(txs) {
|
|
906
953
|
if (txs.length === 0) return;
|
|
907
954
|
await this.ensureInit();
|
|
908
|
-
await this.
|
|
955
|
+
await runInTransaction(this.db, async () => {
|
|
909
956
|
const placeholders = txs.map(() => "?").join(", ");
|
|
910
957
|
const existing = await this.db.all(
|
|
911
958
|
`SELECT * FROM ${this.tTx} WHERE txid IN (${placeholders})`,
|
|
@@ -932,7 +979,7 @@ var SQLiteVirtualTxRepository = class {
|
|
|
932
979
|
}
|
|
933
980
|
async setBranch(vtxo, branch) {
|
|
934
981
|
await this.ensureInit();
|
|
935
|
-
await this.
|
|
982
|
+
await runInTransaction(this.db, async () => {
|
|
936
983
|
await this.db.run(`DELETE FROM ${this.tBranch} WHERE vtxo_txid = ? AND vtxo_vout = ?`, [
|
|
937
984
|
vtxo.txid,
|
|
938
985
|
vtxo.vout
|
|
@@ -967,7 +1014,7 @@ var SQLiteVirtualTxRepository = class {
|
|
|
967
1014
|
}
|
|
968
1015
|
async pruneForSpentVtxo(vtxo) {
|
|
969
1016
|
await this.ensureInit();
|
|
970
|
-
await this.
|
|
1017
|
+
await runInTransaction(this.db, async () => {
|
|
971
1018
|
const removed = await this.db.all(
|
|
972
1019
|
`SELECT DISTINCT virtual_txid FROM ${this.tBranch} WHERE vtxo_txid = ? AND vtxo_vout = ?`,
|
|
973
1020
|
[vtxo.txid, vtxo.vout]
|
|
@@ -1000,13 +1047,6 @@ function rowToTx(r) {
|
|
|
1000
1047
|
};
|
|
1001
1048
|
}
|
|
1002
1049
|
|
|
1003
|
-
// src/repositories/sqlite/prefix.ts
|
|
1004
|
-
var SAFE_PREFIX5 = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
|
|
1005
|
-
function sanitizeTablePrefix(p) {
|
|
1006
|
-
if (!SAFE_PREFIX5.test(p)) throw new Error(`Invalid table prefix "${p}"`);
|
|
1007
|
-
return p;
|
|
1008
|
-
}
|
|
1009
|
-
|
|
1010
1050
|
export { SQLiteContractRepository, SQLiteIntentRepository, SQLiteVirtualTxRepository, SQLiteWalletRepository, runInTransaction, sanitizeTablePrefix };
|
|
1011
1051
|
//# sourceMappingURL=index.js.map
|
|
1012
1052
|
//# sourceMappingURL=index.js.map
|