@arkade-os/boltz-swap 0.3.0 → 0.3.2

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.
@@ -36,8 +36,11 @@ var init_errors = __esm({
36
36
  "src/errors.ts"() {
37
37
  "use strict";
38
38
  SwapError = class extends Error {
39
+ /** Whether the swap can still be claimed (default: false). */
39
40
  isClaimable;
41
+ /** Whether the swap can be refunded (default: false). */
40
42
  isRefundable;
43
+ /** The pending swap associated with this error, if available. */
41
44
  pendingSwap;
42
45
  constructor(options = {}) {
43
46
  super(options.message ?? "Error during swap.");
@@ -63,7 +66,9 @@ var init_errors = __esm({
63
66
  }
64
67
  };
65
68
  NetworkError = class extends Error {
69
+ /** HTTP status code from the failed request, if available. */
66
70
  statusCode;
71
+ /** Raw error payload from the Boltz API, if available. */
67
72
  errorData;
68
73
  constructor(message, statusCode, errorData) {
69
74
  super(message);
@@ -106,7 +111,7 @@ var init_errors = __esm({
106
111
  });
107
112
 
108
113
  // src/boltz-swap-provider.ts
109
- var import_sdk, import_base, isSubmarineFinalStatus, isSubmarineRefundableStatus, isReverseFinalStatus, isReverseClaimableStatus, isChainClaimableStatus, isChainFinalStatus, isChainRefundableStatus, isChainSignableStatus, isPendingReverseSwap, isPendingSubmarineSwap, isPendingChainSwap, isSubmarineSwapRefundable, isTimeoutBlockHeights, isGetReverseSwapTxIdResponse, isGetSwapStatusResponse, isGetSubmarinePairsResponse, isGetReversePairsResponse, isCreateSubmarineSwapResponse, isGetSwapPreimageResponse, isCreateReverseSwapResponse, isRefundSubmarineSwapResponse, isRefundChainSwapResponse, isGetChainPairsResponse, isSwapTree, isChainSwapDetailsResponse, isCreateChainSwapResponse, isGetChainClaimDetailsResponse, isPostChainClaimDetailsResponse, isGetChainQuoteResponse, isPostChainQuoteResponse, isPostBtcTransactionResponse, isLeaf, isTree, isDetails, isRestoredSubmarineSwap, isRestoredReverseSwap, isCreateSwapsRestoreResponse, BASE_URLS, BoltzSwapProvider;
114
+ var import_sdk, import_base, isSubmarineFinalStatus, isSubmarineRefundableStatus, isReverseFinalStatus, isReverseClaimableStatus, isChainClaimableStatus, isChainFinalStatus, isChainRefundableStatus, isChainSignableStatus, isPendingReverseSwap, isPendingSubmarineSwap, isPendingChainSwap, isSubmarineSwapRefundable, isTimeoutBlockHeights, isGetReverseSwapTxIdResponse, isGetSwapStatusResponse, isGetSubmarinePairsResponse, isGetReversePairsResponse, isCreateSubmarineSwapResponse, isGetSwapPreimageResponse, isCreateReverseSwapResponse, isRefundSubmarineSwapResponse, isRefundChainSwapResponse, isGetChainPairsResponse, isSwapTree, isChainSwapDetailsResponse, isCreateChainSwapResponse, isGetChainClaimDetailsResponse, isPostChainClaimDetailsResponse, isGetChainQuoteResponse, isPostChainQuoteResponse, isPostBtcTransactionResponse, isLeaf, isTree, isDetails, isRestoredChainSwap, isRestoredSubmarineSwap, isRestoredReverseSwap, isCreateSwapsRestoreResponse, BASE_URLS, BoltzSwapProvider;
110
115
  var init_boltz_swap_provider = __esm({
111
116
  "src/boltz-swap-provider.ts"() {
112
117
  "use strict";
@@ -236,7 +241,10 @@ var init_boltz_swap_provider = __esm({
236
241
  return data && typeof data === "object" && isLeaf(data.claimLeaf) && isLeaf(data.refundLeaf) && isLeaf(data.refundWithoutBoltzLeaf) && isLeaf(data.unilateralClaimLeaf) && isLeaf(data.unilateralRefundLeaf) && isLeaf(data.unilateralRefundWithoutBoltzLeaf);
237
242
  };
238
243
  isDetails = (data) => {
239
- return data && typeof data === "object" && isTree(data.tree) && (data.amount === void 0 || typeof data.amount === "number") && typeof data.keyIndex === "number" && (data.transaction === void 0 || data.transaction && typeof data.transaction === "object" && typeof data.transaction.id === "string" && typeof data.transaction.vout === "number") && typeof data.lockupAddress === "string" && typeof data.serverPublicKey === "string" && typeof data.timeoutBlockHeight === "number" && isTimeoutBlockHeights(data.timeoutBlockHeights) && (data.preimageHash === void 0 || typeof data.preimageHash === "string");
244
+ return data && typeof data === "object" && isTree(data.tree) && (data.amount === void 0 || typeof data.amount === "number") && typeof data.keyIndex === "number" && (data.transaction === void 0 || data.transaction && typeof data.transaction === "object" && typeof data.transaction.id === "string" && typeof data.transaction.vout === "number") && typeof data.lockupAddress === "string" && typeof data.serverPublicKey === "string" && typeof data.timeoutBlockHeight === "number" && (data.timeoutBlockHeights === void 0 || isTimeoutBlockHeights(data.timeoutBlockHeights)) && (data.preimageHash === void 0 || typeof data.preimageHash === "string");
245
+ };
246
+ isRestoredChainSwap = (data) => {
247
+ return data && typeof data === "object" && typeof data.id === "string" && data.type === "chain" && typeof data.status === "string" && typeof data.createdAt === "number" && (data.from === "ARK" || data.from === "BTC") && (data.to === "ARK" || data.to === "BTC") && typeof data.preimageHash === "string" && data.refundDetails && typeof data.refundDetails === "object" && isTree(data.refundDetails.tree) && typeof data.refundDetails.amount === "number" && typeof data.refundDetails.keyIndex === "number" && (data.refundDetails.transaction === void 0 || data.refundDetails.transaction && typeof data.refundDetails.transaction === "object" && typeof data.refundDetails.transaction.id === "string" && typeof data.refundDetails.transaction.vout === "number") && typeof data.refundDetails.lockupAddress === "string" && typeof data.refundDetails.serverPublicKey === "string" && typeof data.refundDetails.timeoutBlockHeight === "number";
240
248
  };
241
249
  isRestoredSubmarineSwap = (data) => {
242
250
  return data && typeof data === "object" && data.to === "BTC" && typeof data.id === "string" && data.from === "ARK" && data.type === "submarine" && typeof data.createdAt === "number" && typeof data.preimageHash === "string" && typeof data.status === "string" && isDetails(data.refundDetails);
@@ -246,10 +254,11 @@ var init_boltz_swap_provider = __esm({
246
254
  };
247
255
  isCreateSwapsRestoreResponse = (data) => {
248
256
  return Array.isArray(data) && data.every(
249
- (item) => isRestoredReverseSwap(item) || isRestoredSubmarineSwap(item)
257
+ (item) => isRestoredChainSwap(item) || isRestoredReverseSwap(item) || isRestoredSubmarineSwap(item)
250
258
  );
251
259
  };
252
260
  BASE_URLS = {
261
+ bitcoin: "https://api.ark.boltz.exchange",
253
262
  mutinynet: "https://api.boltz.mutinynet.arkade.sh",
254
263
  regtest: "http://localhost:9069"
255
264
  };
@@ -258,6 +267,7 @@ var init_boltz_swap_provider = __esm({
258
267
  apiUrl;
259
268
  network;
260
269
  referralId;
270
+ /** @param config Provider configuration with network and optional API URL. */
261
271
  constructor(config) {
262
272
  this.network = config.network;
263
273
  this.referralId = config.referralId;
@@ -269,15 +279,19 @@ var init_boltz_swap_provider = __esm({
269
279
  this.apiUrl = apiUrl;
270
280
  this.wsUrl = this.apiUrl.replace(/^http(s)?:\/\//, "ws$1://").replace("9069", "9004") + "/v2/ws";
271
281
  }
282
+ /** Returns the Boltz API base URL. */
272
283
  getApiUrl() {
273
284
  return this.apiUrl;
274
285
  }
286
+ /** Returns the Boltz WebSocket URL (derived from apiUrl). */
275
287
  getWsUrl() {
276
288
  return this.wsUrl;
277
289
  }
290
+ /** Returns the configured network. */
278
291
  getNetwork() {
279
292
  return this.network;
280
293
  }
294
+ /** Returns current Lightning swap fees (submarine + reverse) from Boltz. */
281
295
  async getFees() {
282
296
  const [submarine, reverse] = await Promise.all([
283
297
  this.request(
@@ -301,6 +315,7 @@ var init_boltz_swap_provider = __esm({
301
315
  }
302
316
  };
303
317
  }
318
+ /** Returns current Lightning swap min/max limits from Boltz. */
304
319
  async getLimits() {
305
320
  const response = await this.request(
306
321
  "/v2/swap/submarine",
@@ -313,6 +328,7 @@ var init_boltz_swap_provider = __esm({
313
328
  max: response.ARK.BTC.limits.maximal
314
329
  };
315
330
  }
331
+ /** Gets the lockup transaction ID for a reverse swap. */
316
332
  async getReverseSwapTxId(id) {
317
333
  const res = await this.request(
318
334
  `/v2/swap/reverse/${id}/transaction`,
@@ -324,6 +340,7 @@ var init_boltz_swap_provider = __esm({
324
340
  });
325
341
  return res;
326
342
  }
343
+ /** Queries the current status of a swap by ID. */
327
344
  async getSwapStatus(id) {
328
345
  const response = await this.request(
329
346
  `/v2/swap/${id}`,
@@ -335,6 +352,7 @@ var init_boltz_swap_provider = __esm({
335
352
  });
336
353
  return response;
337
354
  }
355
+ /** Gets the preimage for a settled submarine swap (proof of payment). */
338
356
  async getSwapPreimage(id) {
339
357
  const res = await this.request(
340
358
  `/v2/swap/submarine/${id}/preimage`,
@@ -346,6 +364,7 @@ var init_boltz_swap_provider = __esm({
346
364
  });
347
365
  return res;
348
366
  }
367
+ /** Creates a submarine swap (Arkade → Lightning) on Boltz. */
349
368
  async createSubmarineSwap({
350
369
  invoice,
351
370
  refundPublicKey
@@ -371,6 +390,7 @@ var init_boltz_swap_provider = __esm({
371
390
  throw new SchemaError({ message: "Error creating submarine swap" });
372
391
  return response;
373
392
  }
393
+ /** Creates a reverse swap (Lightning → Arkade) on Boltz. */
374
394
  async createReverseSwap({
375
395
  invoiceAmount,
376
396
  claimPublicKey,
@@ -400,6 +420,7 @@ var init_boltz_swap_provider = __esm({
400
420
  throw new SchemaError({ message: "Error creating reverse swap" });
401
421
  return response;
402
422
  }
423
+ /** Creates a chain swap (ARK ↔ BTC) on Boltz. */
403
424
  async createChainSwap({
404
425
  to,
405
426
  from,
@@ -458,6 +479,7 @@ var init_boltz_swap_provider = __esm({
458
479
  throw new SchemaError({ message: "Error creating chain swap" });
459
480
  return response;
460
481
  }
482
+ /** Requests Boltz co-signature for a submarine swap refund. Returns signed transaction + checkpoint. */
461
483
  async refundSubmarineSwap(swapId, transaction, checkpoint) {
462
484
  const requestBody = {
463
485
  checkpoint: import_base.base64.encode(checkpoint.toPSBT()),
@@ -481,6 +503,7 @@ var init_boltz_swap_provider = __esm({
481
503
  )
482
504
  };
483
505
  }
506
+ /** Requests Boltz co-signature for a chain swap refund. Returns signed transaction + checkpoint. */
484
507
  async refundChainSwap(swapId, transaction, checkpoint) {
485
508
  const requestBody = {
486
509
  checkpoint: import_base.base64.encode(checkpoint.toPSBT()),
@@ -504,6 +527,7 @@ var init_boltz_swap_provider = __esm({
504
527
  )
505
528
  };
506
529
  }
530
+ /** Monitors swap status updates via WebSocket. Calls update callback on each status change. Resolves when terminal. */
507
531
  async monitorSwap(swapId, update) {
508
532
  return new Promise((resolve, reject) => {
509
533
  const webSocket = new globalThis.WebSocket(this.wsUrl);
@@ -571,6 +595,7 @@ var init_boltz_swap_provider = __esm({
571
595
  };
572
596
  });
573
597
  }
598
+ /** Returns current chain swap fees for a given pair (e.g. ARK→BTC). */
574
599
  async getChainFees(from, to) {
575
600
  if (from === to) {
576
601
  throw new SwapError({ message: "Invalid chain pair" });
@@ -588,6 +613,7 @@ var init_boltz_swap_provider = __esm({
588
613
  }
589
614
  return response[from][to].fees;
590
615
  }
616
+ /** Returns current chain swap min/max limits for a given pair. */
591
617
  async getChainLimits(from, to) {
592
618
  if (from === to) {
593
619
  throw new SwapError({ message: "Invalid chain pair" });
@@ -608,6 +634,7 @@ var init_boltz_swap_provider = __esm({
608
634
  max: response[from][to].limits.maximal
609
635
  };
610
636
  }
637
+ /** Gets claim details (pubNonce, publicKey, transactionHash) for cooperative chain swap claiming. */
611
638
  async getChainClaimDetails(swapId) {
612
639
  const response = await this.request(
613
640
  `/v2/swap/chain/${swapId}/claim`,
@@ -619,6 +646,7 @@ var init_boltz_swap_provider = __esm({
619
646
  });
620
647
  return response;
621
648
  }
649
+ /** Gets a renegotiated quote for a chain swap when lockup amount differs from expected. */
622
650
  async getChainQuote(swapId) {
623
651
  const response = await this.request(
624
652
  `/v2/swap/chain/${swapId}/quote`,
@@ -630,6 +658,7 @@ var init_boltz_swap_provider = __esm({
630
658
  });
631
659
  return response;
632
660
  }
661
+ /** Accepts a renegotiated quote amount for a chain swap. */
633
662
  async postChainQuote(swapId, request) {
634
663
  const response = await this.request(
635
664
  `/v2/swap/chain/${swapId}/quote`,
@@ -642,6 +671,7 @@ var init_boltz_swap_provider = __esm({
642
671
  });
643
672
  return response;
644
673
  }
674
+ /** Broadcasts a raw BTC transaction through Boltz. */
645
675
  async postBtcTransaction(hex9) {
646
676
  const requestBody = { hex: hex9 };
647
677
  const response = await this.request(
@@ -655,6 +685,7 @@ var init_boltz_swap_provider = __esm({
655
685
  });
656
686
  return response;
657
687
  }
688
+ /** Posts claim details (preimage + signing data) or cooperative signature for a chain swap. */
658
689
  async postChainClaimDetails(swapId, request) {
659
690
  const response = await this.request(
660
691
  `/v2/swap/chain/${swapId}/claim`,
@@ -667,6 +698,7 @@ var init_boltz_swap_provider = __esm({
667
698
  });
668
699
  return response;
669
700
  }
701
+ /** Restores swaps from Boltz API using the wallet's public key. */
670
702
  async restoreSwaps(publicKey) {
671
703
  const requestBody = {
672
704
  publicKey
@@ -2804,24 +2836,61 @@ var init_arkade_swaps = __esm({
2804
2836
  init_swap_repository();
2805
2837
  init_identity();
2806
2838
  init_vhtlc();
2807
- ArkadeSwaps = class {
2839
+ ArkadeSwaps = class _ArkadeSwaps {
2840
+ /** The Arkade wallet instance used for signing and address generation. */
2808
2841
  wallet;
2842
+ /** Provider for Ark protocol operations (VTXO management, batch joining). */
2809
2843
  arkProvider;
2844
+ /** Boltz API client for creating and monitoring swaps. */
2810
2845
  swapProvider;
2846
+ /** Provider for querying VTXO state on the Ark indexer. */
2811
2847
  indexerProvider;
2848
+ /** Background swap monitor, or null if not enabled. */
2812
2849
  swapManager = null;
2850
+ /** Storage backend for persisting swap data. */
2813
2851
  swapRepository;
2852
+ /**
2853
+ * Creates an ArkadeSwaps instance, auto-detecting the network from the wallet's Ark server.
2854
+ * If no `swapProvider` is given, one is created automatically using the detected network.
2855
+ *
2856
+ * This is the recommended way to initialize ArkadeSwaps.
2857
+ *
2858
+ * @param config - Configuration options. swapProvider is auto-created from the wallet's network if omitted.
2859
+ * @returns A fully initialized ArkadeSwaps instance.
2860
+ *
2861
+ * @example
2862
+ * ```ts
2863
+ * const swaps = await ArkadeSwaps.create({
2864
+ * wallet,
2865
+ * swapManager: true,
2866
+ * });
2867
+ * ```
2868
+ */
2869
+ static async create(config) {
2870
+ if (config.swapProvider) {
2871
+ return new _ArkadeSwaps(config);
2872
+ }
2873
+ const arkProvider = config.arkProvider ?? config.wallet.arkProvider;
2874
+ if (!arkProvider)
2875
+ throw new Error(
2876
+ "Ark provider is required either in wallet or config."
2877
+ );
2878
+ const arkInfo = await arkProvider.getInfo();
2879
+ const network = arkInfo.network;
2880
+ const swapProvider = new BoltzSwapProvider({ network });
2881
+ return new _ArkadeSwaps({ ...config, swapProvider });
2882
+ }
2814
2883
  constructor(config) {
2815
2884
  if (!config.wallet) throw new Error("Wallet is required.");
2816
2885
  if (!config.swapProvider) throw new Error("Swap provider is required.");
2817
2886
  this.wallet = config.wallet;
2818
- const arkProvider = config.wallet.arkProvider ?? config.arkProvider;
2887
+ const arkProvider = config.arkProvider ?? config.wallet.arkProvider;
2819
2888
  if (!arkProvider)
2820
2889
  throw new Error(
2821
2890
  "Ark provider is required either in wallet or config."
2822
2891
  );
2823
2892
  this.arkProvider = arkProvider;
2824
- const indexerProvider = config.wallet.indexerProvider ?? config.indexerProvider;
2893
+ const indexerProvider = config.indexerProvider ?? config.wallet.indexerProvider;
2825
2894
  if (!indexerProvider)
2826
2895
  throw new Error(
2827
2896
  "Indexer provider is required either in wallet or config."
@@ -2833,8 +2902,8 @@ var init_arkade_swaps = __esm({
2833
2902
  } else {
2834
2903
  this.swapRepository = new IndexedDbSwapRepository();
2835
2904
  }
2836
- if (config.swapManager) {
2837
- const swapManagerConfig = config.swapManager === true ? {} : config.swapManager;
2905
+ if (config.swapManager !== false) {
2906
+ const swapManagerConfig = !config.swapManager || config.swapManager === true ? {} : config.swapManager;
2838
2907
  const shouldAutostart = swapManagerConfig.autoStart ?? true;
2839
2908
  this.swapManager = new SwapManager(
2840
2909
  this.swapProvider,
@@ -2951,9 +3020,11 @@ var init_arkade_swaps = __esm({
2951
3020
  // Lightning: Reverse swaps (receive Lightning -> Arkade)
2952
3021
  // =========================================================================
2953
3022
  /**
2954
- * Creates a Lightning invoice.
2955
- * @param args - The arguments for creating a Lightning invoice.
2956
- * @returns The response containing the created Lightning invoice.
3023
+ * Creates a Lightning invoice via a reverse swap (Lightning → Arkade).
3024
+ * @param args.amount - Invoice amount in satoshis.
3025
+ * @param args.description - Optional description for the BOLT11 invoice.
3026
+ * @returns Object containing the BOLT11 invoice, payment hash, preimage, and pending swap for monitoring.
3027
+ * @throws {SwapError} If amount is <= 0 or wallet key retrieval fails.
2957
3028
  */
2958
3029
  async createLightningInvoice(args) {
2959
3030
  const pendingSwap = await this.createReverseSwap(args);
@@ -2968,9 +3039,11 @@ var init_arkade_swaps = __esm({
2968
3039
  };
2969
3040
  }
2970
3041
  /**
2971
- * Creates a reverse swap.
2972
- * @param args - The arguments for creating a reverse swap.
2973
- * @returns The created pending reverse swap.
3042
+ * Creates a reverse swap (Lightning → Arkade) and saves it to storage.
3043
+ * @param args.amount - Amount in satoshis for the reverse swap.
3044
+ * @param args.description - Optional invoice description.
3045
+ * @returns The pending reverse swap, added to SwapManager if enabled.
3046
+ * @throws {SwapError} If amount is <= 0 or key retrieval fails.
2974
3047
  */
2975
3048
  async createReverseSwap(args) {
2976
3049
  if (args.amount <= 0)
@@ -3009,8 +3082,9 @@ var init_arkade_swaps = __esm({
3009
3082
  return pendingSwap;
3010
3083
  }
3011
3084
  /**
3012
- * Claims the VHTLC for a pending reverse swap.
3013
- * @param pendingSwap - The pending reverse swap to claim the VHTLC.
3085
+ * Claims the VHTLC for a pending reverse swap, transferring locked funds to the wallet.
3086
+ * @param pendingSwap - The reverse swap whose VHTLC should be claimed.
3087
+ * @throws {Error} If preimage is missing, VHTLC script creation fails, or no spendable VTXOs found.
3014
3088
  */
3015
3089
  async claimVHTLC(pendingSwap) {
3016
3090
  if (!pendingSwap.preimage)
@@ -3090,9 +3164,13 @@ var init_arkade_swaps = __esm({
3090
3164
  );
3091
3165
  }
3092
3166
  /**
3093
- * Waits for the swap to be confirmed and claims the VHTLC.
3094
- * @param pendingSwap - The pending reverse swap.
3167
+ * Waits for a reverse swap to be confirmed and claims the VHTLC.
3168
+ * Delegates to SwapManager if enabled, otherwise monitors via WebSocket.
3169
+ * @param pendingSwap - The reverse swap to monitor and claim.
3095
3170
  * @returns The transaction ID of the claimed VHTLC.
3171
+ * @throws {InvoiceExpiredError} If the Lightning invoice expires.
3172
+ * @throws {SwapExpiredError} If the swap exceeds its time limit.
3173
+ * @throws {TransactionFailedError} If the on-chain transaction fails.
3096
3174
  */
3097
3175
  async waitAndClaim(pendingSwap) {
3098
3176
  if (this.swapManager && await this.swapManager.hasSwap(pendingSwap.id)) {
@@ -3172,9 +3250,11 @@ var init_arkade_swaps = __esm({
3172
3250
  // Lightning: Submarine swaps (send Arkade -> Lightning)
3173
3251
  // =========================================================================
3174
3252
  /**
3175
- * Sends a Lightning payment.
3176
- * @param args - The arguments for sending a Lightning payment.
3177
- * @returns The result of the payment.
3253
+ * Sends a Lightning payment via a submarine swap (Arkade → Lightning).
3254
+ * Creates the swap, sends funds, and waits for settlement. Auto-refunds on failure.
3255
+ * @param args.invoice - BOLT11 Lightning invoice to pay.
3256
+ * @returns The amount paid, preimage (proof of payment), and transaction ID.
3257
+ * @throws {TransactionFailedError} If the payment fails (auto-refunds if possible).
3178
3258
  */
3179
3259
  async sendLightningPayment(args) {
3180
3260
  const pendingSwap = await this.createSubmarineSwap(args);
@@ -3204,9 +3284,10 @@ var init_arkade_swaps = __esm({
3204
3284
  }
3205
3285
  }
3206
3286
  /**
3207
- * Creates a submarine swap.
3208
- * @param args - The arguments for creating a submarine swap.
3209
- * @returns The created pending submarine swap.
3287
+ * Creates a submarine swap (Arkade → Lightning) and saves it to storage.
3288
+ * @param args.invoice - BOLT11 Lightning invoice to pay.
3289
+ * @returns The pending submarine swap, added to SwapManager if enabled.
3290
+ * @throws {SwapError} If invoice is missing or key retrieval fails.
3210
3291
  */
3211
3292
  async createSubmarineSwap(args) {
3212
3293
  const refundPublicKey = import_base9.hex.encode(
@@ -3238,8 +3319,10 @@ var init_arkade_swaps = __esm({
3238
3319
  return pendingSwap;
3239
3320
  }
3240
3321
  /**
3241
- * Claims the VHTLC for a pending submarine swap (aka refund).
3242
- * @param pendingSwap - The pending submarine swap to refund the VHTLC.
3322
+ * Refunds the VHTLC for a failed submarine swap, returning locked funds to the wallet.
3323
+ * Uses multi-party signatures (user + Boltz + server) for non-recoverable VTXOs.
3324
+ * @param pendingSwap - The submarine swap to refund.
3325
+ * @throws {Error} If preimage hash is unavailable, VHTLC not found, or already spent.
3243
3326
  */
3244
3327
  async refundVHTLC(pendingSwap) {
3245
3328
  const preimageHash = pendingSwap.request.invoice ? getInvoicePaymentHash(pendingSwap.request.invoice) : pendingSwap.preimageHash;
@@ -3323,9 +3406,12 @@ var init_arkade_swaps = __esm({
3323
3406
  );
3324
3407
  }
3325
3408
  /**
3326
- * Waits for the swap settlement.
3327
- * @param pendingSwap - The pending submarine swap.
3328
- * @returns The status of the swap settlement.
3409
+ * Waits for a submarine swap's Lightning payment to settle.
3410
+ * @param pendingSwap - The submarine swap to monitor.
3411
+ * @returns The preimage from the settled Lightning payment (proof of payment).
3412
+ * @throws {SwapExpiredError} If the swap expires.
3413
+ * @throws {InvoiceFailedToPayError} If Boltz fails to route the payment.
3414
+ * @throws {TransactionLockupFailedError} If the lockup transaction fails.
3329
3415
  */
3330
3416
  async waitForSwapSettlement(pendingSwap) {
3331
3417
  return new Promise((resolve, reject) => {
@@ -3396,8 +3482,12 @@ var init_arkade_swaps = __esm({
3396
3482
  // =========================================================================
3397
3483
  /**
3398
3484
  * Creates a chain swap from ARK to BTC.
3399
- * @param args - Swap arguments.
3400
- * @returns The payment details and pending chain swap.
3485
+ * @param args.btcAddress - Destination Bitcoin address.
3486
+ * @param args.senderLockAmount - Exact amount sender locks (receiver gets less after fees). Specify this OR receiverLockAmount.
3487
+ * @param args.receiverLockAmount - Exact amount receiver gets (sender pays more). Specify this OR senderLockAmount.
3488
+ * @param args.feeSatsPerByte - Fee rate for the BTC claim transaction (default: 1).
3489
+ * @returns The ARK lockup address, amount to pay, and pending swap.
3490
+ * @throws {SwapError} If chain swap verification fails.
3401
3491
  */
3402
3492
  async arkToBtc(args) {
3403
3493
  const pendingSwap = await this.createChainSwap({
@@ -3689,8 +3779,11 @@ var init_arkade_swaps = __esm({
3689
3779
  // =========================================================================
3690
3780
  /**
3691
3781
  * Creates a chain swap from BTC to ARK.
3692
- * @param args - Swap arguments.
3693
- * @returns The pending chain swap and payment details.
3782
+ * @param args.feeSatsPerByte - Fee rate for BTC transactions (default: 1).
3783
+ * @param args.senderLockAmount - Exact BTC amount to lock. Specify this OR receiverLockAmount.
3784
+ * @param args.receiverLockAmount - Exact ARK amount to receive. Specify this OR senderLockAmount.
3785
+ * @returns The BTC lockup address, amount to pay, and pending swap.
3786
+ * @throws {SwapError} If chain swap verification fails.
3694
3787
  */
3695
3788
  async btcToArk(args) {
3696
3789
  const pendingSwap = await this.createChainSwap({
@@ -4232,6 +4325,7 @@ var init_arkade_swaps = __esm({
4232
4325
  );
4233
4326
  if (!publicKey) throw new Error("Failed to get public key from wallet");
4234
4327
  const fees = boltzFees ?? await this.swapProvider.getFees();
4328
+ const chainSwaps = [];
4235
4329
  const reverseSwaps = [];
4236
4330
  const submarineSwaps = [];
4237
4331
  const restoredSwaps = await this.swapProvider.restoreSwaps(publicKey);
@@ -4324,9 +4418,45 @@ var init_arkade_swaps = __esm({
4324
4418
  }
4325
4419
  }
4326
4420
  });
4421
+ } else if (isRestoredChainSwap(swap)) {
4422
+ const {
4423
+ amount,
4424
+ lockupAddress,
4425
+ serverPublicKey,
4426
+ timeoutBlockHeight
4427
+ } = swap.refundDetails;
4428
+ chainSwaps.push({
4429
+ id,
4430
+ type: "chain",
4431
+ createdAt,
4432
+ preimage: "",
4433
+ ephemeralKey: "",
4434
+ feeSatsPerByte: 1,
4435
+ amount,
4436
+ status,
4437
+ request: {
4438
+ to: swap.to,
4439
+ from: swap.from,
4440
+ preimageHash: swap.preimageHash,
4441
+ claimPublicKey: "",
4442
+ feeSatsPerByte: 1,
4443
+ refundPublicKey: "",
4444
+ serverLockAmount: amount,
4445
+ userLockAmount: amount
4446
+ },
4447
+ response: {
4448
+ id,
4449
+ lockupDetails: {
4450
+ amount,
4451
+ lockupAddress,
4452
+ serverPublicKey,
4453
+ timeoutBlockHeight
4454
+ }
4455
+ }
4456
+ });
4327
4457
  }
4328
4458
  }
4329
- return { reverseSwaps, submarineSwaps };
4459
+ return { chainSwaps, reverseSwaps, submarineSwaps };
4330
4460
  }
4331
4461
  /**
4332
4462
  * Enrich a restored reverse swap with its preimage.
@@ -1,5 +1,5 @@
1
- import { I as IArkadeSwaps, A as ArkadeSwaps } from '../arkade-swaps-Brpa88Fg.cjs';
2
- import { A as ArkadeSwapsConfig, i as SwapRepository, l as BoltzSwapProvider, N as Network, j as SwapManagerClient, C as CreateLightningInvoiceRequest, e as CreateLightningInvoiceResponse, S as SendLightningPaymentRequest, f as SendLightningPaymentResponse, c as PendingSubmarineSwap, b as PendingReverseSwap, F as FeesResponse, h as ArkToBtcResponse, a as PendingChainSwap, B as BtcToArkResponse, d as Chain, g as ChainFeesResponse, L as LimitsResponse, G as GetSwapStatusResponse, P as PendingSwap } from '../types-BRYTZH1Z.cjs';
1
+ import { I as IArkadeSwaps, A as ArkadeSwaps } from '../arkade-swaps-w-cm-cPg.cjs';
2
+ import { A as ArkadeSwapsConfig, i as SwapRepository, l as BoltzSwapProvider, N as Network, j as SwapManagerClient, C as CreateLightningInvoiceRequest, e as CreateLightningInvoiceResponse, S as SendLightningPaymentRequest, f as SendLightningPaymentResponse, c as PendingSubmarineSwap, b as PendingReverseSwap, F as FeesResponse, a as PendingChainSwap, h as ArkToBtcResponse, B as BtcToArkResponse, d as Chain, g as ChainFeesResponse, L as LimitsResponse, G as GetSwapStatusResponse, P as PendingSwap } from '../types-t0r41rlw.cjs';
3
3
  import { Identity, ArkProvider, IndexerProvider, IWallet, ArkInfo, ArkTxInput, VHTLC } from '@arkade-os/sdk';
4
4
  import { AsyncStorageTaskQueue, TaskProcessor } from '@arkade-os/sdk/worker/expo';
5
5
  import { TransactionOutput } from '@scure/btc-signer/psbt.js';
@@ -142,6 +142,7 @@ declare class ExpoArkadeSwaps implements IArkadeSwaps {
142
142
  preimage: string;
143
143
  }>;
144
144
  restoreSwaps(boltzFees?: FeesResponse): Promise<{
145
+ chainSwaps: PendingChainSwap[];
145
146
  reverseSwaps: PendingReverseSwap[];
146
147
  submarineSwaps: PendingSubmarineSwap[];
147
148
  }>;
@@ -1,5 +1,5 @@
1
- import { I as IArkadeSwaps, A as ArkadeSwaps } from '../arkade-swaps-DnvQayY0.js';
2
- import { A as ArkadeSwapsConfig, i as SwapRepository, l as BoltzSwapProvider, N as Network, j as SwapManagerClient, C as CreateLightningInvoiceRequest, e as CreateLightningInvoiceResponse, S as SendLightningPaymentRequest, f as SendLightningPaymentResponse, c as PendingSubmarineSwap, b as PendingReverseSwap, F as FeesResponse, h as ArkToBtcResponse, a as PendingChainSwap, B as BtcToArkResponse, d as Chain, g as ChainFeesResponse, L as LimitsResponse, G as GetSwapStatusResponse, P as PendingSwap } from '../types-BRYTZH1Z.js';
1
+ import { I as IArkadeSwaps, A as ArkadeSwaps } from '../arkade-swaps-DHjneVaF.js';
2
+ import { A as ArkadeSwapsConfig, i as SwapRepository, l as BoltzSwapProvider, N as Network, j as SwapManagerClient, C as CreateLightningInvoiceRequest, e as CreateLightningInvoiceResponse, S as SendLightningPaymentRequest, f as SendLightningPaymentResponse, c as PendingSubmarineSwap, b as PendingReverseSwap, F as FeesResponse, a as PendingChainSwap, h as ArkToBtcResponse, B as BtcToArkResponse, d as Chain, g as ChainFeesResponse, L as LimitsResponse, G as GetSwapStatusResponse, P as PendingSwap } from '../types-t0r41rlw.js';
3
3
  import { Identity, ArkProvider, IndexerProvider, IWallet, ArkInfo, ArkTxInput, VHTLC } from '@arkade-os/sdk';
4
4
  import { AsyncStorageTaskQueue, TaskProcessor } from '@arkade-os/sdk/worker/expo';
5
5
  import { TransactionOutput } from '@scure/btc-signer/psbt.js';
@@ -142,6 +142,7 @@ declare class ExpoArkadeSwaps implements IArkadeSwaps {
142
142
  preimage: string;
143
143
  }>;
144
144
  restoreSwaps(boltzFees?: FeesResponse): Promise<{
145
+ chainSwaps: PendingChainSwap[];
145
146
  reverseSwaps: PendingReverseSwap[];
146
147
  submarineSwaps: PendingSubmarineSwap[];
147
148
  }>;
@@ -4,10 +4,10 @@ import {
4
4
  registerExpoSwapBackgroundTask,
5
5
  swapsPollProcessor,
6
6
  unregisterExpoSwapBackgroundTask
7
- } from "../chunk-WNTQXNGX.js";
7
+ } from "../chunk-LKAPZQDE.js";
8
8
  import {
9
9
  ArkadeSwaps
10
- } from "../chunk-XVJ47GNJ.js";
10
+ } from "../chunk-Y7C7NJ5D.js";
11
11
  import "../chunk-3RG5ZIWI.js";
12
12
 
13
13
  // src/expo/arkade-lightning.ts
@@ -56,7 +56,7 @@ var ExpoArkadeSwaps = class _ExpoArkadeSwaps {
56
56
  await instance.seedSwapPollTask();
57
57
  if (config.background.minimumBackgroundInterval) {
58
58
  try {
59
- const { registerExpoSwapBackgroundTask: registerExpoSwapBackgroundTask2 } = await import("../background-OI6ONB3C.js");
59
+ const { registerExpoSwapBackgroundTask: registerExpoSwapBackgroundTask2 } = await import("../background-2UJPEKEU.js");
60
60
  await registerExpoSwapBackgroundTask2(
61
61
  config.background.taskName,
62
62
  {
@@ -119,7 +119,7 @@ var ExpoArkadeSwaps = class _ExpoArkadeSwaps {
119
119
  }
120
120
  await this.inner.dispose();
121
121
  try {
122
- const { unregisterExpoSwapBackgroundTask: unregisterExpoSwapBackgroundTask2 } = await import("../background-OI6ONB3C.js");
122
+ const { unregisterExpoSwapBackgroundTask: unregisterExpoSwapBackgroundTask2 } = await import("../background-2UJPEKEU.js");
123
123
  await unregisterExpoSwapBackgroundTask2(this.taskName);
124
124
  } catch (err) {
125
125
  const message = err instanceof Error ? err.message : String(err);