@arkade-os/swap 0.0.5 → 0.0.7

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/dist/index.js CHANGED
@@ -22,6 +22,7 @@ import {
22
22
  SWAP_LOCKUP_CONTRACT_LABEL,
23
23
  SWAP_LOCKUP_CONTRACT_TYPE,
24
24
  SwapRefusal,
25
+ arkadeAssetLeg,
25
26
  arkadeSwapRequest,
26
27
  assertFundable,
27
28
  assertReceivable,
@@ -59,7 +60,11 @@ import {
59
60
  unilateralRefundWithoutReceiverDelay,
60
61
  verifyLockupAddress,
61
62
  verifyReceiveInvoice
62
- } from "./chunk-Q4FAYBXS.js";
63
+ } from "./chunk-ZDTRQZE2.js";
64
+ import {
65
+ InMemoryAssetSwapRepository,
66
+ marketsCacheKey
67
+ } from "./chunk-WGRU2DBF.js";
63
68
 
64
69
  // src/offer.ts
65
70
  import { hex as hex2 } from "@scure/base";
@@ -690,40 +695,6 @@ var validatePlan = (plan, giveBalance, dust) => {
690
695
  return void 0;
691
696
  };
692
697
 
693
- // src/repository.ts
694
- var marketsCacheKey = (network, registry) => `arkade-intents-markets-${network}-${registry}`;
695
- var InMemoryAssetSwapRepository = class {
696
- version = 2;
697
- swaps = /* @__PURE__ */ new Map();
698
- scanned = /* @__PURE__ */ new Set();
699
- markets = /* @__PURE__ */ new Map();
700
- async saveSwap(swap) {
701
- this.swaps.set(swap.id, swap);
702
- }
703
- async getAllSwaps() {
704
- return [...this.swaps.values()];
705
- }
706
- async getScannedTxids() {
707
- return new Set(this.scanned);
708
- }
709
- async markTxidsScanned(txids) {
710
- for (const txid of txids) this.scanned.add(txid);
711
- }
712
- async getCachedMarkets(network, registry) {
713
- return this.markets.get(marketsCacheKey(network, registry));
714
- }
715
- async saveCachedMarkets(network, registry, entry) {
716
- this.markets.set(marketsCacheKey(network, registry), entry);
717
- }
718
- async clear() {
719
- this.swaps.clear();
720
- this.scanned.clear();
721
- this.markets.clear();
722
- }
723
- async [Symbol.asyncDispose]() {
724
- }
725
- };
726
-
727
698
  // src/indexedDbRepository.ts
728
699
  import { closeDatabase, openDatabase } from "@arkade-os/sdk";
729
700
  var DEFAULT_DB_NAME = "arkade-intents";
@@ -2207,6 +2178,60 @@ var outcomeOf = (swap) => {
2207
2178
  };
2208
2179
  var errorMessage = (error) => error instanceof Error ? error.message : String(error);
2209
2180
  var outpointKey = (vtxo) => `${vtxo.txid}:${vtxo.vout}`;
2181
+
2182
+ // src/activity.ts
2183
+ var LABELS = {
2184
+ lightning_send: "Lightning send",
2185
+ lightning_receive: "Lightning receive",
2186
+ onchain_send: "Onchain send"
2187
+ };
2188
+ var OUTCOME = {
2189
+ pending: "pending",
2190
+ // `claimable` and `claimed` are both in-progress states with no
2191
+ // user-visible phase distinct from "pending". `needs_counterparty` is
2192
+ // different in kind — the swap is BLOCKED, not merely in flight, since no
2193
+ // unilateral trader move exists (see `RfqSwapState`). Collapsing it into
2194
+ // `pending` here is a deliberate choice the opaque-token design permits —
2195
+ // apps map tokens themselves — but a future reader weighing a `"blocked"`
2196
+ // or `"stuck"` token should know this was already considered.
2197
+ claimable: "pending",
2198
+ claimed: "pending",
2199
+ needs_counterparty: "pending",
2200
+ settled: "settled",
2201
+ refunded: "refunded",
2202
+ failed: "failed"
2203
+ };
2204
+ function swapActivityResolver(deps) {
2205
+ let byTxid = /* @__PURE__ */ new Map();
2206
+ return {
2207
+ id: "arkade:swap",
2208
+ async prepare() {
2209
+ const swaps = await deps.listSwaps();
2210
+ const index = /* @__PURE__ */ new Map();
2211
+ for (const swap of swaps) {
2212
+ for (const txid of swap.txids) {
2213
+ if (txid) index.set(txid, swap);
2214
+ }
2215
+ }
2216
+ byTxid = index;
2217
+ },
2218
+ resolve(tx) {
2219
+ const key = tx.key.arkTxid || tx.key.commitmentTxid || tx.key.boardingTxid;
2220
+ const swap = key ? byTxid.get(key) : void 0;
2221
+ if (!swap) return void 0;
2222
+ const lostReceive = swap.kind === "lightning_receive" && swap.state === "refunded";
2223
+ return [
2224
+ {
2225
+ groupId: `swap:${swap.rfqId}`,
2226
+ label: LABELS[swap.kind],
2227
+ kind: "swap",
2228
+ outcome: lostReceive ? "lost" : OUTCOME[swap.state],
2229
+ metadata: { rfqId: swap.rfqId, swapKind: swap.kind }
2230
+ }
2231
+ ];
2232
+ }
2233
+ };
2234
+ }
2210
2235
  export {
2211
2236
  ARKADE_ASSET,
2212
2237
  ARKADE_BTC,
@@ -2245,6 +2270,7 @@ export {
2245
2270
  SWAP_LOCKUP_CONTRACT_TYPE,
2246
2271
  SwapRefusal,
2247
2272
  addAssetSwap,
2273
+ arkadeAssetLeg,
2248
2274
  arkadeSwapRequest,
2249
2275
  assertFundable,
2250
2276
  assertReceivable,
@@ -2306,6 +2332,7 @@ export {
2306
2332
  senderIdentityForSwapRecord,
2307
2333
  spendTxidsOf,
2308
2334
  spendUpdate,
2335
+ swapActivityResolver,
2309
2336
  swapPrograms,
2310
2337
  swapSecretsToRecord,
2311
2338
  unilateralClaimDelay,
package/dist/nostr.cjs CHANGED
@@ -91,6 +91,20 @@ var SwapRefusal = class extends Error {
91
91
  }
92
92
  };
93
93
  var MIN_HEADROOM_SECONDS = 90 * 60;
94
+ var expectQuote = (payload, rfqId, requestedPair) => {
95
+ const p = payload;
96
+ if (p?.type === "rfq_refusal") throw new SwapRefusal(p.reason ?? "unknown", p.rfq_id ?? rfqId);
97
+ if (p?.type !== "rfq_quote" || p.rfq_id !== rfqId) {
98
+ throw new Error(`unexpected reply: ${p?.type ?? "no payload"}`);
99
+ }
100
+ if (requestedPair !== void 0 && p.pair !== requestedPair) {
101
+ throw new Error(
102
+ `solver quoted ${JSON.stringify(p.pair)}, not the requested ${requestedPair}`
103
+ );
104
+ }
105
+ return payload;
106
+ };
107
+ var pairOf = (payload) => typeof payload.pair === "string" ? payload.pair : void 0;
94
108
  var SEQUENCE_GRANULARITY_SECONDS = 512;
95
109
  var SOLO_REFUND_HEADROOM_SECONDS = 8 * SEQUENCE_GRANULARITY_SECONDS;
96
110
  var MIN_CLAIM_WINDOW_SECONDS = 30 * 60;
@@ -119,14 +133,6 @@ var closeReasons = (raw) => raw.map((entry) => {
119
133
  const { url, reason } = entry ?? {};
120
134
  return url ? `${url}: ${reason ?? "closed"}` : reason ?? "closed";
121
135
  });
122
- var asQuote = (payload, rfqId) => {
123
- const p = payload;
124
- if (p?.type === "rfq_refusal") throw new SwapRefusal(p.reason ?? "unknown", p.rfq_id ?? rfqId);
125
- if (p?.type !== "rfq_quote" || p.rfq_id !== rfqId) {
126
- throw new Error(`unexpected reply: ${p?.type ?? "no payload"}`);
127
- }
128
- return payload;
129
- };
130
136
  var nostrRfqTransport = (options) => {
131
137
  const relays = options.relays;
132
138
  const solverPubkey = options.solverPubkey;
@@ -202,7 +208,7 @@ var nostrRfqTransport = (options) => {
202
208
  const rfqId = String(payload.rfq_id);
203
209
  const reply = awaitReply(rfqId);
204
210
  await send(payload);
205
- return asQuote(await reply, rfqId);
211
+ return expectQuote(await reply, rfqId, pairOf(payload));
206
212
  },
207
213
  async status(rfqId) {
208
214
  const reply = awaitReply(rfqId);
package/dist/nostr.d.cts CHANGED
@@ -1,10 +1,11 @@
1
- import { a as RfqTransport } from './rfq-BH2yvo3O.cjs';
1
+ import { a as RfqTransport } from './rfq-DfT9dAss.cjs';
2
2
  import { SimplePool } from 'nostr-tools';
3
3
  import '@arkade-os/sdk';
4
4
 
5
5
  /**
6
- * The Nostr RFQ transport — the PRODUCTION one (docs/rfq-protocol.md § 3.1 in
7
- * arkade-os/lightning-swap-service).
6
+ * The Nostr RFQ transport — the PRODUCTION one (the kind, the NIP-44 framing
7
+ * and the payloads it carries are public at
8
+ * https://docs.arkadeos.com/intents/reference/rfq).
8
9
  *
9
10
  * `rfq.ts` ships two other transports: `httpTransport`, and `relayTransport`
10
11
  * which speaks the dev broker's `{op:"sub"|"event"}` framing. Neither is what a
package/dist/nostr.d.ts CHANGED
@@ -1,10 +1,11 @@
1
- import { a as RfqTransport } from './rfq-BH2yvo3O.js';
1
+ import { a as RfqTransport } from './rfq-DfT9dAss.js';
2
2
  import { SimplePool } from 'nostr-tools';
3
3
  import '@arkade-os/sdk';
4
4
 
5
5
  /**
6
- * The Nostr RFQ transport — the PRODUCTION one (docs/rfq-protocol.md § 3.1 in
7
- * arkade-os/lightning-swap-service).
6
+ * The Nostr RFQ transport — the PRODUCTION one (the kind, the NIP-44 framing
7
+ * and the payloads it carries are public at
8
+ * https://docs.arkadeos.com/intents/reference/rfq).
8
9
  *
9
10
  * `rfq.ts` ships two other transports: `httpTransport`, and `relayTransport`
10
11
  * which speaks the dev broker's `{op:"sub"|"event"}` framing. Neither is what a
package/dist/nostr.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import {
2
- SwapRefusal
3
- } from "./chunk-Q4FAYBXS.js";
2
+ expectQuote,
3
+ pairOf
4
+ } from "./chunk-ZDTRQZE2.js";
4
5
 
5
6
  // src/nostr.ts
6
7
  import {
@@ -32,14 +33,6 @@ var closeReasons = (raw) => raw.map((entry) => {
32
33
  const { url, reason } = entry ?? {};
33
34
  return url ? `${url}: ${reason ?? "closed"}` : reason ?? "closed";
34
35
  });
35
- var asQuote = (payload, rfqId) => {
36
- const p = payload;
37
- if (p?.type === "rfq_refusal") throw new SwapRefusal(p.reason ?? "unknown", p.rfq_id ?? rfqId);
38
- if (p?.type !== "rfq_quote" || p.rfq_id !== rfqId) {
39
- throw new Error(`unexpected reply: ${p?.type ?? "no payload"}`);
40
- }
41
- return payload;
42
- };
43
36
  var nostrRfqTransport = (options) => {
44
37
  const relays = options.relays;
45
38
  const solverPubkey = options.solverPubkey;
@@ -115,7 +108,7 @@ var nostrRfqTransport = (options) => {
115
108
  const rfqId = String(payload.rfq_id);
116
109
  const reply = awaitReply(rfqId);
117
110
  await send(payload);
118
- return asQuote(await reply, rfqId);
111
+ return expectQuote(await reply, rfqId, pairOf(payload));
119
112
  },
120
113
  async status(rfqId) {
121
114
  const reply = awaitReply(rfqId);
@@ -0,0 +1,138 @@
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/realm/index.ts
21
+ var realm_exports = {};
22
+ __export(realm_exports, {
23
+ ArkadeAssetSwapMarketsCacheSchema: () => ArkadeAssetSwapMarketsCacheSchema,
24
+ ArkadeAssetSwapScannedTxidSchema: () => ArkadeAssetSwapScannedTxidSchema,
25
+ ArkadeAssetSwapSchema: () => ArkadeAssetSwapSchema,
26
+ AssetSwapRealmSchemas: () => AssetSwapRealmSchemas,
27
+ RealmAssetSwapRepository: () => RealmAssetSwapRepository
28
+ });
29
+ module.exports = __toCommonJS(realm_exports);
30
+
31
+ // src/repository.ts
32
+ var marketsCacheKey = (network, registry) => `arkade-intents-markets-${network}-${registry}`;
33
+
34
+ // src/repositories/realm/repository.ts
35
+ var SWAPS = "ArkadeAssetSwap";
36
+ var SCANNED = "ArkadeAssetSwapScannedTxid";
37
+ var MARKETS = "ArkadeAssetSwapMarketsCache";
38
+ var RealmAssetSwapRepository = class {
39
+ constructor(realm) {
40
+ this.realm = realm;
41
+ }
42
+ realm;
43
+ version = 2;
44
+ async saveSwap(swap) {
45
+ this.realm.write(() => {
46
+ this.realm.create(
47
+ SWAPS,
48
+ {
49
+ id: swap.id,
50
+ status: swap.status,
51
+ createdAt: swap.createdAt,
52
+ data: JSON.stringify(swap)
53
+ },
54
+ "modified"
55
+ );
56
+ });
57
+ }
58
+ async getAllSwaps() {
59
+ return [...this.realm.objects(SWAPS)].map(
60
+ (o) => JSON.parse(o.data)
61
+ );
62
+ }
63
+ async getScannedTxids() {
64
+ return new Set([...this.realm.objects(SCANNED)].map((o) => o.txid));
65
+ }
66
+ async markTxidsScanned(txids) {
67
+ this.realm.write(() => {
68
+ for (const txid of txids) this.realm.create(SCANNED, { txid }, "modified");
69
+ });
70
+ }
71
+ async getCachedMarkets(network, registry) {
72
+ const [row] = [
73
+ ...this.realm.objects(MARKETS).filtered("key == $0", marketsCacheKey(network, registry))
74
+ ];
75
+ return row ? JSON.parse(row.data) : void 0;
76
+ }
77
+ async saveCachedMarkets(network, registry, entry) {
78
+ this.realm.write(() => {
79
+ this.realm.create(
80
+ MARKETS,
81
+ { key: marketsCacheKey(network, registry), data: JSON.stringify(entry) },
82
+ "modified"
83
+ );
84
+ });
85
+ }
86
+ /** All three schemas in one write: clearing swaps but keeping scanned txids
87
+ * would leave the restore scan permanently skipping those funding txs, so
88
+ * a partial clear must not be observable. */
89
+ async clear() {
90
+ this.realm.write(() => {
91
+ for (const name of [SWAPS, SCANNED, MARKETS]) {
92
+ this.realm.delete(this.realm.objects(name));
93
+ }
94
+ });
95
+ }
96
+ async [Symbol.asyncDispose]() {
97
+ }
98
+ };
99
+
100
+ // src/repositories/realm/schemas.ts
101
+ var ArkadeAssetSwapSchema = {
102
+ name: "ArkadeAssetSwap",
103
+ primaryKey: "id",
104
+ properties: {
105
+ id: "string",
106
+ status: "string",
107
+ createdAt: "int",
108
+ data: "string"
109
+ }
110
+ };
111
+ var ArkadeAssetSwapScannedTxidSchema = {
112
+ name: "ArkadeAssetSwapScannedTxid",
113
+ primaryKey: "txid",
114
+ properties: {
115
+ txid: "string"
116
+ }
117
+ };
118
+ var ArkadeAssetSwapMarketsCacheSchema = {
119
+ name: "ArkadeAssetSwapMarketsCache",
120
+ primaryKey: "key",
121
+ properties: {
122
+ key: "string",
123
+ data: "string"
124
+ }
125
+ };
126
+ var AssetSwapRealmSchemas = [
127
+ ArkadeAssetSwapSchema,
128
+ ArkadeAssetSwapScannedTxidSchema,
129
+ ArkadeAssetSwapMarketsCacheSchema
130
+ ];
131
+ // Annotate the CommonJS export names for ESM import in node:
132
+ 0 && (module.exports = {
133
+ ArkadeAssetSwapMarketsCacheSchema,
134
+ ArkadeAssetSwapScannedTxidSchema,
135
+ ArkadeAssetSwapSchema,
136
+ AssetSwapRealmSchemas,
137
+ RealmAssetSwapRepository
138
+ });
@@ -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
+ };