@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.
package/dist/index.d.ts CHANGED
@@ -1,233 +1,9 @@
1
- import { IWallet, ProvisionedKey, ProvisionedClaimSecret, asset, arkade, RestIndexerProvider, Transaction, IContractManager, RestArkProvider, VHTLC, Identity } from '@arkade-os/sdk';
2
- import { DiscoveredMarket, Network, LocalCardInput, Side, OfferPlan } from '@arkade-os/solver-discovery';
3
- import { R as RfqStatus, a as RfqTransport, O as OnchainHtlc, C as ChainSource, b as ChainUtxo, c as OnchainHtlcPhase } from './rfq-BH2yvo3O.js';
4
- export { A as ARKADE_ASSET, d as ARKADE_BTC, e as AddressMismatch, H as HtlcUtxo, I as InvoiceFacts, L as LIGHTNING_BTC, f as LIGHTNING_RECEIVE_PAIR, g as LIGHTNING_SEND_PAIR, M as MAX_MIN_CONFIRMATIONS, h as MIN_CLAIM_WINDOW_SECONDS, i as MIN_HEADROOM_SECONDS, j as ONCHAIN_BTC, k as ONCHAIN_CLAIM_MARGIN_SECONDS, l as ONCHAIN_DUST_SATS, m as ONCHAIN_ORDER_MARGIN_SECONDS, n as ONCHAIN_RECEIVE_PAIR, o as ONCHAIN_SECONDS_PER_BLOCK, p as ONCHAIN_SEND_PAIR, q as OnchainHtlcParams, r as OnchainNetwork, s as RFQ_TERMINAL_STATES, t as RelaySocket, u as RfqQuote, v as RfqRefusalReason, S as SOLO_REFUND_HEADROOM_SECONDS, w as SwapRefusal, x as arkadeSwapRequest, y as assertFundable, z as assertReceivable, B as awaitOnchainFill, D as buildHtlcClaim, E as buildHtlcRefund, F as claimOnchainFill, G as classifyOnchainHtlc, J as deriveLightningReceive, K as deriveOnchainReceive, N as deriveOnchainSend, P as extractPreimage, Q as httpTransport, T as lightningReceiveRequest, U as lightningSendRequest, V as lightningSendVtxoScript, W as newPreimage, X as newRfqId, Y as offerTermsFromQuote, Z as onchainHtlcScript, _ as onchainReceiveRequest, $ as onchainSendRequest, a0 as paymentHashOf, a1 as receiveVtxoScript, a2 as relayTransport, a3 as requestLightningReceive, a4 as requestLightningSend, a5 as requestOnchainReceive, a6 as requestOnchainSend, a7 as rfqPair, a8 as unilateralClaimDelay, a9 as unilateralRefundDelay, aa as unilateralRefundWithoutReceiverDelay, ab as verifyLockupAddress, ac as verifyReceiveInvoice } from './rfq-BH2yvo3O.js';
5
-
6
- type AssetSwapStatus = "pending" | "cancelling" | "fulfilled" | "cancelled" | "recoverable" | "awaiting_fill" | "claimable" | "claimed" | "refunded_l1";
7
- /** The sentinel asset id for BTC itself, as opposed to a 68-hex asset id.
8
- * Lives here with the {@link AssetSwap} fields it describes so the market and
9
- * restore layers share one spelling instead of re-typing the literal. */
10
- declare const BTC_ASSET_ID = "btc";
11
- /**
12
- * The record fields a wallet-provisioned secret becomes — what
13
- * {@link swapSecretsToRecord} emits, and what every record type carrying swap
14
- * secrets embeds.
15
- *
16
- * A named type rather than four fields restated per record: the mapper and the
17
- * records it feeds must agree exactly, and a record that silently omits one of
18
- * these round-trips a swap whose preimage cannot be re-derived. Embedding makes
19
- * the omission a compile error instead.
20
- *
21
- * **Only `preimageHex` is secret.** `signingDescriptor` and `preimageSaltHex`
22
- * are public derivation inputs — they must survive a field-mapped backend, but
23
- * they leak nothing without the seed.
24
- */
25
- interface SwapSecretsProjection {
26
- /**
27
- * The wallet descriptor this swap's sender key comes from — a fresh HD
28
- * child, or a static wallet's `tr(pubkey)`. Public — the signer
29
- * re-derives from the wallet, so the record carries no key material.
30
- */
31
- signingDescriptor?: string;
32
- /** P, hex, when it cannot be re-derived from the seed at all: the user
33
- * supplied it, or the signer cannot sign deterministically. The swap's only
34
- * claim secret when present. */
35
- preimageHex?: string;
36
- /**
37
- * The salt P derives from, hex, on the salted arm — what a static wallet
38
- * gets instead of storing P. **Public**, and unlike every other field here
39
- * it is minted per swap: it is what stops one repeating key from handing
40
- * every swap the same preimage.
41
- */
42
- preimageSaltHex?: string;
43
- }
44
- interface AssetSwap extends SwapSecretsProjection {
45
- /** Funding txid — the swap's identity. */
46
- id: string;
47
- /** 'btc' or a 68-hex asset id. */
48
- fromAsset: string;
49
- toAsset: string;
50
- /** Atomic amounts as strings (bigint is not JSON-safe). */
51
- fromAmount: string;
52
- /** The covenant wantAmount — a floor, the fill pays >= this. */
53
- toAmount: string;
54
- swapAddress: string;
55
- /** Hex pkScript of the swap contract — the indexer monitoring key. */
56
- swapPkScript: string;
57
- /** TLV offer — needed to rebuild the contract for cancel. */
58
- offerHex: string;
59
- fundingTxid: string;
60
- spentTxid?: string;
61
- status: AssetSwapStatus;
62
- createdAt: number;
63
- completedAt?: number;
64
- /** RFQ pair string, e.g. `arkade:BTC->onchain:BTC`. */
65
- pair?: string;
66
- /** `sha256(P)`, hex. Public, and how a restore confirms a candidate
67
- * derivation is the right one. */
68
- paymentHash?: string;
69
- /** The L1 HTLC's pkScript, hex — the chain-watch key. */
70
- htlcPkScriptHex?: string;
71
- htlcLocktime?: number;
72
- /** The L1 funding txid, once observed. */
73
- l1Txid?: string;
74
- }
75
- /** All swaps, newest-first. Insertion order is not chronological — the restore
76
- * scan rebuilds records in tx-scan order — so sort at read to keep
77
- * newest-first canonical for every consumer. */
78
- declare const getAssetSwapsOrThrow: (repository: AssetSwapRepository) => Promise<AssetSwap[]>;
79
- /** The consumer read: a broken backend reads as no swaps rather than crashing
80
- * a history view. Mutations must use {@link getAssetSwapsOrThrow} instead —
81
- * swallowing the read there would let "the backend is gone" masquerade as "no
82
- * such swap" and skip the write silently. */
83
- declare const getAssetSwaps: (repository: AssetSwapRepository) => Promise<AssetSwap[]>;
84
- /** Add a swap; no-op if the id is already stored. Returns the updated list.
85
- * THROWS on a failed write — nothing irreversible may happen until this record
86
- * is durable, so the caller must not fund on a failure. */
87
- declare const addAssetSwap: (repository: AssetSwapRepository, swap: AssetSwap) => Promise<AssetSwap[]>;
88
- /** Merge changes into a swap by id. Returns the updated list.
89
- * THROWS on a failed read or write, like {@link addAssetSwap} — use this for a
90
- * write that gates something irreversible. Transitions written *after* the
91
- * irreversible act belong on {@link updateAssetSwapBestEffort}. */
92
- declare const updateAssetSwap: (repository: AssetSwapRepository, id: string, changes: Partial<Omit<AssetSwap, "id">>) => Promise<AssetSwap[]>;
93
- /**
94
- * {@link updateAssetSwap} for transitions that follow an irreversible action (a
95
- * broadcast claim, a spent lockup): failing the caller there would report as
96
- * failed a swap whose funds already moved, and a stale status is recoverable —
97
- * crash recovery re-derives the true state from the chain
98
- * (`classifyOnchainHtlc`).
99
- *
100
- * `persisted` is the part that must not be hidden: a caller that notifies on a
101
- * change, or treats one as terminal, has to know the store did not agree.
102
- */
103
- declare const updateAssetSwapBestEffort: (repository: AssetSwapRepository, id: string, changes: Partial<Omit<AssetSwap, "id">>) => Promise<{
104
- swaps: AssetSwap[];
105
- persisted: boolean;
106
- }>;
107
- /**
108
- * The record fields a wallet-provisioned secret becomes.
109
- *
110
- * `signingDescriptor` is public and always stored — it is what recovers the
111
- * signer. Then at most one of: `preimageHex`, when the wallet says it cannot
112
- * re-derive P and it becomes the swap's only claim secret; or
113
- * `preimageSaltHex`, the public input a derivable-but-repeating key needs.
114
- */
115
- declare const swapSecretsToRecord: (secrets: ProvisionedKey | ProvisionedClaimSecret) => SwapSecretsProjection & {
116
- signingDescriptor: string;
117
- };
118
- /** Why a wallet cannot produce a swap's preimage. */
119
- type PreimageBlockedReason =
120
- /** The record carries no `signingDescriptor`. */
121
- "no-secrets"
122
- /** `preimageHex` or `preimageSaltHex` is present but not 32 bytes of hex. */
123
- | "malformed-record"
124
- /**
125
- * Nothing to derive from: a descriptor that repeats across swaps, with
126
- * neither a stored preimage nor a salt — or one this wallet holds no key
127
- * for. Merged deliberately: `contractSigner` reports a key it does not
128
- * hold as a plain `Error` for static wallets and a `ForeignDescriptorError`
129
- * for HD ones, so splitting the two here would mean matching on message
130
- * text, which is the thing this type exists to avoid. The `cause` carries
131
- * whichever it was.
132
- */
133
- | "not-derivable"
134
- /** Derived, but it does not hash to the record's `paymentHash`. */
135
- | "hash-mismatch";
136
- /**
137
- * The wallet cannot produce this swap's preimage, and which of the four ways
138
- * is `reason`.
139
- *
140
- * Deliberately **not** {@link RefundNotLocallyPossibleError}: that one means
141
- * "no local refund is possible", and `RfqSwapManager` acts on it by reporting
142
- * `needs_counterparty`. A claim-path read failure is a different verdict, and
143
- * borrowing the refund error would have the manager announce one for the
144
- * other.
145
- */
146
- declare class PreimageNotRecoverableError extends Error {
147
- readonly reason: PreimageBlockedReason;
148
- readonly name = "PreimageNotRecoverableError";
149
- constructor(reason: PreimageBlockedReason, message: string, options?: {
150
- cause?: unknown;
151
- });
152
- }
153
- /**
154
- * The preimage a swap record claims with — stored, or re-derived from the
155
- * wallet.
156
- *
157
- * The record-shaped inverse of {@link swapSecretsToRecord}, and the one place
158
- * that knows which of a record's fields `contractPreimage` needs. Wire claim
159
- * paths here rather than composing it by hand: a caller that forgets to pass
160
- * `preimageSaltHex` gets a *wrong* preimage from a wallet that can derive,
161
- * not an error.
162
- *
163
- * Verifies the result against `paymentHash` when the record carries one. The
164
- * salted arm has two inputs that can be wrong — the key and the salt — where
165
- * the HD arm had one, and a wrong P otherwise surfaces as an opaque script
166
- * failure at claim time, long after the mistake.
167
- *
168
- * Every refusal is a {@link PreimageNotRecoverableError} carrying a `reason`,
169
- * so a caller can tell "this record predates the descriptor" from "the salt is
170
- * corrupt" without reading message text.
171
- */
172
- declare const preimageForSwapRecord: (wallet: IWallet, record: SwapSecretsProjection & {
173
- paymentHash?: string;
174
- }) => Promise<Uint8Array>;
175
-
176
- /** A registry discovery result held for reuse. Refetchable — unlike a swap
177
- * record, losing it costs one network round trip — but it must survive a cold
178
- * boot: serving it stale is what keeps quoting alive while a registry is down. */
179
- interface MarketsCacheEntry {
180
- markets: DiscoveredMarket[];
181
- fetchedAt: number;
182
- }
183
- /**
184
- * Everything the package persists, following the monorepo repository
185
- * convention (versioned interface, AsyncDisposable, one backend per
186
- * platform — see the Boltz plugin's SwapRepository). Consumers construct
187
- * exactly one of these; there is no second storage seam.
188
- *
189
- * Durable records (swaps) and rebuildable state (the restore scan's txid
190
- * cursor, the markets cache) live side by side because they share a
191
- * lifetime: all three belong to one wallet on one device, and a consumer
192
- * that wipes one wants all three gone.
193
- *
194
- * ponytail: no query filters — every consumer reads all swaps and filters
195
- * in memory; mirror the Boltz plugin's GetSwapsFilter when a consumer needs
196
- * subset queries.
197
- */
198
- interface AssetSwapRepository extends AsyncDisposable {
199
- readonly version: 2;
200
- /** Insert or replace a swap by id. Store the record whole: `preimageHex`
201
- * and `preimageSaltHex` both leave the swap unclaimable if a field-mapped
202
- * backend drops them — the first is the only claim secret of a swap whose
203
- * signer cannot derive, the second the public input every other static
204
- * wallet's preimage derives from. */
205
- saveSwap(swap: AssetSwap): Promise<void>;
206
- /** All stored swaps, in no particular order — `getAssetSwaps` is the
207
- * canonical newest-first read. */
208
- getAllSwaps(): Promise<AssetSwap[]>;
209
- /** Sent txids already checked for offer packets (see restore.ts). */
210
- getScannedTxids(): Promise<Set<string>>;
211
- markTxidsScanned(txids: Iterable<string>): Promise<void>;
212
- /** Cached registry markets, or undefined on a miss. */
213
- getCachedMarkets(network: string, registry: string): Promise<MarketsCacheEntry | undefined>;
214
- saveCachedMarkets(network: string, registry: string, entry: MarketsCacheEntry): Promise<void>;
215
- clear(): Promise<void>;
216
- }
217
- declare class InMemoryAssetSwapRepository implements AssetSwapRepository {
218
- readonly version: 2;
219
- private readonly swaps;
220
- private readonly scanned;
221
- private readonly markets;
222
- saveSwap(swap: AssetSwap): Promise<void>;
223
- getAllSwaps(): Promise<AssetSwap[]>;
224
- getScannedTxids(): Promise<Set<string>>;
225
- markTxidsScanned(txids: Iterable<string>): Promise<void>;
226
- getCachedMarkets(network: string, registry: string): Promise<MarketsCacheEntry | undefined>;
227
- saveCachedMarkets(network: string, registry: string, entry: MarketsCacheEntry): Promise<void>;
228
- clear(): Promise<void>;
229
- [Symbol.asyncDispose](): Promise<void>;
230
- }
1
+ import { asset, IWallet, arkade, RestIndexerProvider, Transaction, IContractManager, RestArkProvider, VHTLC, Identity, ActivityResolver } from '@arkade-os/sdk';
2
+ import { A as AssetSwapRepository, a as AssetSwap, M as MarketsCacheEntry } from './repository-BwnZ8N62.js';
3
+ export { b as AssetSwapStatus, B as BTC_ASSET_ID, I as InMemoryAssetSwapRepository, P as PreimageBlockedReason, c as PreimageNotRecoverableError, S as SwapSecretsProjection, d as addAssetSwap, g as getAssetSwaps, e as getAssetSwapsOrThrow, p as preimageForSwapRecord, s as swapSecretsToRecord, u as updateAssetSwap, f as updateAssetSwapBestEffort } from './repository-BwnZ8N62.js';
4
+ import { Network, LocalCardInput, DiscoveredMarket, Side, OfferPlan } from '@arkade-os/solver-discovery';
5
+ import { R as RfqStatus, a as RfqTransport, O as OnchainHtlc, C as ChainSource, b as ChainUtxo, c as OnchainHtlcPhase } from './rfq-3jWha5xA.js';
6
+ export { A as ARKADE_ASSET, d as ARKADE_BTC, e as AddressMismatch, H as HtlcUtxo, I as InvoiceFacts, L as LIGHTNING_BTC, f as LIGHTNING_RECEIVE_PAIR, g as LIGHTNING_SEND_PAIR, M as MAX_MIN_CONFIRMATIONS, h as MIN_CLAIM_WINDOW_SECONDS, i as MIN_HEADROOM_SECONDS, j as ONCHAIN_BTC, k as ONCHAIN_CLAIM_MARGIN_SECONDS, l as ONCHAIN_DUST_SATS, m as ONCHAIN_ORDER_MARGIN_SECONDS, n as ONCHAIN_RECEIVE_PAIR, o as ONCHAIN_SECONDS_PER_BLOCK, p as ONCHAIN_SEND_PAIR, q as OnchainHtlcParams, r as OnchainNetwork, s as RFQ_TERMINAL_STATES, t as RelaySocket, u as RfqQuote, v as RfqRefusalReason, S as SOLO_REFUND_HEADROOM_SECONDS, w as SwapRefusal, x as arkadeSwapRequest, y as assertFundable, z as assertReceivable, B as awaitOnchainFill, D as buildHtlcClaim, E as buildHtlcRefund, F as claimOnchainFill, G as classifyOnchainHtlc, J as deriveLightningReceive, K as deriveOnchainReceive, N as deriveOnchainSend, P as extractPreimage, Q as httpTransport, T as lightningReceiveRequest, U as lightningSendRequest, V as lightningSendVtxoScript, W as newPreimage, X as newRfqId, Y as offerTermsFromQuote, Z as onchainHtlcScript, _ as onchainReceiveRequest, $ as onchainSendRequest, a0 as paymentHashOf, a1 as receiveVtxoScript, a2 as relayTransport, a3 as requestLightningReceive, a4 as requestLightningSend, a5 as requestOnchainReceive, a6 as requestOnchainSend, a7 as rfqPair, a8 as unilateralClaimDelay, a9 as unilateralRefundDelay, aa as unilateralRefundWithoutReceiverDelay, ab as verifyLockupAddress, ac as verifyReceiveInvoice } from './rfq-3jWha5xA.js';
231
7
 
232
8
  /** The contracts — pure data, shared verbatim with any other implementation. */
233
9
  declare const swapPrograms: Record<"wantAsset" | "wantBtc", ReturnType<typeof arkade.parseArtifact>>;
@@ -2010,4 +1786,43 @@ interface RfqSwapOutcome {
2010
1786
  txid?: string;
2011
1787
  }
2012
1788
 
2013
- export { type ArkadeRefundResult, type AssetSwap, type AssetSwapRepository, type AssetSwapStatus, BTC_ASSET_ID, ChainSource, ChainUtxo, type ClaimArkProvider, type ClaimPacketInput, type DiscoverMarketsOptions, InMemoryAssetSwapRepository, IndexedDbAssetSwapRepository, type LightningReceiveSwap, type LightningSendSwap, LockupAmountMismatchError, type LockupContractWriter, type LockupFate, LockupNeedsRecoveryError, LockupRegistrationFailed, type LockupSpendIndexer, type LockupVtxo, type MarketsCacheEntry, OFFER_PACKET_TYPE, type Offer, type OfferContractRetirer, type OfferSwapWatcher, OnchainHtlc, OnchainHtlcPhase, type OnchainSendAction, type OnchainSendSwap, type PlanError, type PreimageBlockedReason, PreimageNotRecoverableError, QUOTE_OPTIONS, REFUND_MTP_LAG_SECONDS, RFQ_RESOLVED_STATES, RFQ_SWAP_TERMINAL_STATES, type RefundArkProvider, type RefundBlockedReason, type RefundIndexer, RefundNotLocallyPossibleError, type RefundOutcome, type RestoreIndexer, RfqStatus, type RfqSwap, type RfqSwapActionName, type RfqSwapLockup, RfqSwapManager, type RfqSwapManagerCallbacks, type RfqSwapManagerConfig, type RfqSwapManagerDeps, type RfqSwapManagerEvents, type RfqSwapOutcome, type RfqSwapState, RfqTransport, SWAP_LOCKUP_CONTRACT_KIND, SWAP_LOCKUP_CONTRACT_LABEL, SWAP_LOCKUP_CONTRACT_TYPE, type SealedClaimPacket, type SpendKind, type SwapContractRegistry, type SwapSecretsProjection, type Tx, type WatchOfferSwapsParams, addAssetSwap, awaitLockupFunding, awaitRfqResolution, cancelOffer, claimReceiveLockup, classifyDepositSpend, classifySpend, createOffer, decodeOffer, discoverMarkets, encodeOffer, findLockupVtxos, findMarket, getAssetSwaps, getAssetSwapsOrThrow, isRfqSwapTerminal, isRfqTerminal, makeCachedFeedFetch, nextOnchainAction, offerVtxoScript, preimageForSwapRecord, pushClaim, pushRefundWithoutReceiver, readLockupFate, refundIfUnresolved, registerLockupContract, restoreAssetSwaps, retireSettledOfferContracts, sealClaimPacket, senderIdentityForSwapRecord, spendTxidsOf, spendUpdate, swapPrograms, swapSecretsToRecord, updateAssetSwap, updateAssetSwapBestEffort, validatePlan, watchOfferSwaps };
1789
+ /**
1790
+ * One swap, flattened to what grouping needs: an identity, a corridor, an
1791
+ * outcome, and every Arkade transaction that belongs to it.
1792
+ *
1793
+ * Deliberately not a stored swap record itself — resolution should stay
1794
+ * testable with plain data rather than a repository. A correlation helper
1795
+ * that derives these from the record store and the funding lockup's VTXOs
1796
+ * lands separately.
1797
+ */
1798
+ interface SwapActivityInput {
1799
+ rfqId: string;
1800
+ /**
1801
+ * Literal union rather than `RfqSwapRecord["kind"]` — `RfqSwapRecord` lives
1802
+ * only on the unmerged rfq-persistence branch, not on master. Reconcile
1803
+ * with `RfqSwapRecord["kind"]` once that branch lands.
1804
+ */
1805
+ kind: "lightning_send" | "lightning_receive" | "onchain_send";
1806
+ state: RfqSwapState;
1807
+ /** Funding, claim and refund txids, in whatever order. */
1808
+ txids: readonly string[];
1809
+ }
1810
+ /**
1811
+ * Group each RFQ swap's transactions into one activity carrying its outcome.
1812
+ *
1813
+ * Without this a failed swap renders as two unrelated rows: the send that
1814
+ * funded the lockup, and the receive when the covenant refunds. Grouping by
1815
+ * `rfqId` collapses them into one activity, and the amount comes out correct
1816
+ * by netting, not by `buildActivities`'s same-key change exclusion — that
1817
+ * rule only fires when one txid is both sent and received, and funding and
1818
+ * refund are different txids. Summing the signed amounts
1819
+ * (`-funding + refund ≈ -fees`) is what does the work here.
1820
+ *
1821
+ * `prepare` loads once and `resolve` stays pure and synchronous, as the SDK's
1822
+ * `ActivityResolver` contract requires.
1823
+ */
1824
+ declare function swapActivityResolver(deps: {
1825
+ listSwaps(): Promise<readonly SwapActivityInput[]>;
1826
+ }): ActivityResolver;
1827
+
1828
+ export { type ArkadeRefundResult, AssetSwap, AssetSwapRepository, ChainSource, ChainUtxo, type ClaimArkProvider, type ClaimPacketInput, type DiscoverMarketsOptions, IndexedDbAssetSwapRepository, type LightningReceiveSwap, type LightningSendSwap, LockupAmountMismatchError, type LockupContractWriter, type LockupFate, LockupNeedsRecoveryError, LockupRegistrationFailed, type LockupSpendIndexer, type LockupVtxo, MarketsCacheEntry, OFFER_PACKET_TYPE, type Offer, type OfferContractRetirer, type OfferSwapWatcher, OnchainHtlc, OnchainHtlcPhase, type OnchainSendAction, type OnchainSendSwap, type PlanError, QUOTE_OPTIONS, REFUND_MTP_LAG_SECONDS, RFQ_RESOLVED_STATES, RFQ_SWAP_TERMINAL_STATES, type RefundArkProvider, type RefundBlockedReason, type RefundIndexer, RefundNotLocallyPossibleError, type RefundOutcome, type RestoreIndexer, RfqStatus, type RfqSwap, type RfqSwapActionName, type RfqSwapLockup, RfqSwapManager, type RfqSwapManagerCallbacks, type RfqSwapManagerConfig, type RfqSwapManagerDeps, type RfqSwapManagerEvents, type RfqSwapOutcome, type RfqSwapState, RfqTransport, SWAP_LOCKUP_CONTRACT_KIND, SWAP_LOCKUP_CONTRACT_LABEL, SWAP_LOCKUP_CONTRACT_TYPE, type SealedClaimPacket, type SpendKind, type SwapActivityInput, type SwapContractRegistry, type Tx, type WatchOfferSwapsParams, awaitLockupFunding, awaitRfqResolution, cancelOffer, claimReceiveLockup, classifyDepositSpend, classifySpend, createOffer, decodeOffer, discoverMarkets, encodeOffer, findLockupVtxos, findMarket, isRfqSwapTerminal, isRfqTerminal, makeCachedFeedFetch, nextOnchainAction, offerVtxoScript, pushClaim, pushRefundWithoutReceiver, readLockupFate, refundIfUnresolved, registerLockupContract, restoreAssetSwaps, retireSettledOfferContracts, sealClaimPacket, senderIdentityForSwapRecord, spendTxidsOf, spendUpdate, swapActivityResolver, swapPrograms, validatePlan, watchOfferSwaps };
package/dist/index.js CHANGED
@@ -60,6 +60,10 @@ import {
60
60
  verifyLockupAddress,
61
61
  verifyReceiveInvoice
62
62
  } from "./chunk-Q4FAYBXS.js";
63
+ import {
64
+ InMemoryAssetSwapRepository,
65
+ marketsCacheKey
66
+ } from "./chunk-WGRU2DBF.js";
63
67
 
64
68
  // src/offer.ts
65
69
  import { hex as hex2 } from "@scure/base";
@@ -690,40 +694,6 @@ var validatePlan = (plan, giveBalance, dust) => {
690
694
  return void 0;
691
695
  };
692
696
 
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
697
  // src/indexedDbRepository.ts
728
698
  import { closeDatabase, openDatabase } from "@arkade-os/sdk";
729
699
  var DEFAULT_DB_NAME = "arkade-intents";
@@ -2207,6 +2177,60 @@ var outcomeOf = (swap) => {
2207
2177
  };
2208
2178
  var errorMessage = (error) => error instanceof Error ? error.message : String(error);
2209
2179
  var outpointKey = (vtxo) => `${vtxo.txid}:${vtxo.vout}`;
2180
+
2181
+ // src/activity.ts
2182
+ var LABELS = {
2183
+ lightning_send: "Lightning send",
2184
+ lightning_receive: "Lightning receive",
2185
+ onchain_send: "Onchain send"
2186
+ };
2187
+ var OUTCOME = {
2188
+ pending: "pending",
2189
+ // `claimable` and `claimed` are both in-progress states with no
2190
+ // user-visible phase distinct from "pending". `needs_counterparty` is
2191
+ // different in kind — the swap is BLOCKED, not merely in flight, since no
2192
+ // unilateral trader move exists (see `RfqSwapState`). Collapsing it into
2193
+ // `pending` here is a deliberate choice the opaque-token design permits —
2194
+ // apps map tokens themselves — but a future reader weighing a `"blocked"`
2195
+ // or `"stuck"` token should know this was already considered.
2196
+ claimable: "pending",
2197
+ claimed: "pending",
2198
+ needs_counterparty: "pending",
2199
+ settled: "settled",
2200
+ refunded: "refunded",
2201
+ failed: "failed"
2202
+ };
2203
+ function swapActivityResolver(deps) {
2204
+ let byTxid = /* @__PURE__ */ new Map();
2205
+ return {
2206
+ id: "arkade:swap",
2207
+ async prepare() {
2208
+ const swaps = await deps.listSwaps();
2209
+ const index = /* @__PURE__ */ new Map();
2210
+ for (const swap of swaps) {
2211
+ for (const txid of swap.txids) {
2212
+ if (txid) index.set(txid, swap);
2213
+ }
2214
+ }
2215
+ byTxid = index;
2216
+ },
2217
+ resolve(tx) {
2218
+ const key = tx.key.arkTxid || tx.key.commitmentTxid || tx.key.boardingTxid;
2219
+ const swap = key ? byTxid.get(key) : void 0;
2220
+ if (!swap) return void 0;
2221
+ const lostReceive = swap.kind === "lightning_receive" && swap.state === "refunded";
2222
+ return [
2223
+ {
2224
+ groupId: `swap:${swap.rfqId}`,
2225
+ label: LABELS[swap.kind],
2226
+ kind: "swap",
2227
+ outcome: lostReceive ? "lost" : OUTCOME[swap.state],
2228
+ metadata: { rfqId: swap.rfqId, swapKind: swap.kind }
2229
+ }
2230
+ ];
2231
+ }
2232
+ };
2233
+ }
2210
2234
  export {
2211
2235
  ARKADE_ASSET,
2212
2236
  ARKADE_BTC,
@@ -2306,6 +2330,7 @@ export {
2306
2330
  senderIdentityForSwapRecord,
2307
2331
  spendTxidsOf,
2308
2332
  spendUpdate,
2333
+ swapActivityResolver,
2309
2334
  swapPrograms,
2310
2335
  swapSecretsToRecord,
2311
2336
  unilateralClaimDelay,
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-3jWha5xA.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-3jWha5xA.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
@@ -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
+ });