@arkade-os/swap 0.0.5 → 0.0.6

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.
@@ -0,0 +1,103 @@
1
+ import { RealmLike } from '@arkade-os/sdk/repositories/realm';
2
+ import { A as AssetSwapRepository, a as AssetSwap, M as MarketsCacheEntry } from '../../repository-BwnZ8N62.cjs';
3
+ import '@arkade-os/solver-discovery';
4
+ import '@arkade-os/sdk';
5
+
6
+ /**
7
+ * Realm backend for React Native.
8
+ *
9
+ * `realm` is not a dependency of this package: consumers open Realm with the
10
+ * schemas from `./schemas.ts` and pass the instance, validated against the
11
+ * shared `RealmLike` shape from `@arkade-os/sdk`.
12
+ *
13
+ * **Records are serialized as JSON**, whole, into a `data` property —
14
+ * `status` and `createdAt` are mapped out for querying only, so no field of a
15
+ * record can be dropped. That holds for JSON-safe values: a consumer-added
16
+ * `Date` comes back a string and a `bigint` throws on save, unlike the
17
+ * IndexedDB backend's structured clone. `AssetSwap` itself is JSON-safe by
18
+ * design.
19
+ *
20
+ * Realm creates the schemas on open, so there is nothing to initialise. The
21
+ * consumer owns the Realm lifecycle — `[Symbol.asyncDispose]` is a no-op.
22
+ */
23
+ declare class RealmAssetSwapRepository implements AssetSwapRepository {
24
+ private readonly realm;
25
+ readonly version: 2;
26
+ constructor(realm: RealmLike);
27
+ saveSwap(swap: AssetSwap): Promise<void>;
28
+ getAllSwaps(): Promise<AssetSwap[]>;
29
+ getScannedTxids(): Promise<Set<string>>;
30
+ markTxidsScanned(txids: Iterable<string>): Promise<void>;
31
+ getCachedMarkets(network: string, registry: string): Promise<MarketsCacheEntry | undefined>;
32
+ saveCachedMarkets(network: string, registry: string, entry: MarketsCacheEntry): Promise<void>;
33
+ /** All three schemas in one write: clearing swaps but keeping scanned txids
34
+ * would leave the restore scan permanently skipping those funding txs, so
35
+ * a partial clear must not be observable. */
36
+ clear(): Promise<void>;
37
+ [Symbol.asyncDispose](): Promise<void>;
38
+ }
39
+
40
+ /**
41
+ * Realm object schemas for the asset-swap repository.
42
+ *
43
+ * The names land in the **consuming application's** schema namespace, next to
44
+ * its own models and the SDK's `Ark*` / the Boltz plugin's `Boltz*`, so they
45
+ * are prefixed with `ArkadeAssetSwap`. Unlike the SQLite backend there is no
46
+ * prefix option: a Realm schema name is baked into the schema objects the
47
+ * consumer registers and into every `realm.objects(…)` call here.
48
+ *
49
+ * Since `realm` is not a dependency of this package, schemas are plain JS
50
+ * objects conforming to Realm's ObjectSchema shape. They are new, so a consumer
51
+ * adds them to its Realm config and bumps its own `schemaVersion`; no migration
52
+ * helper ships here.
53
+ */
54
+ declare const ArkadeAssetSwapSchema: {
55
+ name: string;
56
+ primaryKey: string;
57
+ properties: {
58
+ id: string;
59
+ status: string;
60
+ createdAt: string;
61
+ data: string;
62
+ };
63
+ };
64
+ declare const ArkadeAssetSwapScannedTxidSchema: {
65
+ name: string;
66
+ primaryKey: string;
67
+ properties: {
68
+ txid: string;
69
+ };
70
+ };
71
+ declare const ArkadeAssetSwapMarketsCacheSchema: {
72
+ name: string;
73
+ primaryKey: string;
74
+ properties: {
75
+ key: string;
76
+ data: string;
77
+ };
78
+ };
79
+ declare const AssetSwapRealmSchemas: ({
80
+ name: string;
81
+ primaryKey: string;
82
+ properties: {
83
+ id: string;
84
+ status: string;
85
+ createdAt: string;
86
+ data: string;
87
+ };
88
+ } | {
89
+ name: string;
90
+ primaryKey: string;
91
+ properties: {
92
+ txid: string;
93
+ };
94
+ } | {
95
+ name: string;
96
+ primaryKey: string;
97
+ properties: {
98
+ key: string;
99
+ data: string;
100
+ };
101
+ })[];
102
+
103
+ export { ArkadeAssetSwapMarketsCacheSchema, ArkadeAssetSwapScannedTxidSchema, ArkadeAssetSwapSchema, AssetSwapRealmSchemas, RealmAssetSwapRepository };
@@ -0,0 +1,103 @@
1
+ import { RealmLike } from '@arkade-os/sdk/repositories/realm';
2
+ import { A as AssetSwapRepository, a as AssetSwap, M as MarketsCacheEntry } from '../../repository-BwnZ8N62.js';
3
+ import '@arkade-os/solver-discovery';
4
+ import '@arkade-os/sdk';
5
+
6
+ /**
7
+ * Realm backend for React Native.
8
+ *
9
+ * `realm` is not a dependency of this package: consumers open Realm with the
10
+ * schemas from `./schemas.ts` and pass the instance, validated against the
11
+ * shared `RealmLike` shape from `@arkade-os/sdk`.
12
+ *
13
+ * **Records are serialized as JSON**, whole, into a `data` property —
14
+ * `status` and `createdAt` are mapped out for querying only, so no field of a
15
+ * record can be dropped. That holds for JSON-safe values: a consumer-added
16
+ * `Date` comes back a string and a `bigint` throws on save, unlike the
17
+ * IndexedDB backend's structured clone. `AssetSwap` itself is JSON-safe by
18
+ * design.
19
+ *
20
+ * Realm creates the schemas on open, so there is nothing to initialise. The
21
+ * consumer owns the Realm lifecycle — `[Symbol.asyncDispose]` is a no-op.
22
+ */
23
+ declare class RealmAssetSwapRepository implements AssetSwapRepository {
24
+ private readonly realm;
25
+ readonly version: 2;
26
+ constructor(realm: RealmLike);
27
+ saveSwap(swap: AssetSwap): Promise<void>;
28
+ getAllSwaps(): Promise<AssetSwap[]>;
29
+ getScannedTxids(): Promise<Set<string>>;
30
+ markTxidsScanned(txids: Iterable<string>): Promise<void>;
31
+ getCachedMarkets(network: string, registry: string): Promise<MarketsCacheEntry | undefined>;
32
+ saveCachedMarkets(network: string, registry: string, entry: MarketsCacheEntry): Promise<void>;
33
+ /** All three schemas in one write: clearing swaps but keeping scanned txids
34
+ * would leave the restore scan permanently skipping those funding txs, so
35
+ * a partial clear must not be observable. */
36
+ clear(): Promise<void>;
37
+ [Symbol.asyncDispose](): Promise<void>;
38
+ }
39
+
40
+ /**
41
+ * Realm object schemas for the asset-swap repository.
42
+ *
43
+ * The names land in the **consuming application's** schema namespace, next to
44
+ * its own models and the SDK's `Ark*` / the Boltz plugin's `Boltz*`, so they
45
+ * are prefixed with `ArkadeAssetSwap`. Unlike the SQLite backend there is no
46
+ * prefix option: a Realm schema name is baked into the schema objects the
47
+ * consumer registers and into every `realm.objects(…)` call here.
48
+ *
49
+ * Since `realm` is not a dependency of this package, schemas are plain JS
50
+ * objects conforming to Realm's ObjectSchema shape. They are new, so a consumer
51
+ * adds them to its Realm config and bumps its own `schemaVersion`; no migration
52
+ * helper ships here.
53
+ */
54
+ declare const ArkadeAssetSwapSchema: {
55
+ name: string;
56
+ primaryKey: string;
57
+ properties: {
58
+ id: string;
59
+ status: string;
60
+ createdAt: string;
61
+ data: string;
62
+ };
63
+ };
64
+ declare const ArkadeAssetSwapScannedTxidSchema: {
65
+ name: string;
66
+ primaryKey: string;
67
+ properties: {
68
+ txid: string;
69
+ };
70
+ };
71
+ declare const ArkadeAssetSwapMarketsCacheSchema: {
72
+ name: string;
73
+ primaryKey: string;
74
+ properties: {
75
+ key: string;
76
+ data: string;
77
+ };
78
+ };
79
+ declare const AssetSwapRealmSchemas: ({
80
+ name: string;
81
+ primaryKey: string;
82
+ properties: {
83
+ id: string;
84
+ status: string;
85
+ createdAt: string;
86
+ data: string;
87
+ };
88
+ } | {
89
+ name: string;
90
+ primaryKey: string;
91
+ properties: {
92
+ txid: string;
93
+ };
94
+ } | {
95
+ name: string;
96
+ primaryKey: string;
97
+ properties: {
98
+ key: string;
99
+ data: string;
100
+ };
101
+ })[];
102
+
103
+ export { ArkadeAssetSwapMarketsCacheSchema, ArkadeAssetSwapScannedTxidSchema, ArkadeAssetSwapSchema, AssetSwapRealmSchemas, RealmAssetSwapRepository };
@@ -0,0 +1,108 @@
1
+ import {
2
+ marketsCacheKey
3
+ } from "../../chunk-WGRU2DBF.js";
4
+
5
+ // src/repositories/realm/repository.ts
6
+ var SWAPS = "ArkadeAssetSwap";
7
+ var SCANNED = "ArkadeAssetSwapScannedTxid";
8
+ var MARKETS = "ArkadeAssetSwapMarketsCache";
9
+ var RealmAssetSwapRepository = class {
10
+ constructor(realm) {
11
+ this.realm = realm;
12
+ }
13
+ realm;
14
+ version = 2;
15
+ async saveSwap(swap) {
16
+ this.realm.write(() => {
17
+ this.realm.create(
18
+ SWAPS,
19
+ {
20
+ id: swap.id,
21
+ status: swap.status,
22
+ createdAt: swap.createdAt,
23
+ data: JSON.stringify(swap)
24
+ },
25
+ "modified"
26
+ );
27
+ });
28
+ }
29
+ async getAllSwaps() {
30
+ return [...this.realm.objects(SWAPS)].map(
31
+ (o) => JSON.parse(o.data)
32
+ );
33
+ }
34
+ async getScannedTxids() {
35
+ return new Set([...this.realm.objects(SCANNED)].map((o) => o.txid));
36
+ }
37
+ async markTxidsScanned(txids) {
38
+ this.realm.write(() => {
39
+ for (const txid of txids) this.realm.create(SCANNED, { txid }, "modified");
40
+ });
41
+ }
42
+ async getCachedMarkets(network, registry) {
43
+ const [row] = [
44
+ ...this.realm.objects(MARKETS).filtered("key == $0", marketsCacheKey(network, registry))
45
+ ];
46
+ return row ? JSON.parse(row.data) : void 0;
47
+ }
48
+ async saveCachedMarkets(network, registry, entry) {
49
+ this.realm.write(() => {
50
+ this.realm.create(
51
+ MARKETS,
52
+ { key: marketsCacheKey(network, registry), data: JSON.stringify(entry) },
53
+ "modified"
54
+ );
55
+ });
56
+ }
57
+ /** All three schemas in one write: clearing swaps but keeping scanned txids
58
+ * would leave the restore scan permanently skipping those funding txs, so
59
+ * a partial clear must not be observable. */
60
+ async clear() {
61
+ this.realm.write(() => {
62
+ for (const name of [SWAPS, SCANNED, MARKETS]) {
63
+ this.realm.delete(this.realm.objects(name));
64
+ }
65
+ });
66
+ }
67
+ async [Symbol.asyncDispose]() {
68
+ }
69
+ };
70
+
71
+ // src/repositories/realm/schemas.ts
72
+ var ArkadeAssetSwapSchema = {
73
+ name: "ArkadeAssetSwap",
74
+ primaryKey: "id",
75
+ properties: {
76
+ id: "string",
77
+ status: "string",
78
+ createdAt: "int",
79
+ data: "string"
80
+ }
81
+ };
82
+ var ArkadeAssetSwapScannedTxidSchema = {
83
+ name: "ArkadeAssetSwapScannedTxid",
84
+ primaryKey: "txid",
85
+ properties: {
86
+ txid: "string"
87
+ }
88
+ };
89
+ var ArkadeAssetSwapMarketsCacheSchema = {
90
+ name: "ArkadeAssetSwapMarketsCache",
91
+ primaryKey: "key",
92
+ properties: {
93
+ key: "string",
94
+ data: "string"
95
+ }
96
+ };
97
+ var AssetSwapRealmSchemas = [
98
+ ArkadeAssetSwapSchema,
99
+ ArkadeAssetSwapScannedTxidSchema,
100
+ ArkadeAssetSwapMarketsCacheSchema
101
+ ];
102
+ export {
103
+ ArkadeAssetSwapMarketsCacheSchema,
104
+ ArkadeAssetSwapScannedTxidSchema,
105
+ ArkadeAssetSwapSchema,
106
+ AssetSwapRealmSchemas,
107
+ RealmAssetSwapRepository
108
+ };
@@ -0,0 +1,163 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/repositories/sqlite/index.ts
21
+ var sqlite_exports = {};
22
+ __export(sqlite_exports, {
23
+ SQLiteAssetSwapRepository: () => SQLiteAssetSwapRepository
24
+ });
25
+ module.exports = __toCommonJS(sqlite_exports);
26
+
27
+ // src/repositories/sqlite/repository.ts
28
+ var import_sqlite = require("@arkade-os/sdk/repositories/sqlite");
29
+
30
+ // src/repository.ts
31
+ var marketsCacheKey = (network, registry) => `arkade-intents-markets-${network}-${registry}`;
32
+
33
+ // src/repositories/sqlite/repository.ts
34
+ var DEFAULT_PREFIX = "arkade_";
35
+ var INSERT_CHUNK = 500;
36
+ var SQLiteAssetSwapRepository = class {
37
+ constructor(db, options) {
38
+ this.db = db;
39
+ this.prefix = (0, import_sqlite.sanitizeTablePrefix)(options?.prefix ?? DEFAULT_PREFIX);
40
+ this.swaps = `${this.prefix}asset_swaps`;
41
+ this.scanned = `${this.prefix}asset_swap_scanned_txids`;
42
+ this.markets = `${this.prefix}asset_swap_markets`;
43
+ }
44
+ db;
45
+ version = 2;
46
+ initPromise = null;
47
+ prefix;
48
+ swaps;
49
+ scanned;
50
+ markets;
51
+ /** A rejected init is not cached. The DDL runs in a transaction on a shared
52
+ * connection, so it can fail for reasons that pass — a `SQLITE_BUSY` on
53
+ * `BEGIN IMMEDIATE`, a neighbour's rollback — and caching that rejection
54
+ * would strand the instance unusable for the life of the process. Same rule
55
+ * as the IndexedDB backend's `ensureDb`. */
56
+ ensureInit() {
57
+ return this.initPromise ??= this.init().catch((err) => {
58
+ this.initPromise = null;
59
+ throw err;
60
+ });
61
+ }
62
+ /** The DDL is transactional in SQLite too: run raw on a shared connection it
63
+ * would join a neighbour's open transaction and vanish with its rollback,
64
+ * while `initPromise` stayed resolved and every later statement failed with
65
+ * `no such table`. */
66
+ async init() {
67
+ await this.withTx(async () => {
68
+ await this.db.run(`CREATE TABLE IF NOT EXISTS ${this.swaps} (
69
+ id TEXT PRIMARY KEY,
70
+ status TEXT NOT NULL,
71
+ created_at INTEGER NOT NULL,
72
+ data TEXT NOT NULL
73
+ )`);
74
+ await this.db.run(
75
+ `CREATE INDEX IF NOT EXISTS idx_${this.prefix}asset_swaps_status ON ${this.swaps} (status)`
76
+ );
77
+ await this.db.run(
78
+ `CREATE INDEX IF NOT EXISTS idx_${this.prefix}asset_swaps_created_at ON ${this.swaps} (created_at)`
79
+ );
80
+ await this.db.run(`CREATE TABLE IF NOT EXISTS ${this.scanned} (txid TEXT PRIMARY KEY)`);
81
+ await this.db.run(
82
+ `CREATE TABLE IF NOT EXISTS ${this.markets} (cache_key TEXT PRIMARY KEY, data TEXT NOT NULL)`
83
+ );
84
+ });
85
+ }
86
+ /** Every write, including the single-statement ones. The chain serializes
87
+ * transaction *blocks*, not bare statements: one issued between a
88
+ * neighbour's BEGIN IMMEDIATE and its COMMIT becomes part of that
89
+ * transaction and dies with it. `fn` must issue only raw db calls — no
90
+ * repository method, no `ensureInit` — since `runInTransaction` cannot
91
+ * nest. */
92
+ withTx(fn) {
93
+ return (0, import_sqlite.runInTransaction)(this.db, fn);
94
+ }
95
+ async saveSwap(swap) {
96
+ await this.ensureInit();
97
+ await this.withTx(async () => {
98
+ await this.db.run(
99
+ `INSERT OR REPLACE INTO ${this.swaps} (id, status, created_at, data)
100
+ VALUES (?, ?, ?, ?)`,
101
+ [swap.id, swap.status, swap.createdAt, JSON.stringify(swap)]
102
+ );
103
+ });
104
+ }
105
+ async getAllSwaps() {
106
+ await this.ensureInit();
107
+ const rows = await this.db.all(`SELECT data FROM ${this.swaps}`);
108
+ return rows.map((r) => JSON.parse(r.data));
109
+ }
110
+ async getScannedTxids() {
111
+ await this.ensureInit();
112
+ const rows = await this.db.all(`SELECT txid FROM ${this.scanned}`);
113
+ return new Set(rows.map((r) => r.txid));
114
+ }
115
+ async markTxidsScanned(txids) {
116
+ await this.ensureInit();
117
+ const all = [...txids];
118
+ if (all.length === 0) return;
119
+ await this.withTx(async () => {
120
+ for (let i = 0; i < all.length; i += INSERT_CHUNK) {
121
+ const chunk = all.slice(i, i + INSERT_CHUNK);
122
+ await this.db.run(
123
+ `INSERT OR IGNORE INTO ${this.scanned} (txid) VALUES ${chunk.map(() => "(?)").join(", ")}`,
124
+ chunk
125
+ );
126
+ }
127
+ });
128
+ }
129
+ async getCachedMarkets(network, registry) {
130
+ await this.ensureInit();
131
+ const row = await this.db.get(
132
+ `SELECT data FROM ${this.markets} WHERE cache_key = ?`,
133
+ [marketsCacheKey(network, registry)]
134
+ );
135
+ return row ? JSON.parse(row.data) : void 0;
136
+ }
137
+ async saveCachedMarkets(network, registry, entry) {
138
+ await this.ensureInit();
139
+ await this.withTx(async () => {
140
+ await this.db.run(
141
+ `INSERT OR REPLACE INTO ${this.markets} (cache_key, data) VALUES (?, ?)`,
142
+ [marketsCacheKey(network, registry), JSON.stringify(entry)]
143
+ );
144
+ });
145
+ }
146
+ /** All three tables in one transaction: clearing swaps but keeping scanned
147
+ * txids would leave the restore scan permanently skipping those funding
148
+ * txs, so a partial clear must not be observable. */
149
+ async clear() {
150
+ await this.ensureInit();
151
+ await this.withTx(async () => {
152
+ await this.db.run(`DELETE FROM ${this.swaps}`);
153
+ await this.db.run(`DELETE FROM ${this.scanned}`);
154
+ await this.db.run(`DELETE FROM ${this.markets}`);
155
+ });
156
+ }
157
+ async [Symbol.asyncDispose]() {
158
+ }
159
+ };
160
+ // Annotate the CommonJS export names for ESM import in node:
161
+ 0 && (module.exports = {
162
+ SQLiteAssetSwapRepository
163
+ });
@@ -0,0 +1,63 @@
1
+ import { SQLExecutor } from '@arkade-os/sdk/repositories/sqlite';
2
+ import { A as AssetSwapRepository, a as AssetSwap, M as MarketsCacheEntry } from '../../repository-BwnZ8N62.cjs';
3
+ import '@arkade-os/solver-discovery';
4
+ import '@arkade-os/sdk';
5
+
6
+ /**
7
+ * SQLite backend over the SDK's `SQLExecutor`, so any driver plugs in
8
+ * (expo-sqlite on React Native, better-sqlite3, node:sqlite).
9
+ *
10
+ * **Records are serialized as JSON**, whole, into a `data` column — `status`
11
+ * and `created_at` are mapped out for querying only, so no field of a record
12
+ * can be dropped. That holds for JSON-safe values: a consumer-added `Date`
13
+ * comes back a string and a `bigint` throws on save, unlike the IndexedDB
14
+ * backend's structured clone. `AssetSwap` itself is JSON-safe by design.
15
+ *
16
+ * Tables are created lazily on first operation. The consumer owns the
17
+ * `SQLExecutor` lifecycle — `[Symbol.asyncDispose]` is a no-op — and must pass
18
+ * the **same executor instance** to every repository on the database: the
19
+ * write chain is keyed by that object, and a per-repository literal splits it.
20
+ */
21
+ declare class SQLiteAssetSwapRepository implements AssetSwapRepository {
22
+ private readonly db;
23
+ readonly version: 2;
24
+ private initPromise;
25
+ private readonly prefix;
26
+ private readonly swaps;
27
+ private readonly scanned;
28
+ private readonly markets;
29
+ constructor(db: SQLExecutor, options?: {
30
+ prefix?: string;
31
+ });
32
+ /** A rejected init is not cached. The DDL runs in a transaction on a shared
33
+ * connection, so it can fail for reasons that pass — a `SQLITE_BUSY` on
34
+ * `BEGIN IMMEDIATE`, a neighbour's rollback — and caching that rejection
35
+ * would strand the instance unusable for the life of the process. Same rule
36
+ * as the IndexedDB backend's `ensureDb`. */
37
+ private ensureInit;
38
+ /** The DDL is transactional in SQLite too: run raw on a shared connection it
39
+ * would join a neighbour's open transaction and vanish with its rollback,
40
+ * while `initPromise` stayed resolved and every later statement failed with
41
+ * `no such table`. */
42
+ private init;
43
+ /** Every write, including the single-statement ones. The chain serializes
44
+ * transaction *blocks*, not bare statements: one issued between a
45
+ * neighbour's BEGIN IMMEDIATE and its COMMIT becomes part of that
46
+ * transaction and dies with it. `fn` must issue only raw db calls — no
47
+ * repository method, no `ensureInit` — since `runInTransaction` cannot
48
+ * nest. */
49
+ private withTx;
50
+ saveSwap(swap: AssetSwap): Promise<void>;
51
+ getAllSwaps(): Promise<AssetSwap[]>;
52
+ getScannedTxids(): Promise<Set<string>>;
53
+ markTxidsScanned(txids: Iterable<string>): Promise<void>;
54
+ getCachedMarkets(network: string, registry: string): Promise<MarketsCacheEntry | undefined>;
55
+ saveCachedMarkets(network: string, registry: string, entry: MarketsCacheEntry): Promise<void>;
56
+ /** All three tables in one transaction: clearing swaps but keeping scanned
57
+ * txids would leave the restore scan permanently skipping those funding
58
+ * txs, so a partial clear must not be observable. */
59
+ clear(): Promise<void>;
60
+ [Symbol.asyncDispose](): Promise<void>;
61
+ }
62
+
63
+ export { SQLiteAssetSwapRepository };
@@ -0,0 +1,63 @@
1
+ import { SQLExecutor } from '@arkade-os/sdk/repositories/sqlite';
2
+ import { A as AssetSwapRepository, a as AssetSwap, M as MarketsCacheEntry } from '../../repository-BwnZ8N62.js';
3
+ import '@arkade-os/solver-discovery';
4
+ import '@arkade-os/sdk';
5
+
6
+ /**
7
+ * SQLite backend over the SDK's `SQLExecutor`, so any driver plugs in
8
+ * (expo-sqlite on React Native, better-sqlite3, node:sqlite).
9
+ *
10
+ * **Records are serialized as JSON**, whole, into a `data` column — `status`
11
+ * and `created_at` are mapped out for querying only, so no field of a record
12
+ * can be dropped. That holds for JSON-safe values: a consumer-added `Date`
13
+ * comes back a string and a `bigint` throws on save, unlike the IndexedDB
14
+ * backend's structured clone. `AssetSwap` itself is JSON-safe by design.
15
+ *
16
+ * Tables are created lazily on first operation. The consumer owns the
17
+ * `SQLExecutor` lifecycle — `[Symbol.asyncDispose]` is a no-op — and must pass
18
+ * the **same executor instance** to every repository on the database: the
19
+ * write chain is keyed by that object, and a per-repository literal splits it.
20
+ */
21
+ declare class SQLiteAssetSwapRepository implements AssetSwapRepository {
22
+ private readonly db;
23
+ readonly version: 2;
24
+ private initPromise;
25
+ private readonly prefix;
26
+ private readonly swaps;
27
+ private readonly scanned;
28
+ private readonly markets;
29
+ constructor(db: SQLExecutor, options?: {
30
+ prefix?: string;
31
+ });
32
+ /** A rejected init is not cached. The DDL runs in a transaction on a shared
33
+ * connection, so it can fail for reasons that pass — a `SQLITE_BUSY` on
34
+ * `BEGIN IMMEDIATE`, a neighbour's rollback — and caching that rejection
35
+ * would strand the instance unusable for the life of the process. Same rule
36
+ * as the IndexedDB backend's `ensureDb`. */
37
+ private ensureInit;
38
+ /** The DDL is transactional in SQLite too: run raw on a shared connection it
39
+ * would join a neighbour's open transaction and vanish with its rollback,
40
+ * while `initPromise` stayed resolved and every later statement failed with
41
+ * `no such table`. */
42
+ private init;
43
+ /** Every write, including the single-statement ones. The chain serializes
44
+ * transaction *blocks*, not bare statements: one issued between a
45
+ * neighbour's BEGIN IMMEDIATE and its COMMIT becomes part of that
46
+ * transaction and dies with it. `fn` must issue only raw db calls — no
47
+ * repository method, no `ensureInit` — since `runInTransaction` cannot
48
+ * nest. */
49
+ private withTx;
50
+ saveSwap(swap: AssetSwap): Promise<void>;
51
+ getAllSwaps(): Promise<AssetSwap[]>;
52
+ getScannedTxids(): Promise<Set<string>>;
53
+ markTxidsScanned(txids: Iterable<string>): Promise<void>;
54
+ getCachedMarkets(network: string, registry: string): Promise<MarketsCacheEntry | undefined>;
55
+ saveCachedMarkets(network: string, registry: string, entry: MarketsCacheEntry): Promise<void>;
56
+ /** All three tables in one transaction: clearing swaps but keeping scanned
57
+ * txids would leave the restore scan permanently skipping those funding
58
+ * txs, so a partial clear must not be observable. */
59
+ clear(): Promise<void>;
60
+ [Symbol.asyncDispose](): Promise<void>;
61
+ }
62
+
63
+ export { SQLiteAssetSwapRepository };