@arkade-os/swap 0.0.10 → 0.1.0-rc.0
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 +59 -15
- package/dist/{chunk-5NPYNQ5V.js → chunk-AM3NNUMR.js} +112 -66
- package/dist/index.cjs +763 -227
- package/dist/index.d.cts +184 -47
- package/dist/index.d.ts +184 -47
- package/dist/index.js +653 -169
- package/dist/nostr.cjs +4 -1
- package/dist/nostr.d.cts +1 -1
- package/dist/nostr.d.ts +1 -1
- package/dist/nostr.js +1 -1
- package/dist/repositories/realm/index.d.cts +4 -4
- package/dist/repositories/realm/index.d.ts +4 -4
- package/dist/repositories/sqlite/index.d.cts +2 -2
- package/dist/repositories/sqlite/index.d.ts +2 -2
- package/dist/{repository-C8FXlmHY.d.cts → repository-BWP1UstE.d.cts} +124 -59
- package/dist/{repository-Cw2EvvZG.d.ts → repository-DLpH41ZO.d.ts} +124 -59
- package/dist/{rfq-DglvHMNC.d.ts → rfq-CzCGjICq.d.cts} +86 -48
- package/dist/{rfq-DglvHMNC.d.cts → rfq-CzCGjICq.d.ts} +86 -48
- package/package.json +4 -3
package/dist/index.d.cts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { ProvisionedKey, ProvisionedClaimSecret, asset, IWallet, arkade, RestIndexerProvider, Transaction, IContractManager, VHTLC, Identity, ActivityResolver } from '@arkade-os/sdk';
|
|
2
|
-
import { S as SwapSecretsProjection, R as RfqSwapRecord, A as AssetSwapRepository, a as AssetSwap, M as MarketsCacheEntry, b as
|
|
3
|
-
export {
|
|
1
|
+
import { ProvisionedKey, ProvisionedClaimSecret, asset, RelativeTimelock, IWallet, arkade, RestIndexerProvider, Transaction, IContractManager, VHTLC, Identity, ActivityResolver } from '@arkade-os/sdk';
|
|
2
|
+
import { S as SwapSecretsProjection, R as RfqSwapRecord, A as AssetSwapRepository, a as AssetSwap, M as MarketsCacheEntry, b as RefundIndexer, L as LockupVtxo, c as SwapOperator, d as RfqSwap, e as ArkadeRefundResult, f as LockupSpendIndexer, g as RfqSwapState, h as RfqSwapManager, i as RfqSwapManagerCallbacks } from './repository-BWP1UstE.cjs';
|
|
3
|
+
export { j as AssetSwapStatus, k as AvailableRfqSwapManagerCallbacks, B as BTC_ASSET_ID, I as InMemoryAssetSwapRepository, l as LightningReceiveSwap, m as LightningSendSwap, n as LockupFate, o as LockupNeedsRecoveryError, p as LockupParams, q as LockupSpend, O as OnchainSendAction, r as OnchainSendSwap, P as PersistableRfqSwap, s as PreimageBlockedReason, t as PreimageNotRecoverableError, u as REFUND_MTP_LAG_SECONDS, v as RFQ_RESOLVED_STATES, w as RFQ_SWAP_RETENTION_SECONDS, x as RFQ_SWAP_TERMINAL_STATES, y as RefundOutcome, z as RfqRestoreFailure, C as RfqRestoreOptions, D as RfqRestoreResult, E as RfqSwapActionName, F as RfqSwapLockup, G as RfqSwapManagerConfig, H as RfqSwapManagerDeps, J as RfqSwapManagerEvents, K as RfqSwapOrigin, N as RfqSwapOriginRequired, Q as RfqSwapOutcome, T as RfqSwapRecordStore, U as SwapContractRegistry, V as addAssetSwap, W as awaitRfqResolution, X as createRfqSwapRecord, Y as findLockupVtxos, Z as getAssetSwaps, _ as getAssetSwapsOrThrow, $ as isRfqSwapTerminal, a0 as isRfqTerminal, a1 as nextOnchainAction, a2 as normalizeRfqSwapRecord, a3 as preimageForSwapRecord, a4 as pushRefundWithoutReceiver, a5 as readLockupFate, a6 as rebuildRfqSwap, a7 as refundIfUnresolved, a8 as rfqSwapOriginOf, a9 as shouldRetainRfqSwap, aa as swapSecretsToRecord, ab as updateAssetSwap, ac as updateAssetSwapBestEffort, ad as updateRfqSwapRecord } from './repository-BWP1UstE.cjs';
|
|
4
4
|
import { Network, LocalCardInput, DiscoveredMarket, Side, OfferPlan } from '@arkade-os/solver-discovery';
|
|
5
|
-
import { O as OnchainNetwork, a as OnchainHtlc, b as OnchainHtlcParams } from './rfq-
|
|
6
|
-
export { A as ARKADE_ASSET,
|
|
5
|
+
import { O as OnchainNetwork, a as OnchainHtlc, b as OnchainHtlcParams, r as requestLightningReceive, c as requestLightningSend, d as requestOnchainSend, I as InvoiceFacts, R as RfqTransport, C as ChainSource } from './rfq-CzCGjICq.cjs';
|
|
6
|
+
export { A as ARKADE_ASSET, e as ARKADE_BTC, f as AddressMismatch, g as ChainUtxo, H as HtlcUtxo, L as LIGHTNING_BTC, h as LIGHTNING_RECEIVE_PAIR, i as LIGHTNING_SEND_PAIR, j as LOCKTIME_THRESHOLD, k as LightningReceiveContractParams, l as LightningSendContractParams, M as MAX_MIN_CONFIRMATIONS, m as MIN_CLAIM_WINDOW_SECONDS, n as MIN_HEADROOM_SECONDS, o as ONCHAIN_BTC, p as ONCHAIN_CLAIM_MARGIN_SECONDS, q as ONCHAIN_DUST_SATS, s as ONCHAIN_ORDER_MARGIN_SECONDS, t as ONCHAIN_RECEIVE_PAIR, u as ONCHAIN_SECONDS_PER_BLOCK, v as ONCHAIN_SEND_PAIR, w as OnchainHtlcPhase, x as RFQ_TERMINAL_STATES, y as RelaySocket, z as RfqQuote, B as RfqRefusalReason, D as RfqStatus, S as SOLO_REFUND_HEADROOM_SECONDS, E as SwapRefusal, F as arkadeAssetLeg, G as arkadeSwapRequest, J as assertFundable, K as assertReceivable, N as awaitOnchainFill, P as buildHtlcClaim, Q as buildHtlcRefund, T as claimOnchainFill, U as classifyOnchainHtlc, V as deriveLightningReceive, W as deriveOnchainReceive, X as deriveOnchainSend, Y as extractPreimage, Z as httpTransport, _ as lightningReceiveContract, $ as lightningReceiveRequest, a0 as lightningSendContract, a1 as lightningSendRequest, a2 as newPreimage, a3 as newRfqId, a4 as offerTermsFromQuote, a5 as onchainHtlcScript, a6 as onchainReceiveRequest, a7 as onchainSendRequest, a8 as paymentHashOf, a9 as relayTransport, aa as requestOnchainReceive, ab as rfqPair, ac as unilateralClaimDelay, ad as unilateralRefundDelay, ae as unilateralRefundWithoutReceiverDelay, af as verifyLockupAddress, ag as verifyReceiveInvoice } from './rfq-CzCGjICq.cjs';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Which wallet key signs this leg. Stored at `profile.signer`.
|
|
@@ -111,7 +111,7 @@ interface LightningReceiveProfile extends Record<string, unknown> {
|
|
|
111
111
|
* preimage that is already public, and a swap that did claim is relabelled
|
|
112
112
|
* `needs_counterparty` once its window shuts.
|
|
113
113
|
*/
|
|
114
|
-
|
|
114
|
+
claimTxid?: string;
|
|
115
115
|
}
|
|
116
116
|
/** `arkade:BTC->onchain:BTC`. */
|
|
117
117
|
interface OnchainSendProfile extends Record<string, unknown> {
|
|
@@ -182,7 +182,18 @@ declare function onchainSendProfile(result: {
|
|
|
182
182
|
minConfirmations: number;
|
|
183
183
|
}): Omit<OnchainSendProfile, "signer" | "hashlock">;
|
|
184
184
|
|
|
185
|
-
/**
|
|
185
|
+
/**
|
|
186
|
+
* The contracts, one per WANT side — pure data, shared verbatim with any other
|
|
187
|
+
* implementation.
|
|
188
|
+
*
|
|
189
|
+
* **These are the base: an offer carrying an exit delay compiles to a third
|
|
190
|
+
* closure that is not in either file.** The tree is not fixed-shape — the
|
|
191
|
+
* protocol defines the exit as `iff ExitDelay`, and solverd appends it the same
|
|
192
|
+
* way (`pkg/swap/contract/offer.go`, `VtxoScript`) — so it cannot be a function
|
|
193
|
+
* in a static artifact without splitting these into one file per exit variant.
|
|
194
|
+
* {@link withExitClosure} owns that step, and the golden in `offer.test.ts`
|
|
195
|
+
* pins the artifact it produces so the whole contract is still readable as data.
|
|
196
|
+
*/
|
|
186
197
|
declare const swapPrograms: Record<"wantAsset" | "wantBtc", ReturnType<typeof arkade.parseArtifact>>;
|
|
187
198
|
/** A full-fill offer. Exactly one field names an asset: `wantAsset` set = the
|
|
188
199
|
* fill must deliver that asset (the deposit may be BTC or another asset,
|
|
@@ -203,9 +214,17 @@ interface Offer {
|
|
|
203
214
|
makerPublicKey: Uint8Array;
|
|
204
215
|
/** Covenant co-signer (emulator) x-only key (32 bytes). */
|
|
205
216
|
emulatorPubkey: Uint8Array;
|
|
217
|
+
/** Partial-fill numerator. Reserved wire space in V1: carried through the
|
|
218
|
+
* codec so an offer that sets it decodes, never interpreted here. */
|
|
219
|
+
ratioNum?: bigint;
|
|
220
|
+
/** Partial-fill denominator. Set with {@link Offer.ratioNum} or not at all. */
|
|
221
|
+
ratioDen?: bigint;
|
|
222
|
+
/** The maker's unilateral exit path. Present adds a third closure to the
|
|
223
|
+
* taproot tree, so it changes `swapPkScript` — see {@link offerVtxoScript}. */
|
|
224
|
+
exitDelay?: RelativeTimelock;
|
|
206
225
|
}
|
|
207
226
|
/** Compile the offer's contract: program + args -> taproot tree. */
|
|
208
|
-
declare function
|
|
227
|
+
declare function offerContract(offer: Omit<Offer, "swapPkScript">, operatorPubkey: Uint8Array): InstanceType<typeof arkade.ArkadeProgramScript>;
|
|
209
228
|
/** Extension packet type tag for Arkade Intents offers. */
|
|
210
229
|
declare const OFFER_PACKET_TYPE = 3;
|
|
211
230
|
/** Serialize an offer to TLV bytes (the packet payload). */
|
|
@@ -217,11 +236,11 @@ declare function decodeOffer(data: Uint8Array): Offer;
|
|
|
217
236
|
* you deposit, embedding the returned extension, and the solver does the rest:
|
|
218
237
|
*
|
|
219
238
|
* // BTC -> asset
|
|
220
|
-
* const o = await createOffer(wallet,
|
|
239
|
+
* const o = await createOffer(wallet, { wantAmount: 1000n, wantAsset })
|
|
221
240
|
* await wallet.send({ address: o.address, amount: 1000, extensions: [o.extension] })
|
|
222
241
|
*
|
|
223
242
|
* // asset -> BTC (the sats are the VTXO carrier for the asset)
|
|
224
|
-
* const o = await createOffer(wallet,
|
|
243
|
+
* const o = await createOffer(wallet, { wantAmount: 1000n, offerAsset })
|
|
225
244
|
* await wallet.send({ address: o.address, amount: 500,
|
|
226
245
|
* assets: [{ assetId, amount: 1000n }],
|
|
227
246
|
* extensions: [o.extension] })
|
|
@@ -233,14 +252,28 @@ declare function decodeOffer(data: Uint8Array): Offer;
|
|
|
233
252
|
* funding rather than after: nothing is at stake yet, so a failure can throw
|
|
234
253
|
* and be retried, where the same failure after `wallet.send` would leave a
|
|
235
254
|
* funded deposit unwatched with no way to notice.
|
|
255
|
+
*
|
|
256
|
+
* **The maker's unilateral exit closure is built by default**, at the server's
|
|
257
|
+
* own `unilateralExitDelay` — the same thing solverd does. Without it `cancel`
|
|
258
|
+
* is the only way back out, and `cancel` needs the server's signature: a server
|
|
259
|
+
* that will not co-sign leaves the deposit stuck at the swap address until the
|
|
260
|
+
* VTXO expires and the operator sweeps it. An offer has no expiry of its own,
|
|
261
|
+
* so that exposure has no end. `noExit` opts out for a caller who wants the
|
|
262
|
+
* smaller tree and accepts the dependency.
|
|
236
263
|
*/
|
|
237
|
-
declare function createOffer(wallet: IWallet,
|
|
264
|
+
declare function createOffer(wallet: IWallet, params: {
|
|
238
265
|
wantAmount: bigint;
|
|
239
266
|
wantAsset?: asset.AssetId;
|
|
240
267
|
offerAsset?: asset.AssetId;
|
|
241
268
|
/** Co-signer key override (33-byte compressed hex); see
|
|
242
269
|
* {@link resolveEmulatorPubkey}. */
|
|
243
270
|
emulatorPubkey?: string;
|
|
271
|
+
/** Override the exit closure's delay. Defaults to the server's own
|
|
272
|
+
* `unilateralExitDelay`, which is the delay solverd uses too. */
|
|
273
|
+
exitDelay?: RelativeTimelock;
|
|
274
|
+
/** Publish without the exit closure, leaving `cancel` — which needs the
|
|
275
|
+
* server — as the only way back out. See the note on this function. */
|
|
276
|
+
noExit?: boolean;
|
|
244
277
|
}): Promise<{
|
|
245
278
|
/** The encoded offer, hex. **Persist this** — it is the only input
|
|
246
279
|
* `cancelOffer` needs to rebuild the covenant, and the restore scan reads
|
|
@@ -263,19 +296,23 @@ declare function createOffer(wallet: IWallet, arkServerUrl: string, params: {
|
|
|
263
296
|
/**
|
|
264
297
|
* Cancel an offer: spend the swap VTXO back to the user. Returns the ark txid.
|
|
265
298
|
*
|
|
266
|
-
* This is the refund path — how a user takes back a deposit no
|
|
267
|
-
* **
|
|
268
|
-
* place at the swap address rather than expiring:
|
|
269
|
-
* "expired" state to unwind, at the cost of the refund being something the
|
|
299
|
+
* This is the cooperative refund path — how a user takes back a deposit no
|
|
300
|
+
* solver filled. **No path here is on a deadline**, so an unfilled deposit
|
|
301
|
+
* keeps its place at the swap address rather than expiring: nothing to miss and
|
|
302
|
+
* no "expired" state to unwind, at the cost of the refund being something the
|
|
270
303
|
* user asks for rather than something a clock delivers.
|
|
271
304
|
*
|
|
272
|
-
*
|
|
305
|
+
* The routes out of the covenant are deliberately asymmetric:
|
|
273
306
|
* - `fulfill` is signed by the **server alone**, but the covenant constrains
|
|
274
307
|
* it to pay output 0 to `makerWP` for at least `wantAmount` — a solver
|
|
275
308
|
* cannot take the deposit without delivering.
|
|
276
309
|
* - `cancel` is a **2-of-2 of the user and the server**, so cancelling is
|
|
277
310
|
* cooperative: the server co-signs. No solver signature is involved, so the
|
|
278
311
|
* refund never depends on the counterparty being reachable.
|
|
312
|
+
* - `exit` is the user **alone** after a relative timelock, present unless the
|
|
313
|
+
* offer was created with `noExit`. It is the route that survives a server
|
|
314
|
+
* that will not co-sign this one, and it is reached by unrolling the VTXO
|
|
315
|
+
* onchain rather than through this function.
|
|
279
316
|
*
|
|
280
317
|
* Cancel therefore races a fill rather than pre-empting it. An offer the solver
|
|
281
318
|
* is filling in the same moment may be spent by `fulfill` first, in which case
|
|
@@ -291,8 +328,8 @@ declare function createOffer(wallet: IWallet, arkServerUrl: string, params: {
|
|
|
291
328
|
* Identical offers derive the same address, so `fundingTxid` selects the exact
|
|
292
329
|
* deposit; without it the address must hold exactly one spendable VTXO — with
|
|
293
330
|
* several, cancel refuses to guess and throws.
|
|
294
|
-
* `swapAddress` (the funded address) pins the
|
|
295
|
-
* built with, so cancel keeps working across
|
|
331
|
+
* `swapAddress` (the funded address) pins the operator key the covenant was
|
|
332
|
+
* built with, so cancel keeps working across an operator signer rotation; without
|
|
296
333
|
* it a rotated key is detected and reported rather than reading as a missing
|
|
297
334
|
* VTXO.
|
|
298
335
|
*
|
|
@@ -313,8 +350,13 @@ declare function createOffer(wallet: IWallet, arkServerUrl: string, params: {
|
|
|
313
350
|
* returns, so a spend event that arrives in that window finds a `cancelling`
|
|
314
351
|
* record and classifies the spend by its covenant leaf instead — the same
|
|
315
352
|
* answer, one indexer read more.
|
|
353
|
+
*
|
|
354
|
+
* Takes no server URL, like every other entrypoint here: broadcast comes from
|
|
355
|
+
* `wallet.getArkadeBroadcaster()` and the indexer fallback from
|
|
356
|
+
* `wallet.getArkadeReader()`, so the wallet's own connection is the only one
|
|
357
|
+
* used (#734).
|
|
316
358
|
*/
|
|
317
|
-
declare function cancelOffer(wallet: IWallet,
|
|
359
|
+
declare function cancelOffer(wallet: IWallet, offerHex: string, opts: {
|
|
318
360
|
repository: AssetSwapRepository;
|
|
319
361
|
fundingTxid?: string;
|
|
320
362
|
swapAddress?: string;
|
|
@@ -393,8 +435,7 @@ type PlanError = "insufficient-balance" | "side-disabled" | "below-min" | "above
|
|
|
393
435
|
/** Validate a plan against the user's balance and the server dust limit. */
|
|
394
436
|
declare const validatePlan: (plan: OfferPlan, giveBalance: bigint, dust: bigint) => PlanError | undefined;
|
|
395
437
|
|
|
396
|
-
/** Browser backend over the SDK's shared IndexedDB manager
|
|
397
|
-
* infrastructure the wallet already uses for its Boltz swap repository. */
|
|
438
|
+
/** Browser backend over the SDK's shared IndexedDB manager. */
|
|
398
439
|
declare class IndexedDbAssetSwapRepository implements AssetSwapRepository {
|
|
399
440
|
readonly version: 4;
|
|
400
441
|
private readonly connection;
|
|
@@ -451,10 +492,19 @@ type SpendKind = "cancelled" | "fulfilled" | "indeterminate";
|
|
|
451
492
|
/**
|
|
452
493
|
* Classify a spend by the covenant leaf it took.
|
|
453
494
|
*
|
|
454
|
-
* The
|
|
455
|
-
*
|
|
456
|
-
* each input's `tapLeafScript`, so the spend
|
|
457
|
-
* reads an answer rather than inferring one.
|
|
495
|
+
* The vocabulary is what became of the deposit, not which key moved it:
|
|
496
|
+
* `fulfill` is the solver paying for it, and everything else returns it to the
|
|
497
|
+
* user. A submitted ark tx keeps each input's `tapLeafScript`, so the spend
|
|
498
|
+
* *states* which one it used — this reads an answer rather than inferring one.
|
|
499
|
+
*
|
|
500
|
+
* **`exit` reports `cancelled`, like `cancel` does.** The two differ in who had
|
|
501
|
+
* to agree — `cancel` is cooperative with the signer, `exit` is the maker alone
|
|
502
|
+
* after a delay — but not in outcome: the deposit went back unfilled either
|
|
503
|
+
* way, which is the question this answers. Reporting the exit leaf as
|
|
504
|
+
* `indeterminate` instead would be worse than imprecise: no status is written,
|
|
505
|
+
* so the swap stays `pending`, `restoreAssetSwaps` re-queues it on every scan,
|
|
506
|
+
* and `retireOfferContract` never runs — leaving a dead script in the
|
|
507
|
+
* subscription and the failsafe poll for the life of the wallet.
|
|
458
508
|
*
|
|
459
509
|
* **Hand it the transaction that actually spends the deposit outpoint, which is
|
|
460
510
|
* the checkpoint, not the ark tx.** A spend is two linked transactions: the
|
|
@@ -474,12 +524,12 @@ type SpendKind = "cancelled" | "fulfilled" | "indeterminate";
|
|
|
474
524
|
* and they also survive batching: a solver filling several offers in one tx
|
|
475
525
|
* gives each input its own leaf.
|
|
476
526
|
*
|
|
477
|
-
* `
|
|
527
|
+
* `operatorPubkey` must be the key the covenant was *funded* against. If it has
|
|
478
528
|
* rotated since, the rebuilt script will not match the offer's own
|
|
479
529
|
* `swapPkScript` and this returns `indeterminate` rather than guessing —
|
|
480
530
|
* `cancelOffer` diagnoses the same mismatch the same way.
|
|
481
531
|
*/
|
|
482
|
-
declare function classifySpend(offer: Offer,
|
|
532
|
+
declare function classifySpend(offer: Offer, operatorPubkey: Uint8Array, spendTx: Transaction, deposit: {
|
|
483
533
|
txid: string;
|
|
484
534
|
vout: number;
|
|
485
535
|
}): SpendKind;
|
|
@@ -500,7 +550,7 @@ declare const spendTxidsOf: (vtxo: {
|
|
|
500
550
|
* settlement they may be the same id. Try each and take the first definite
|
|
501
551
|
* answer, so the classification does not depend on that distinction.
|
|
502
552
|
*/
|
|
503
|
-
declare function classifyDepositSpend(offer: Offer,
|
|
553
|
+
declare function classifyDepositSpend(offer: Offer, operatorPubkey: Uint8Array, spendTxs: Iterable<Transaction>, deposit: {
|
|
504
554
|
txid: string;
|
|
505
555
|
vout: number;
|
|
506
556
|
}): SpendKind;
|
|
@@ -525,12 +575,12 @@ declare function classifyDepositSpend(offer: Offer, serverPubkey: Uint8Array, sp
|
|
|
525
575
|
* does, so the `existingIds` escape hatch is no longer a correction mechanism
|
|
526
576
|
* for a wrong label — it is only a skip list.
|
|
527
577
|
*
|
|
528
|
-
* `
|
|
578
|
+
* `operatorPubkey` must be the operator key the covenants were funded against; a
|
|
529
579
|
* key that has rotated since makes every affected swap unclassifiable rather
|
|
530
580
|
* than misclassified.
|
|
531
581
|
*/
|
|
532
582
|
declare function restoreAssetSwaps(indexer: RestoreIndexer, txs: Tx[], existingIds: ReadonlySet<string>, opts: {
|
|
533
|
-
|
|
583
|
+
operatorPubkey: Uint8Array;
|
|
534
584
|
scanned?: ReadonlySet<string>;
|
|
535
585
|
}): Promise<{
|
|
536
586
|
restored: AssetSwap[];
|
|
@@ -558,9 +608,6 @@ interface OfferSwapWatcher {
|
|
|
558
608
|
}
|
|
559
609
|
interface WatchOfferSwapsParams {
|
|
560
610
|
wallet: IWallet;
|
|
561
|
-
/** Same URL `createOffer`/`cancelOffer` take; used to read a spending tx
|
|
562
|
-
* when the exact classifier cannot answer. */
|
|
563
|
-
arkServerUrl: string;
|
|
564
611
|
repository: AssetSwapRepository;
|
|
565
612
|
/** Called after a change is persisted. A notification, not a store. */
|
|
566
613
|
onUpdate?: (swap: AssetSwap) => void;
|
|
@@ -576,7 +623,7 @@ interface WatchOfferSwapsParams {
|
|
|
576
623
|
* provide an `EventSource` implementation or use a runtime where it is enabled;
|
|
577
624
|
* otherwise live updates do not arrive and restore remains the fallback.
|
|
578
625
|
*/
|
|
579
|
-
declare function watchOfferSwaps({ wallet,
|
|
626
|
+
declare function watchOfferSwaps({ wallet, repository, onUpdate, }: WatchOfferSwapsParams): Promise<OfferSwapWatcher>;
|
|
580
627
|
|
|
581
628
|
/**
|
|
582
629
|
* Coverage: whether an offer's script is in the wallet's watched set.
|
|
@@ -644,8 +691,6 @@ interface ClaimPacketInput {
|
|
|
644
691
|
*/
|
|
645
692
|
declare function sealClaimPacket(input: ClaimPacketInput): Promise<SealedClaimPacket>;
|
|
646
693
|
|
|
647
|
-
/** The Ark surface the claim push needs — the same seam the refund push uses. */
|
|
648
|
-
type ClaimArkProvider = RefundArkProvider;
|
|
649
694
|
/**
|
|
650
695
|
* The lockup is funded for less than the swap agreed.
|
|
651
696
|
*
|
|
@@ -688,9 +733,9 @@ declare class LockupAmountMismatchError extends Error {
|
|
|
688
733
|
* server at submit — but it turns "reported claimed, nothing landed, the
|
|
689
734
|
* solver refunds hours later" into an immediate failure.
|
|
690
735
|
*/
|
|
691
|
-
declare function pushClaim(
|
|
692
|
-
/** The receive-direction covenant (see `
|
|
693
|
-
|
|
736
|
+
declare function pushClaim(operator: SwapOperator, input: {
|
|
737
|
+
/** The receive-direction covenant (see `lightningReceiveContract`). */
|
|
738
|
+
contract: InstanceType<typeof VHTLC.ScriptV2>;
|
|
694
739
|
/** The trader's `receiver` signer. Build it from the swap's `secrets`
|
|
695
740
|
* with `contractSigner` — on an HD wallet that resolves
|
|
696
741
|
* from the seed, with no stored key bytes anywhere. */
|
|
@@ -710,7 +755,7 @@ declare function pushClaim(ark: ClaimArkProvider, input: {
|
|
|
710
755
|
* the remainder. */
|
|
711
756
|
partiallyClaimed?: boolean;
|
|
712
757
|
}): Promise<{
|
|
713
|
-
|
|
758
|
+
txid: string;
|
|
714
759
|
amount: number;
|
|
715
760
|
}>;
|
|
716
761
|
/**
|
|
@@ -737,13 +782,13 @@ declare function awaitLockupFunding(indexer: RefundIndexer, swapPkScript: Uint8A
|
|
|
737
782
|
* rest lands is safe — and that is also the answer to a genuinely underfunded
|
|
738
783
|
* lockup, which never gets past the gate at all.
|
|
739
784
|
*/
|
|
740
|
-
declare function claimReceiveLockup(indexer: RefundIndexer,
|
|
785
|
+
declare function claimReceiveLockup(indexer: RefundIndexer, operator: SwapOperator, input: Parameters<typeof pushClaim>[1] & {
|
|
741
786
|
/** The covenant's scriptPubKey, from the request flow's `swapPkScript`. */
|
|
742
787
|
swapPkScript: Uint8Array;
|
|
743
788
|
pollMs?: number;
|
|
744
789
|
deadline?: number;
|
|
745
790
|
}): Promise<{
|
|
746
|
-
|
|
791
|
+
txid: string;
|
|
747
792
|
amount: number;
|
|
748
793
|
}>;
|
|
749
794
|
|
|
@@ -810,7 +855,7 @@ declare function senderIdentityForSwapRecord(wallet: IWallet, record: {
|
|
|
810
855
|
*/
|
|
811
856
|
|
|
812
857
|
interface ArkadeRefunderDeps {
|
|
813
|
-
|
|
858
|
+
operator: SwapOperator;
|
|
814
859
|
indexer: RefundIndexer;
|
|
815
860
|
/** Asked for the descriptor's signer; never asked to mint a key. */
|
|
816
861
|
wallet: IWallet;
|
|
@@ -826,7 +871,7 @@ interface ArkadeRefunderDeps {
|
|
|
826
871
|
*
|
|
827
872
|
* @example
|
|
828
873
|
* manager.setCallbacks({
|
|
829
|
-
* refundArkade: arkadeRefunder({
|
|
874
|
+
* refundArkade: arkadeRefunder({ operator, indexer, wallet, repository }),
|
|
830
875
|
* saveSwap,
|
|
831
876
|
* });
|
|
832
877
|
*/
|
|
@@ -954,7 +999,7 @@ interface RfqSwapActivityDeps {
|
|
|
954
999
|
repository: Pick<AssetSwapRepository, "getAllRfqSwaps">;
|
|
955
1000
|
/**
|
|
956
1001
|
* Consulted only for what a record cannot answer: a record written before
|
|
957
|
-
* `
|
|
1002
|
+
* `fundingTxid` existed, and the counterparty's spend on a swap that
|
|
958
1003
|
* ended without a refund of ours.
|
|
959
1004
|
*
|
|
960
1005
|
* Optional because the stored fields are the primary source — cheaper, and
|
|
@@ -968,7 +1013,7 @@ interface RfqSwapActivityDeps {
|
|
|
968
1013
|
* groups on.
|
|
969
1014
|
*
|
|
970
1015
|
* The txids come from four places, in order of preference: the record's own
|
|
971
|
-
* `
|
|
1016
|
+
* `fundingTxid` and `refundTxid`, the corridor's `activityTxids` (the
|
|
972
1017
|
* receive leg's Arkade claim, the onchain leg's L1 one), and — only when the
|
|
973
1018
|
* first two cannot answer — one read of the lockup's VTXOs.
|
|
974
1019
|
*
|
|
@@ -978,4 +1023,96 @@ interface RfqSwapActivityDeps {
|
|
|
978
1023
|
*/
|
|
979
1024
|
declare function rfqSwapActivityInputs(deps: RfqSwapActivityDeps): Promise<SwapActivityInput[]>;
|
|
980
1025
|
|
|
981
|
-
|
|
1026
|
+
interface SwapQuoteInput {
|
|
1027
|
+
/** Which side of the market the trader deposits. */
|
|
1028
|
+
give: "base" | "quote";
|
|
1029
|
+
/** Size on the named side ("give" = exact-in, "receive" = exact-out).
|
|
1030
|
+
* Spot: display string or atomic bigint; corridors: sats. A lightning
|
|
1031
|
+
* send takes its amount from the invoice instead. */
|
|
1032
|
+
amount?: string | number | bigint;
|
|
1033
|
+
amountOn?: "give" | "receive";
|
|
1034
|
+
/** Required when the receive side is lightning. */
|
|
1035
|
+
invoice?: InvoiceFacts;
|
|
1036
|
+
/** Trader's x-only L1 claim key; required when the receive side is onchain. */
|
|
1037
|
+
payoutPubkey?: Uint8Array;
|
|
1038
|
+
preimage?: Uint8Array;
|
|
1039
|
+
maxPayAmount?: number;
|
|
1040
|
+
}
|
|
1041
|
+
interface SpotQuote {
|
|
1042
|
+
kind: "spot";
|
|
1043
|
+
market: DiscoveredMarket;
|
|
1044
|
+
plan: OfferPlan;
|
|
1045
|
+
}
|
|
1046
|
+
interface LightningSendQuote {
|
|
1047
|
+
kind: "ln_send";
|
|
1048
|
+
market: DiscoveredMarket;
|
|
1049
|
+
request: Awaited<ReturnType<typeof requestLightningSend>>;
|
|
1050
|
+
}
|
|
1051
|
+
interface LightningReceiveQuote {
|
|
1052
|
+
kind: "ln_receive";
|
|
1053
|
+
market: DiscoveredMarket;
|
|
1054
|
+
request: Awaited<ReturnType<typeof requestLightningReceive>>;
|
|
1055
|
+
/** The solver's hold invoice, for the payer. */
|
|
1056
|
+
invoice: string;
|
|
1057
|
+
}
|
|
1058
|
+
interface OnchainSendQuote {
|
|
1059
|
+
kind: "onchain_send";
|
|
1060
|
+
market: DiscoveredMarket;
|
|
1061
|
+
request: Awaited<ReturnType<typeof requestOnchainSend>>;
|
|
1062
|
+
}
|
|
1063
|
+
type SwapQuote = SpotQuote | LightningSendQuote | LightningReceiveQuote | OnchainSendQuote;
|
|
1064
|
+
type UnifiedSwap = {
|
|
1065
|
+
family: "offer";
|
|
1066
|
+
swap: AssetSwap;
|
|
1067
|
+
} | {
|
|
1068
|
+
family: "rfq";
|
|
1069
|
+
swap: RfqSwap;
|
|
1070
|
+
};
|
|
1071
|
+
interface SwapClientDeps {
|
|
1072
|
+
/** The server connection too: every provider below defaults to this
|
|
1073
|
+
* wallet's own, so no server URL is passed in (arkade-os/ts-sdk#734). */
|
|
1074
|
+
wallet: IWallet;
|
|
1075
|
+
repository: AssetSwapRepository;
|
|
1076
|
+
/** The rendezvous for a corridor market; never called for a spot one.
|
|
1077
|
+
*
|
|
1078
|
+
* The market's own `base_corridor`/`quote_corridor` are what route a swap
|
|
1079
|
+
* here rather than to the offer path, so whoever publishes the market
|
|
1080
|
+
* chooses which backend you are asked to open a transport to. Resolve one
|
|
1081
|
+
* only for markets from an index you trust — this client does not, and
|
|
1082
|
+
* cannot, check that a market named a corridor honestly. */
|
|
1083
|
+
transportFor: (market: DiscoveredMarket) => RfqTransport;
|
|
1084
|
+
discovery: Omit<DiscoverMarketsOptions, "repository">;
|
|
1085
|
+
/** BOLT11 decoder for the solver's hold invoice; required to quote lightning receives. */
|
|
1086
|
+
decodeInvoice?: (bolt11: string) => InvoiceFacts;
|
|
1087
|
+
/** covclaimd's 33-byte compressed pubkey — the lightning-receive claim
|
|
1088
|
+
* packet seals to it; required to quote lightning receives. */
|
|
1089
|
+
covclaimdPubkey?: Uint8Array;
|
|
1090
|
+
/** L1 access; required to quote onchain sends. */
|
|
1091
|
+
chain?: ChainSource;
|
|
1092
|
+
/** L1 claim callback (fee rate and signing are environment-specific);
|
|
1093
|
+
* without it the manager reports onchain claims as blocked. */
|
|
1094
|
+
claimOnchain?: RfqSwapManagerCallbacks["claimOnchain"];
|
|
1095
|
+
emulatorPubkey?: string;
|
|
1096
|
+
/** Overrides the wallet's own connection; for tests and for a caller that
|
|
1097
|
+
* must reach a different operator. */
|
|
1098
|
+
ark?: SwapOperator;
|
|
1099
|
+
indexer?: LockupSpendIndexer;
|
|
1100
|
+
}
|
|
1101
|
+
interface SwapClient {
|
|
1102
|
+
markets(useCache?: boolean): Promise<DiscoveredMarket[]>;
|
|
1103
|
+
quote(market: DiscoveredMarket, input: SwapQuoteInput): Promise<SwapQuote>;
|
|
1104
|
+
accept(quote: SwapQuote): Promise<UnifiedSwap>;
|
|
1105
|
+
/** Spot only: the covenant's cooperative reclaim. */
|
|
1106
|
+
cancel(fundingTxid: string): Promise<void>;
|
|
1107
|
+
/** Every swap this client knows of, both families and both live and ended
|
|
1108
|
+
* — not a live-only view. The RFQ half is bounded by what the manager has
|
|
1109
|
+
* loaded and by `RFQ_SWAP_RETENTION_SECONDS`. */
|
|
1110
|
+
swaps(): Promise<UnifiedSwap[]>;
|
|
1111
|
+
onUpdate(listener: (swap: UnifiedSwap) => void): () => void;
|
|
1112
|
+
start(): Promise<void>;
|
|
1113
|
+
stop(): Promise<void>;
|
|
1114
|
+
readonly manager: RfqSwapManager;
|
|
1115
|
+
}
|
|
1116
|
+
declare function createSwapClient(deps: SwapClientDeps): SwapClient;
|
|
1117
|
+
|
|
1118
|
+
export { ArkadeRefundResult, type ArkadeRefunderDeps, AssetSwap, AssetSwapRepository, ChainSource, type ClaimPacketInput, type DiscoverMarketsOptions, IndexedDbAssetSwapRepository, InvoiceFacts, type LightningReceiveProfile, type LightningReceiveQuote, type LightningSendProfile, type LightningSendQuote, LockupAmountMismatchError, LockupContractMissing, type LockupContractReader, type LockupContractWriter, LockupRegistrationFailed, LockupSpendIndexer, LockupVtxo, MarketsCacheEntry, OFFER_PACKET_TYPE, type Offer, type OfferContractRetirer, type OfferSwapWatcher, OnchainHtlc, OnchainHtlcParams, OnchainNetwork, type OnchainSendProfile, type OnchainSendQuote, type PlanError, QUOTE_OPTIONS, type RefundBlockedReason, RefundIndexer, RefundNotLocallyPossibleError, type RestoreIndexer, type RfqClaimSecretProjection, type RfqHashlockProjection, type RfqSignerProjection, RfqSwap, type RfqSwapActivityDeps, RfqSwapManager, RfqSwapManagerCallbacks, RfqSwapRecord, RfqSwapState, RfqTransport, SWAP_LOCKUP_CONTRACT_KIND, SWAP_LOCKUP_CONTRACT_LABEL, SWAP_LOCKUP_CONTRACT_TYPE, type SealedClaimPacket, type SpendKind, type SpotQuote, type SwapActivityInput, type SwapClient, type SwapClientDeps, SwapOperator, type SwapQuote, type SwapQuoteInput, SwapSecretsProjection, type Tx, type UnifiedSwap, type WatchOfferSwapsParams, arkadeRefunder, awaitLockupFunding, cancelOffer, claimReceiveLockup, classifyDepositSpend, classifySpend, createOffer, createSwapClient, decodeOffer, discoverMarkets, encodeOffer, findMarket, lockupContractParams, makeCachedFeedFetch, offerContract, onchainSendProfile, pushClaim, registerLockupContract, requestLightningReceive, requestLightningSend, requestOnchainSend, restoreAssetSwaps, retireSettledOfferContracts, rfqClaimSecretOf, rfqSecretsProfile, rfqSignerOf, rfqSwapActivityInputs, sealClaimPacket, senderIdentityForSwapRecord, spendTxidsOf, spendUpdate, swapActivityResolver, swapPrograms, validatePlan, watchOfferSwaps };
|