@arkade-os/boltz-swap 0.3.40 → 0.3.41

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.
@@ -245,6 +245,22 @@ var isSubmarineFinalStatus = (status) => {
245
245
  var isSubmarineRefundableStatus = (status) => {
246
246
  return ["invoice.failedToPay", "transaction.lockupFailed", "swap.expired"].includes(status);
247
247
  };
248
+ var SUBMARINE_STATUS_PROGRESSION = [
249
+ "swap.created",
250
+ "invoice.set",
251
+ "transaction.mempool",
252
+ "transaction.confirmed",
253
+ "invoice.pending",
254
+ "invoice.paid",
255
+ "transaction.claim.pending",
256
+ "transaction.claimed"
257
+ ];
258
+ var hasSubmarineStatusReached = (status, target) => {
259
+ const progression = SUBMARINE_STATUS_PROGRESSION;
260
+ const statusIndex = progression.indexOf(status);
261
+ const targetIndex = progression.indexOf(target);
262
+ return statusIndex >= 0 && targetIndex >= 0 && statusIndex >= targetIndex;
263
+ };
248
264
  var isSubmarineSuccessStatus = (status) => {
249
265
  return status === "transaction.claimed";
250
266
  };
@@ -3542,16 +3558,6 @@ var ArkadeSwaps = class _ArkadeSwaps {
3542
3558
  this.swapProvider.monitorSwap(pendingSwap.id, onStatusUpdate).catch(reject);
3543
3559
  });
3544
3560
  }
3545
- // =========================================================================
3546
- // Lightning: Submarine swaps (send Arkade -> Lightning)
3547
- // =========================================================================
3548
- /**
3549
- * Sends a Lightning payment via a submarine swap (Arkade → Lightning).
3550
- * Creates the swap, sends funds, and waits for settlement. Auto-refunds on failure.
3551
- * @param args.invoice - BOLT11 Lightning invoice to pay.
3552
- * @returns The amount paid, preimage (proof of payment), and transaction ID.
3553
- * @throws {TransactionFailedError} If the payment fails (auto-refunds if possible).
3554
- */
3555
3561
  async sendLightningPayment(args) {
3556
3562
  const pendingSwap = await this.createSubmarineSwap(args);
3557
3563
  if (!pendingSwap.response.address)
@@ -3562,6 +3568,18 @@ var ArkadeSwaps = class _ArkadeSwaps {
3562
3568
  amount: pendingSwap.response.expectedAmount
3563
3569
  });
3564
3570
  try {
3571
+ if (args.waitFor === "funded") {
3572
+ if (!this.swapManager) {
3573
+ logger.warn(
3574
+ `Swap ${pendingSwap.id}: sendLightningPayment with waitFor "funded" but SwapManager is disabled \u2014 a failure after this promise resolves is only persisted as refundable, not auto-refunded; recover via restoreSwaps/recoverSubmarineFunds`
3575
+ );
3576
+ }
3577
+ await this.waitForSwapFunded(pendingSwap);
3578
+ return {
3579
+ amount: pendingSwap.response.expectedAmount,
3580
+ txid
3581
+ };
3582
+ }
3565
3583
  const { preimage } = await this.waitForSwapSettlement(pendingSwap);
3566
3584
  return {
3567
3585
  amount: pendingSwap.response.expectedAmount,
@@ -4063,6 +4081,9 @@ var ArkadeSwaps = class _ArkadeSwaps {
4063
4081
  }
4064
4082
  /**
4065
4083
  * Waits for a submarine swap's Lightning payment to settle.
4084
+ * Resolves only at the terminal "transaction.claimed" status, once Boltz
4085
+ * has swept the HTLC. To resolve as soon as the payment is in flight, use
4086
+ * {@link waitForSwapFunded} instead.
4066
4087
  * @param pendingSwap - The submarine swap to monitor.
4067
4088
  * @returns The preimage from the settled Lightning payment (proof of payment).
4068
4089
  * @throws {SwapExpiredError} If the swap expires.
@@ -4070,19 +4091,59 @@ var ArkadeSwaps = class _ArkadeSwaps {
4070
4091
  * @throws {TransactionLockupFailedError} If the lockup transaction fails.
4071
4092
  */
4072
4093
  async waitForSwapSettlement(pendingSwap) {
4094
+ return this.waitForSubmarineSwap(pendingSwap);
4095
+ }
4096
+ /**
4097
+ * Waits until a submarine swap is funded: resolves as soon as the lockup
4098
+ * transaction is observed ("transaction.mempool" or any later status in
4099
+ * the lifecycle — statuses can be skipped since subscriptions report only
4100
+ * the current one). The sender's funds are committed and the swap is
4101
+ * refundable from this point, which is when most Lightning wallets show
4102
+ * a payment as "sent".
4103
+ *
4104
+ * Monitoring continues in the background until the swap reaches a
4105
+ * terminal status, persisting updates to the repository (the preimage on
4106
+ * claim, the refundable flag on failure), but this promise no longer
4107
+ * rejects once resolved — acting on a late failure is the caller's
4108
+ * responsibility (the SwapManager handles it automatically when enabled).
4109
+ * @param pendingSwap - The submarine swap to monitor.
4110
+ * @throws {SwapExpiredError} If the swap expires before funding.
4111
+ * @throws {InvoiceFailedToPayError} If Boltz fails to route the payment.
4112
+ * @throws {TransactionLockupFailedError} If the lockup transaction fails.
4113
+ */
4114
+ async waitForSwapFunded(pendingSwap) {
4115
+ await this.waitForSubmarineSwap(pendingSwap, "transaction.mempool");
4116
+ }
4117
+ /**
4118
+ * Shared wait machinery: monitors the swap and resolves at the terminal
4119
+ * "transaction.claimed" status (with the preimage) or, when `resolveAt`
4120
+ * is given, as soon as that status — or any later one in the successful
4121
+ * progression — is observed (without a preimage).
4122
+ */
4123
+ async waitForSubmarineSwap(pendingSwap, resolveAt) {
4073
4124
  return new Promise((resolve, reject) => {
4074
- let isResolved = false;
4125
+ let isFinal = false;
4126
+ let isSettled = false;
4075
4127
  const onStatusUpdate = async (status) => {
4076
- if (isResolved) return;
4077
- const saveStatus = (additionalFields) => updateSubmarineSwapStatus(
4078
- pendingSwap,
4079
- status,
4080
- this.savePendingSubmarineSwap.bind(this),
4081
- additionalFields
4082
- );
4128
+ if (isFinal) return;
4129
+ const saveStatus = async (additionalFields) => {
4130
+ try {
4131
+ await updateSubmarineSwapStatus(
4132
+ pendingSwap,
4133
+ status,
4134
+ this.savePendingSubmarineSwap.bind(this),
4135
+ additionalFields
4136
+ );
4137
+ } catch (error) {
4138
+ logger.error(
4139
+ `Swap ${pendingSwap.id}: failed to persist status "${status}": ${error}`
4140
+ );
4141
+ }
4142
+ };
4083
4143
  switch (status) {
4084
4144
  case "swap.expired":
4085
- isResolved = true;
4145
+ isFinal = true;
4146
+ isSettled = true;
4086
4147
  await saveStatus({ refundable: true });
4087
4148
  reject(
4088
4149
  new SwapExpiredError({
@@ -4092,7 +4153,8 @@ var ArkadeSwaps = class _ArkadeSwaps {
4092
4153
  );
4093
4154
  break;
4094
4155
  case "invoice.failedToPay":
4095
- isResolved = true;
4156
+ isFinal = true;
4157
+ isSettled = true;
4096
4158
  await saveStatus({ refundable: true });
4097
4159
  reject(
4098
4160
  new InvoiceFailedToPayError({
@@ -4102,7 +4164,8 @@ var ArkadeSwaps = class _ArkadeSwaps {
4102
4164
  );
4103
4165
  break;
4104
4166
  case "transaction.lockupFailed":
4105
- isResolved = true;
4167
+ isFinal = true;
4168
+ isSettled = true;
4106
4169
  await saveStatus({ refundable: true });
4107
4170
  reject(
4108
4171
  new TransactionLockupFailedError({
@@ -4112,23 +4175,47 @@ var ArkadeSwaps = class _ArkadeSwaps {
4112
4175
  );
4113
4176
  break;
4114
4177
  case "transaction.claimed": {
4115
- isResolved = true;
4116
- const { preimage } = await this.swapProvider.getSwapPreimage(
4117
- pendingSwap.id
4118
- );
4119
- await saveStatus({ preimage });
4120
- resolve({ preimage });
4178
+ isFinal = true;
4179
+ isSettled = true;
4180
+ try {
4181
+ const { preimage } = await this.swapProvider.getSwapPreimage(
4182
+ pendingSwap.id
4183
+ );
4184
+ await saveStatus({ preimage });
4185
+ resolve({ preimage });
4186
+ } catch (error) {
4187
+ logger.error(
4188
+ `Swap ${pendingSwap.id}: failed to fetch preimage on claim: ${error}`
4189
+ );
4190
+ reject(error);
4191
+ }
4121
4192
  break;
4122
4193
  }
4123
4194
  default:
4124
4195
  await saveStatus();
4196
+ if (resolveAt && hasSubmarineStatusReached(status, resolveAt)) {
4197
+ isSettled = true;
4198
+ resolve({ preimage: void 0 });
4199
+ }
4125
4200
  break;
4126
4201
  }
4127
4202
  };
4128
- this.swapProvider.monitorSwap(pendingSwap.id, onStatusUpdate).catch((error) => {
4129
- if (!isResolved) {
4130
- isResolved = true;
4203
+ this.swapProvider.monitorSwap(pendingSwap.id, (status) => {
4204
+ onStatusUpdate(status).catch(
4205
+ (error) => logger.error(
4206
+ `Swap ${pendingSwap.id}: error handling status "${status}": ${error}`
4207
+ )
4208
+ );
4209
+ }).catch((error) => {
4210
+ if (!isSettled) {
4211
+ isFinal = true;
4212
+ isSettled = true;
4131
4213
  reject(error);
4214
+ } else {
4215
+ isFinal = true;
4216
+ logger.warn(
4217
+ `Swap ${pendingSwap.id}: monitor failed after settlement: ${error}`
4218
+ );
4132
4219
  }
4133
4220
  });
4134
4221
  });
@@ -5152,13 +5239,28 @@ var ArkadeSwaps = class _ArkadeSwaps {
5152
5239
  for (const swap of await this.getPendingSubmarineSwapsFromStorage()) {
5153
5240
  if (isSubmarineFinalStatus(swap.status)) continue;
5154
5241
  promises.push(
5155
- this.getSwapStatus(swap.id).then(
5156
- ({ status }) => updateSubmarineSwapStatus(
5242
+ this.getSwapStatus(swap.id).then(async ({ status }) => {
5243
+ let additionalFields;
5244
+ if (isSubmarineSuccessStatus(status) && !swap.preimage) {
5245
+ try {
5246
+ const { preimage } = await this.swapProvider.getSwapPreimage(
5247
+ swap.id
5248
+ );
5249
+ additionalFields = { preimage };
5250
+ } catch (error) {
5251
+ logger.warn(
5252
+ `Failed to fetch preimage for settled swap ${swap.id}:`,
5253
+ error
5254
+ );
5255
+ }
5256
+ }
5257
+ await updateSubmarineSwapStatus(
5157
5258
  swap,
5158
5259
  status,
5159
- this.savePendingSubmarineSwap.bind(this)
5160
- )
5161
- ).catch((error) => {
5260
+ this.savePendingSubmarineSwap.bind(this),
5261
+ additionalFields
5262
+ );
5263
+ }).catch((error) => {
5162
5264
  logger.error(`Failed to refresh swap status for ${swap.id}:`, error);
5163
5265
  })
5164
5266
  );
@@ -1,8 +1,8 @@
1
- import { D as DefineSwapBackgroundTaskOptions } from '../swapsPollProcessor-BlyUrhtO.cjs';
2
- export { P as PersistedSwapBackgroundConfig, S as SWAP_POLL_TASK_TYPE, a as SwapTaskDependencies, s as swapsPollProcessor } from '../swapsPollProcessor-BlyUrhtO.cjs';
1
+ import { D as DefineSwapBackgroundTaskOptions } from '../swapsPollProcessor-CGMXUKPe.cjs';
2
+ export { P as PersistedSwapBackgroundConfig, S as SWAP_POLL_TASK_TYPE, a as SwapTaskDependencies, s as swapsPollProcessor } from '../swapsPollProcessor-CGMXUKPe.cjs';
3
3
  import '@arkade-os/sdk/worker/expo';
4
4
  import '@arkade-os/sdk';
5
- import '../types-D97i1LFu.cjs';
5
+ import '../types-8NrCdOpS.cjs';
6
6
 
7
7
  /**
8
8
  * Define the Expo background task handler for swap polling.
@@ -1,8 +1,8 @@
1
- import { D as DefineSwapBackgroundTaskOptions } from '../swapsPollProcessor-Bv4Z2R7g.js';
2
- export { P as PersistedSwapBackgroundConfig, S as SWAP_POLL_TASK_TYPE, a as SwapTaskDependencies, s as swapsPollProcessor } from '../swapsPollProcessor-Bv4Z2R7g.js';
1
+ import { D as DefineSwapBackgroundTaskOptions } from '../swapsPollProcessor-CuDM6sxV.js';
2
+ export { P as PersistedSwapBackgroundConfig, S as SWAP_POLL_TASK_TYPE, a as SwapTaskDependencies, s as swapsPollProcessor } from '../swapsPollProcessor-CuDM6sxV.js';
3
3
  import '@arkade-os/sdk/worker/expo';
4
4
  import '@arkade-os/sdk';
5
- import '../types-D97i1LFu.js';
5
+ import '../types-8NrCdOpS.js';
6
6
 
7
7
  /**
8
8
  * Define the Expo background task handler for swap polling.
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  SWAP_POLL_TASK_TYPE,
3
3
  swapsPollProcessor
4
- } from "../chunk-WGLBFONB.js";
4
+ } from "../chunk-CWY37W4B.js";
5
5
  import {
6
6
  BoltzSwapProvider
7
- } from "../chunk-GYWMQOCP.js";
7
+ } from "../chunk-UXYHW7KV.js";
8
8
  import "../chunk-SJQJQO7P.js";
9
9
 
10
10
  // src/expo/background.ts
@@ -239,6 +239,22 @@ var isSubmarineFinalStatus = (status) => {
239
239
  var isSubmarineRefundableStatus = (status) => {
240
240
  return ["invoice.failedToPay", "transaction.lockupFailed", "swap.expired"].includes(status);
241
241
  };
242
+ var SUBMARINE_STATUS_PROGRESSION = [
243
+ "swap.created",
244
+ "invoice.set",
245
+ "transaction.mempool",
246
+ "transaction.confirmed",
247
+ "invoice.pending",
248
+ "invoice.paid",
249
+ "transaction.claim.pending",
250
+ "transaction.claimed"
251
+ ];
252
+ var hasSubmarineStatusReached = (status, target) => {
253
+ const progression = SUBMARINE_STATUS_PROGRESSION;
254
+ const statusIndex = progression.indexOf(status);
255
+ const targetIndex = progression.indexOf(target);
256
+ return statusIndex >= 0 && targetIndex >= 0 && statusIndex >= targetIndex;
257
+ };
242
258
  var isSubmarineSuccessStatus = (status) => {
243
259
  return status === "transaction.claimed";
244
260
  };
@@ -3532,16 +3548,6 @@ var ArkadeSwaps = class _ArkadeSwaps {
3532
3548
  this.swapProvider.monitorSwap(pendingSwap.id, onStatusUpdate).catch(reject);
3533
3549
  });
3534
3550
  }
3535
- // =========================================================================
3536
- // Lightning: Submarine swaps (send Arkade -> Lightning)
3537
- // =========================================================================
3538
- /**
3539
- * Sends a Lightning payment via a submarine swap (Arkade → Lightning).
3540
- * Creates the swap, sends funds, and waits for settlement. Auto-refunds on failure.
3541
- * @param args.invoice - BOLT11 Lightning invoice to pay.
3542
- * @returns The amount paid, preimage (proof of payment), and transaction ID.
3543
- * @throws {TransactionFailedError} If the payment fails (auto-refunds if possible).
3544
- */
3545
3551
  async sendLightningPayment(args) {
3546
3552
  const pendingSwap = await this.createSubmarineSwap(args);
3547
3553
  if (!pendingSwap.response.address)
@@ -3552,6 +3558,18 @@ var ArkadeSwaps = class _ArkadeSwaps {
3552
3558
  amount: pendingSwap.response.expectedAmount
3553
3559
  });
3554
3560
  try {
3561
+ if (args.waitFor === "funded") {
3562
+ if (!this.swapManager) {
3563
+ logger.warn(
3564
+ `Swap ${pendingSwap.id}: sendLightningPayment with waitFor "funded" but SwapManager is disabled \u2014 a failure after this promise resolves is only persisted as refundable, not auto-refunded; recover via restoreSwaps/recoverSubmarineFunds`
3565
+ );
3566
+ }
3567
+ await this.waitForSwapFunded(pendingSwap);
3568
+ return {
3569
+ amount: pendingSwap.response.expectedAmount,
3570
+ txid
3571
+ };
3572
+ }
3555
3573
  const { preimage } = await this.waitForSwapSettlement(pendingSwap);
3556
3574
  return {
3557
3575
  amount: pendingSwap.response.expectedAmount,
@@ -4053,6 +4071,9 @@ var ArkadeSwaps = class _ArkadeSwaps {
4053
4071
  }
4054
4072
  /**
4055
4073
  * Waits for a submarine swap's Lightning payment to settle.
4074
+ * Resolves only at the terminal "transaction.claimed" status, once Boltz
4075
+ * has swept the HTLC. To resolve as soon as the payment is in flight, use
4076
+ * {@link waitForSwapFunded} instead.
4056
4077
  * @param pendingSwap - The submarine swap to monitor.
4057
4078
  * @returns The preimage from the settled Lightning payment (proof of payment).
4058
4079
  * @throws {SwapExpiredError} If the swap expires.
@@ -4060,19 +4081,59 @@ var ArkadeSwaps = class _ArkadeSwaps {
4060
4081
  * @throws {TransactionLockupFailedError} If the lockup transaction fails.
4061
4082
  */
4062
4083
  async waitForSwapSettlement(pendingSwap) {
4084
+ return this.waitForSubmarineSwap(pendingSwap);
4085
+ }
4086
+ /**
4087
+ * Waits until a submarine swap is funded: resolves as soon as the lockup
4088
+ * transaction is observed ("transaction.mempool" or any later status in
4089
+ * the lifecycle — statuses can be skipped since subscriptions report only
4090
+ * the current one). The sender's funds are committed and the swap is
4091
+ * refundable from this point, which is when most Lightning wallets show
4092
+ * a payment as "sent".
4093
+ *
4094
+ * Monitoring continues in the background until the swap reaches a
4095
+ * terminal status, persisting updates to the repository (the preimage on
4096
+ * claim, the refundable flag on failure), but this promise no longer
4097
+ * rejects once resolved — acting on a late failure is the caller's
4098
+ * responsibility (the SwapManager handles it automatically when enabled).
4099
+ * @param pendingSwap - The submarine swap to monitor.
4100
+ * @throws {SwapExpiredError} If the swap expires before funding.
4101
+ * @throws {InvoiceFailedToPayError} If Boltz fails to route the payment.
4102
+ * @throws {TransactionLockupFailedError} If the lockup transaction fails.
4103
+ */
4104
+ async waitForSwapFunded(pendingSwap) {
4105
+ await this.waitForSubmarineSwap(pendingSwap, "transaction.mempool");
4106
+ }
4107
+ /**
4108
+ * Shared wait machinery: monitors the swap and resolves at the terminal
4109
+ * "transaction.claimed" status (with the preimage) or, when `resolveAt`
4110
+ * is given, as soon as that status — or any later one in the successful
4111
+ * progression — is observed (without a preimage).
4112
+ */
4113
+ async waitForSubmarineSwap(pendingSwap, resolveAt) {
4063
4114
  return new Promise((resolve, reject) => {
4064
- let isResolved = false;
4115
+ let isFinal = false;
4116
+ let isSettled = false;
4065
4117
  const onStatusUpdate = async (status) => {
4066
- if (isResolved) return;
4067
- const saveStatus = (additionalFields) => updateSubmarineSwapStatus(
4068
- pendingSwap,
4069
- status,
4070
- this.savePendingSubmarineSwap.bind(this),
4071
- additionalFields
4072
- );
4118
+ if (isFinal) return;
4119
+ const saveStatus = async (additionalFields) => {
4120
+ try {
4121
+ await updateSubmarineSwapStatus(
4122
+ pendingSwap,
4123
+ status,
4124
+ this.savePendingSubmarineSwap.bind(this),
4125
+ additionalFields
4126
+ );
4127
+ } catch (error) {
4128
+ logger.error(
4129
+ `Swap ${pendingSwap.id}: failed to persist status "${status}": ${error}`
4130
+ );
4131
+ }
4132
+ };
4073
4133
  switch (status) {
4074
4134
  case "swap.expired":
4075
- isResolved = true;
4135
+ isFinal = true;
4136
+ isSettled = true;
4076
4137
  await saveStatus({ refundable: true });
4077
4138
  reject(
4078
4139
  new SwapExpiredError({
@@ -4082,7 +4143,8 @@ var ArkadeSwaps = class _ArkadeSwaps {
4082
4143
  );
4083
4144
  break;
4084
4145
  case "invoice.failedToPay":
4085
- isResolved = true;
4146
+ isFinal = true;
4147
+ isSettled = true;
4086
4148
  await saveStatus({ refundable: true });
4087
4149
  reject(
4088
4150
  new InvoiceFailedToPayError({
@@ -4092,7 +4154,8 @@ var ArkadeSwaps = class _ArkadeSwaps {
4092
4154
  );
4093
4155
  break;
4094
4156
  case "transaction.lockupFailed":
4095
- isResolved = true;
4157
+ isFinal = true;
4158
+ isSettled = true;
4096
4159
  await saveStatus({ refundable: true });
4097
4160
  reject(
4098
4161
  new TransactionLockupFailedError({
@@ -4102,23 +4165,47 @@ var ArkadeSwaps = class _ArkadeSwaps {
4102
4165
  );
4103
4166
  break;
4104
4167
  case "transaction.claimed": {
4105
- isResolved = true;
4106
- const { preimage } = await this.swapProvider.getSwapPreimage(
4107
- pendingSwap.id
4108
- );
4109
- await saveStatus({ preimage });
4110
- resolve({ preimage });
4168
+ isFinal = true;
4169
+ isSettled = true;
4170
+ try {
4171
+ const { preimage } = await this.swapProvider.getSwapPreimage(
4172
+ pendingSwap.id
4173
+ );
4174
+ await saveStatus({ preimage });
4175
+ resolve({ preimage });
4176
+ } catch (error) {
4177
+ logger.error(
4178
+ `Swap ${pendingSwap.id}: failed to fetch preimage on claim: ${error}`
4179
+ );
4180
+ reject(error);
4181
+ }
4111
4182
  break;
4112
4183
  }
4113
4184
  default:
4114
4185
  await saveStatus();
4186
+ if (resolveAt && hasSubmarineStatusReached(status, resolveAt)) {
4187
+ isSettled = true;
4188
+ resolve({ preimage: void 0 });
4189
+ }
4115
4190
  break;
4116
4191
  }
4117
4192
  };
4118
- this.swapProvider.monitorSwap(pendingSwap.id, onStatusUpdate).catch((error) => {
4119
- if (!isResolved) {
4120
- isResolved = true;
4193
+ this.swapProvider.monitorSwap(pendingSwap.id, (status) => {
4194
+ onStatusUpdate(status).catch(
4195
+ (error) => logger.error(
4196
+ `Swap ${pendingSwap.id}: error handling status "${status}": ${error}`
4197
+ )
4198
+ );
4199
+ }).catch((error) => {
4200
+ if (!isSettled) {
4201
+ isFinal = true;
4202
+ isSettled = true;
4121
4203
  reject(error);
4204
+ } else {
4205
+ isFinal = true;
4206
+ logger.warn(
4207
+ `Swap ${pendingSwap.id}: monitor failed after settlement: ${error}`
4208
+ );
4122
4209
  }
4123
4210
  });
4124
4211
  });
@@ -5142,13 +5229,28 @@ var ArkadeSwaps = class _ArkadeSwaps {
5142
5229
  for (const swap of await this.getPendingSubmarineSwapsFromStorage()) {
5143
5230
  if (isSubmarineFinalStatus(swap.status)) continue;
5144
5231
  promises.push(
5145
- this.getSwapStatus(swap.id).then(
5146
- ({ status }) => updateSubmarineSwapStatus(
5232
+ this.getSwapStatus(swap.id).then(async ({ status }) => {
5233
+ let additionalFields;
5234
+ if (isSubmarineSuccessStatus(status) && !swap.preimage) {
5235
+ try {
5236
+ const { preimage } = await this.swapProvider.getSwapPreimage(
5237
+ swap.id
5238
+ );
5239
+ additionalFields = { preimage };
5240
+ } catch (error) {
5241
+ logger.warn(
5242
+ `Failed to fetch preimage for settled swap ${swap.id}:`,
5243
+ error
5244
+ );
5245
+ }
5246
+ }
5247
+ await updateSubmarineSwapStatus(
5147
5248
  swap,
5148
5249
  status,
5149
- this.savePendingSubmarineSwap.bind(this)
5150
- )
5151
- ).catch((error) => {
5250
+ this.savePendingSubmarineSwap.bind(this),
5251
+ additionalFields
5252
+ );
5253
+ }).catch((error) => {
5152
5254
  logger.error(`Failed to refresh swap status for ${swap.id}:`, error);
5153
5255
  })
5154
5256
  );
@@ -5458,6 +5560,9 @@ var ExpoArkadeSwaps = class _ExpoArkadeSwaps {
5458
5560
  waitForSwapSettlement(pendingSwap) {
5459
5561
  return this.inner.waitForSwapSettlement(pendingSwap);
5460
5562
  }
5563
+ waitForSwapFunded(pendingSwap) {
5564
+ return this.inner.waitForSwapFunded(pendingSwap);
5565
+ }
5461
5566
  restoreSwaps(boltzFees) {
5462
5567
  return this.inner.restoreSwaps(boltzFees);
5463
5568
  }
@@ -1,7 +1,7 @@
1
- import { I as IArkadeSwaps, A as ArkadeSwaps, Q as QuoteSwapOptions, V as VhtlcTimeouts } from '../arkade-swaps-CObmwpZQ.cjs';
2
- import { o as SwapManagerClient, C as CreateLightningInvoiceRequest, e as CreateLightningInvoiceResponse, S as SendLightningPaymentRequest, f as SendLightningPaymentResponse, c as BoltzSubmarineSwap, b as BoltzReverseSwap, g as SubmarineRefundOutcome, h as SubmarineRecoveryInfo, i as SubmarineRecoveryResult, F as FeesResponse, a as BoltzChainSwap, k as ArkToBtcResponse, m as ChainArkRefundOutcome, l as BtcToArkResponse, d as Chain, j as ChainFeesResponse, L as LimitsResponse, G as GetSwapStatusResponse, B as BoltzSwap } from '../types-D97i1LFu.cjs';
3
- import { E as ExpoArkadeSwapsConfig } from '../swapsPollProcessor-BlyUrhtO.cjs';
4
- export { D as DefineSwapBackgroundTaskOptions, b as ExpoArkadeLightningConfig, c as ExpoSwapBackgroundConfig, P as PersistedSwapBackgroundConfig, S as SWAP_POLL_TASK_TYPE, a as SwapTaskDependencies } from '../swapsPollProcessor-BlyUrhtO.cjs';
1
+ import { I as IArkadeSwaps, A as ArkadeSwaps, Q as QuoteSwapOptions, V as VhtlcTimeouts } from '../arkade-swaps-C3sUFr5f.cjs';
2
+ import { n as SwapManagerClient, C as CreateLightningInvoiceRequest, e as CreateLightningInvoiceResponse, S as SendLightningPaymentRequest, o as SendLightningPaymentResponse, O as OptimisticSendLightningPaymentResponse, c as BoltzSubmarineSwap, b as BoltzReverseSwap, f as SubmarineRefundOutcome, g as SubmarineRecoveryInfo, h as SubmarineRecoveryResult, F as FeesResponse, a as BoltzChainSwap, j as ArkToBtcResponse, l as ChainArkRefundOutcome, k as BtcToArkResponse, d as Chain, i as ChainFeesResponse, L as LimitsResponse, G as GetSwapStatusResponse, B as BoltzSwap } from '../types-8NrCdOpS.cjs';
3
+ import { E as ExpoArkadeSwapsConfig } from '../swapsPollProcessor-CGMXUKPe.cjs';
4
+ export { D as DefineSwapBackgroundTaskOptions, b as ExpoArkadeLightningConfig, c as ExpoSwapBackgroundConfig, P as PersistedSwapBackgroundConfig, S as SWAP_POLL_TASK_TYPE, a as SwapTaskDependencies } from '../swapsPollProcessor-CGMXUKPe.cjs';
5
5
  import { ArkInfo, Identity, ArkTxInput, VHTLC } from '@arkade-os/sdk';
6
6
  import { TransactionOutput } from '@scure/btc-signer/psbt.js';
7
7
  import '@arkade-os/sdk/worker/expo';
@@ -84,7 +84,10 @@ declare class ExpoArkadeSwaps implements IArkadeSwaps {
84
84
  stopSwapManager(): Promise<void>;
85
85
  getSwapManager(): SwapManagerClient | null;
86
86
  createLightningInvoice(args: CreateLightningInvoiceRequest): Promise<CreateLightningInvoiceResponse>;
87
- sendLightningPayment(args: SendLightningPaymentRequest): Promise<SendLightningPaymentResponse>;
87
+ sendLightningPayment(args: SendLightningPaymentRequest & {
88
+ waitFor?: "settled";
89
+ }): Promise<SendLightningPaymentResponse>;
90
+ sendLightningPayment(args: SendLightningPaymentRequest): Promise<OptimisticSendLightningPaymentResponse>;
88
91
  createSubmarineSwap(args: SendLightningPaymentRequest): Promise<BoltzSubmarineSwap>;
89
92
  createReverseSwap(args: CreateLightningInvoiceRequest): Promise<BoltzReverseSwap>;
90
93
  claimVHTLC(pendingSwap: BoltzReverseSwap): Promise<void>;
@@ -99,6 +102,7 @@ declare class ExpoArkadeSwaps implements IArkadeSwaps {
99
102
  waitForSwapSettlement(pendingSwap: BoltzSubmarineSwap): Promise<{
100
103
  preimage: string;
101
104
  }>;
105
+ waitForSwapFunded(pendingSwap: BoltzSubmarineSwap): Promise<void>;
102
106
  restoreSwaps(boltzFees?: FeesResponse): Promise<{
103
107
  chainSwaps: BoltzChainSwap[];
104
108
  reverseSwaps: BoltzReverseSwap[];
@@ -1,7 +1,7 @@
1
- import { I as IArkadeSwaps, A as ArkadeSwaps, Q as QuoteSwapOptions, V as VhtlcTimeouts } from '../arkade-swaps-DnRiRcdW.js';
2
- import { o as SwapManagerClient, C as CreateLightningInvoiceRequest, e as CreateLightningInvoiceResponse, S as SendLightningPaymentRequest, f as SendLightningPaymentResponse, c as BoltzSubmarineSwap, b as BoltzReverseSwap, g as SubmarineRefundOutcome, h as SubmarineRecoveryInfo, i as SubmarineRecoveryResult, F as FeesResponse, a as BoltzChainSwap, k as ArkToBtcResponse, m as ChainArkRefundOutcome, l as BtcToArkResponse, d as Chain, j as ChainFeesResponse, L as LimitsResponse, G as GetSwapStatusResponse, B as BoltzSwap } from '../types-D97i1LFu.js';
3
- import { E as ExpoArkadeSwapsConfig } from '../swapsPollProcessor-Bv4Z2R7g.js';
4
- export { D as DefineSwapBackgroundTaskOptions, b as ExpoArkadeLightningConfig, c as ExpoSwapBackgroundConfig, P as PersistedSwapBackgroundConfig, S as SWAP_POLL_TASK_TYPE, a as SwapTaskDependencies } from '../swapsPollProcessor-Bv4Z2R7g.js';
1
+ import { I as IArkadeSwaps, A as ArkadeSwaps, Q as QuoteSwapOptions, V as VhtlcTimeouts } from '../arkade-swaps-LvsGHtre.js';
2
+ import { n as SwapManagerClient, C as CreateLightningInvoiceRequest, e as CreateLightningInvoiceResponse, S as SendLightningPaymentRequest, o as SendLightningPaymentResponse, O as OptimisticSendLightningPaymentResponse, c as BoltzSubmarineSwap, b as BoltzReverseSwap, f as SubmarineRefundOutcome, g as SubmarineRecoveryInfo, h as SubmarineRecoveryResult, F as FeesResponse, a as BoltzChainSwap, j as ArkToBtcResponse, l as ChainArkRefundOutcome, k as BtcToArkResponse, d as Chain, i as ChainFeesResponse, L as LimitsResponse, G as GetSwapStatusResponse, B as BoltzSwap } from '../types-8NrCdOpS.js';
3
+ import { E as ExpoArkadeSwapsConfig } from '../swapsPollProcessor-CuDM6sxV.js';
4
+ export { D as DefineSwapBackgroundTaskOptions, b as ExpoArkadeLightningConfig, c as ExpoSwapBackgroundConfig, P as PersistedSwapBackgroundConfig, S as SWAP_POLL_TASK_TYPE, a as SwapTaskDependencies } from '../swapsPollProcessor-CuDM6sxV.js';
5
5
  import { ArkInfo, Identity, ArkTxInput, VHTLC } from '@arkade-os/sdk';
6
6
  import { TransactionOutput } from '@scure/btc-signer/psbt.js';
7
7
  import '@arkade-os/sdk/worker/expo';
@@ -84,7 +84,10 @@ declare class ExpoArkadeSwaps implements IArkadeSwaps {
84
84
  stopSwapManager(): Promise<void>;
85
85
  getSwapManager(): SwapManagerClient | null;
86
86
  createLightningInvoice(args: CreateLightningInvoiceRequest): Promise<CreateLightningInvoiceResponse>;
87
- sendLightningPayment(args: SendLightningPaymentRequest): Promise<SendLightningPaymentResponse>;
87
+ sendLightningPayment(args: SendLightningPaymentRequest & {
88
+ waitFor?: "settled";
89
+ }): Promise<SendLightningPaymentResponse>;
90
+ sendLightningPayment(args: SendLightningPaymentRequest): Promise<OptimisticSendLightningPaymentResponse>;
88
91
  createSubmarineSwap(args: SendLightningPaymentRequest): Promise<BoltzSubmarineSwap>;
89
92
  createReverseSwap(args: CreateLightningInvoiceRequest): Promise<BoltzReverseSwap>;
90
93
  claimVHTLC(pendingSwap: BoltzReverseSwap): Promise<void>;
@@ -99,6 +102,7 @@ declare class ExpoArkadeSwaps implements IArkadeSwaps {
99
102
  waitForSwapSettlement(pendingSwap: BoltzSubmarineSwap): Promise<{
100
103
  preimage: string;
101
104
  }>;
105
+ waitForSwapFunded(pendingSwap: BoltzSubmarineSwap): Promise<void>;
102
106
  restoreSwaps(boltzFees?: FeesResponse): Promise<{
103
107
  chainSwaps: BoltzChainSwap[];
104
108
  reverseSwaps: BoltzReverseSwap[];
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  SWAP_POLL_TASK_TYPE
3
- } from "../chunk-WGLBFONB.js";
3
+ } from "../chunk-CWY37W4B.js";
4
4
  import {
5
5
  ArkadeSwaps
6
- } from "../chunk-GYWMQOCP.js";
6
+ } from "../chunk-UXYHW7KV.js";
7
7
  import "../chunk-SJQJQO7P.js";
8
8
 
9
9
  // src/expo/arkade-lightning.ts
@@ -162,6 +162,9 @@ var ExpoArkadeSwaps = class _ExpoArkadeSwaps {
162
162
  waitForSwapSettlement(pendingSwap) {
163
163
  return this.inner.waitForSwapSettlement(pendingSwap);
164
164
  }
165
+ waitForSwapFunded(pendingSwap) {
166
+ return this.inner.waitForSwapFunded(pendingSwap);
167
+ }
165
168
  restoreSwaps(boltzFees) {
166
169
  return this.inner.restoreSwaps(boltzFees);
167
170
  }