@arkade-os/boltz-swap 0.3.7 → 0.3.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{arkade-swaps-MmMjdK2G.d.ts → arkade-swaps--vc0H2oD.d.cts} +15 -1
- package/dist/{arkade-swaps-DnhnGtTb.d.cts → arkade-swaps-qQuX73sR.d.ts} +15 -1
- package/dist/{background-RLZLTWCI.js → background-VM6FN7TU.js} +2 -2
- package/dist/{chunk-XUBVFCQZ.js → chunk-3XJR3RIH.js} +1 -1
- package/dist/{chunk-ZJ2Q5QSA.js → chunk-NUR5GPRK.js} +91 -12
- package/dist/expo/index.cjs +101 -12
- package/dist/expo/index.d.cts +9 -2
- package/dist/expo/index.d.ts +9 -2
- package/dist/expo/index.js +14 -4
- package/dist/index.cjs +231 -28
- package/dist/index.d.cts +19 -4
- package/dist/index.d.ts +19 -4
- package/dist/index.js +144 -17
- package/dist/repositories/realm/index.d.cts +1 -1
- package/dist/repositories/realm/index.d.ts +1 -1
- package/dist/repositories/sqlite/index.d.cts +1 -1
- package/dist/repositories/sqlite/index.d.ts +1 -1
- package/dist/{types-DCCYGYCD.d.cts → types-CEmBBA71.d.cts} +2 -0
- package/dist/{types-DCCYGYCD.d.ts → types-CEmBBA71.d.ts} +2 -0
- package/package.json +2 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { IWallet, ArkProvider, IndexerProvider, ArkInfo, Identity, ArkTxInput, VHTLC } from '@arkade-os/sdk';
|
|
2
|
-
import { l as BoltzSwapProvider, V as SwapManager, i as SwapRepository, X as ArkadeSwapsCreateConfig, A as ArkadeSwapsConfig, j as SwapManagerClient, C as CreateLightningInvoiceRequest, e as CreateLightningInvoiceResponse, b as PendingReverseSwap, S as SendLightningPaymentRequest, f as SendLightningPaymentResponse, c as PendingSubmarineSwap, h as ArkToBtcResponse, a as PendingChainSwap, B as BtcToArkResponse, d as Chain, F as FeesResponse, g as ChainFeesResponse, L as LimitsResponse, G as GetSwapStatusResponse, P as PendingSwap } from './types-
|
|
2
|
+
import { l as BoltzSwapProvider, V as SwapManager, i as SwapRepository, X as ArkadeSwapsCreateConfig, A as ArkadeSwapsConfig, j as SwapManagerClient, C as CreateLightningInvoiceRequest, e as CreateLightningInvoiceResponse, b as PendingReverseSwap, S as SendLightningPaymentRequest, f as SendLightningPaymentResponse, c as PendingSubmarineSwap, h as ArkToBtcResponse, a as PendingChainSwap, B as BtcToArkResponse, d as Chain, F as FeesResponse, g as ChainFeesResponse, L as LimitsResponse, G as GetSwapStatusResponse, P as PendingSwap } from './types-CEmBBA71.cjs';
|
|
3
3
|
import { TransactionOutput } from '@scure/btc-signer/psbt.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -68,6 +68,13 @@ declare class ArkadeSwaps {
|
|
|
68
68
|
* Dispose of resources (stops SwapManager and cleans up).
|
|
69
69
|
* Can be called manually or automatically with `await using` syntax (TypeScript 5.2+).
|
|
70
70
|
*/
|
|
71
|
+
/**
|
|
72
|
+
* Reset all swap state: stops the SwapManager and clears the swap repository.
|
|
73
|
+
*
|
|
74
|
+
* **Destructive** — any swap in a non-terminal state will lose its
|
|
75
|
+
* refund/claim path. Intended for wallet-reset / dev / test scenarios only.
|
|
76
|
+
*/
|
|
77
|
+
reset(): Promise<void>;
|
|
71
78
|
dispose(): Promise<void>;
|
|
72
79
|
/**
|
|
73
80
|
* Symbol.asyncDispose for automatic cleanup with `await using` syntax.
|
|
@@ -426,6 +433,13 @@ interface IArkadeSwaps extends AsyncDisposable {
|
|
|
426
433
|
getSwapStatus(swapId: string): Promise<GetSwapStatusResponse>;
|
|
427
434
|
enrichReverseSwapPreimage(swap: PendingReverseSwap, preimage: string): PendingReverseSwap;
|
|
428
435
|
enrichSubmarineSwapInvoice(swap: PendingSubmarineSwap, invoice: string): PendingSubmarineSwap;
|
|
436
|
+
/**
|
|
437
|
+
* Reset all swap state: stops the SwapManager and clears the swap repository.
|
|
438
|
+
*
|
|
439
|
+
* **Destructive** — any swap in a non-terminal state will lose its
|
|
440
|
+
* refund/claim path. Intended for wallet-reset / dev / test scenarios only.
|
|
441
|
+
*/
|
|
442
|
+
reset(): Promise<void>;
|
|
429
443
|
dispose(): Promise<void>;
|
|
430
444
|
}
|
|
431
445
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { IWallet, ArkProvider, IndexerProvider, ArkInfo, Identity, ArkTxInput, VHTLC } from '@arkade-os/sdk';
|
|
2
|
-
import { l as BoltzSwapProvider, V as SwapManager, i as SwapRepository, X as ArkadeSwapsCreateConfig, A as ArkadeSwapsConfig, j as SwapManagerClient, C as CreateLightningInvoiceRequest, e as CreateLightningInvoiceResponse, b as PendingReverseSwap, S as SendLightningPaymentRequest, f as SendLightningPaymentResponse, c as PendingSubmarineSwap, h as ArkToBtcResponse, a as PendingChainSwap, B as BtcToArkResponse, d as Chain, F as FeesResponse, g as ChainFeesResponse, L as LimitsResponse, G as GetSwapStatusResponse, P as PendingSwap } from './types-
|
|
2
|
+
import { l as BoltzSwapProvider, V as SwapManager, i as SwapRepository, X as ArkadeSwapsCreateConfig, A as ArkadeSwapsConfig, j as SwapManagerClient, C as CreateLightningInvoiceRequest, e as CreateLightningInvoiceResponse, b as PendingReverseSwap, S as SendLightningPaymentRequest, f as SendLightningPaymentResponse, c as PendingSubmarineSwap, h as ArkToBtcResponse, a as PendingChainSwap, B as BtcToArkResponse, d as Chain, F as FeesResponse, g as ChainFeesResponse, L as LimitsResponse, G as GetSwapStatusResponse, P as PendingSwap } from './types-CEmBBA71.js';
|
|
3
3
|
import { TransactionOutput } from '@scure/btc-signer/psbt.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -68,6 +68,13 @@ declare class ArkadeSwaps {
|
|
|
68
68
|
* Dispose of resources (stops SwapManager and cleans up).
|
|
69
69
|
* Can be called manually or automatically with `await using` syntax (TypeScript 5.2+).
|
|
70
70
|
*/
|
|
71
|
+
/**
|
|
72
|
+
* Reset all swap state: stops the SwapManager and clears the swap repository.
|
|
73
|
+
*
|
|
74
|
+
* **Destructive** — any swap in a non-terminal state will lose its
|
|
75
|
+
* refund/claim path. Intended for wallet-reset / dev / test scenarios only.
|
|
76
|
+
*/
|
|
77
|
+
reset(): Promise<void>;
|
|
71
78
|
dispose(): Promise<void>;
|
|
72
79
|
/**
|
|
73
80
|
* Symbol.asyncDispose for automatic cleanup with `await using` syntax.
|
|
@@ -426,6 +433,13 @@ interface IArkadeSwaps extends AsyncDisposable {
|
|
|
426
433
|
getSwapStatus(swapId: string): Promise<GetSwapStatusResponse>;
|
|
427
434
|
enrichReverseSwapPreimage(swap: PendingReverseSwap, preimage: string): PendingReverseSwap;
|
|
428
435
|
enrichSubmarineSwapInvoice(swap: PendingSubmarineSwap, invoice: string): PendingSubmarineSwap;
|
|
436
|
+
/**
|
|
437
|
+
* Reset all swap state: stops the SwapManager and clears the swap repository.
|
|
438
|
+
*
|
|
439
|
+
* **Destructive** — any swap in a non-terminal state will lose its
|
|
440
|
+
* refund/claim path. Intended for wallet-reset / dev / test scenarios only.
|
|
441
|
+
*/
|
|
442
|
+
reset(): Promise<void>;
|
|
429
443
|
dispose(): Promise<void>;
|
|
430
444
|
}
|
|
431
445
|
|
|
@@ -2,8 +2,8 @@ import {
|
|
|
2
2
|
defineExpoSwapBackgroundTask,
|
|
3
3
|
registerExpoSwapBackgroundTask,
|
|
4
4
|
unregisterExpoSwapBackgroundTask
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-3XJR3RIH.js";
|
|
6
|
+
import "./chunk-NUR5GPRK.js";
|
|
7
7
|
import "./chunk-3RG5ZIWI.js";
|
|
8
8
|
export {
|
|
9
9
|
defineExpoSwapBackgroundTask,
|
|
@@ -865,6 +865,8 @@ var SwapManager = class {
|
|
|
865
865
|
// All swaps passed to start(), including completed ones
|
|
866
866
|
pollTimer = null;
|
|
867
867
|
reconnectTimer = null;
|
|
868
|
+
initialPollTimer = null;
|
|
869
|
+
pollRetryTimers = /* @__PURE__ */ new Map();
|
|
868
870
|
isRunning = false;
|
|
869
871
|
currentReconnectDelay;
|
|
870
872
|
currentPollRetryDelay;
|
|
@@ -1048,6 +1050,14 @@ var SwapManager = class {
|
|
|
1048
1050
|
clearTimeout(this.reconnectTimer);
|
|
1049
1051
|
this.reconnectTimer = null;
|
|
1050
1052
|
}
|
|
1053
|
+
if (this.initialPollTimer) {
|
|
1054
|
+
clearTimeout(this.initialPollTimer);
|
|
1055
|
+
this.initialPollTimer = null;
|
|
1056
|
+
}
|
|
1057
|
+
for (const timer of this.pollRetryTimers.values()) {
|
|
1058
|
+
clearTimeout(timer);
|
|
1059
|
+
}
|
|
1060
|
+
this.pollRetryTimers.clear();
|
|
1051
1061
|
}
|
|
1052
1062
|
/**
|
|
1053
1063
|
* Set the polling interval (ms).
|
|
@@ -1103,6 +1113,11 @@ var SwapManager = class {
|
|
|
1103
1113
|
async removeSwap(swapId) {
|
|
1104
1114
|
this.monitoredSwaps.delete(swapId);
|
|
1105
1115
|
this.swapSubscriptions.delete(swapId);
|
|
1116
|
+
const retryTimer = this.pollRetryTimers.get(swapId);
|
|
1117
|
+
if (retryTimer) {
|
|
1118
|
+
clearTimeout(retryTimer);
|
|
1119
|
+
this.pollRetryTimers.delete(swapId);
|
|
1120
|
+
}
|
|
1106
1121
|
logger.log(`Removed swap ${swapId} from monitoring`);
|
|
1107
1122
|
}
|
|
1108
1123
|
/**
|
|
@@ -1253,12 +1268,25 @@ var SwapManager = class {
|
|
|
1253
1268
|
for (const swapId of this.monitoredSwaps.keys()) {
|
|
1254
1269
|
this.subscribeToSwap(swapId);
|
|
1255
1270
|
}
|
|
1256
|
-
this.
|
|
1271
|
+
if (this.initialPollTimer) {
|
|
1272
|
+
clearTimeout(this.initialPollTimer);
|
|
1273
|
+
this.initialPollTimer = null;
|
|
1274
|
+
}
|
|
1275
|
+
this.initialPollTimer = setTimeout(() => {
|
|
1276
|
+
this.initialPollTimer = null;
|
|
1277
|
+
if (this.isRunning) {
|
|
1278
|
+
this.pollAllSwaps();
|
|
1279
|
+
}
|
|
1280
|
+
}, 2e3);
|
|
1257
1281
|
this.startPolling();
|
|
1258
1282
|
this.wsConnectedListeners.forEach((listener) => listener());
|
|
1259
1283
|
};
|
|
1260
1284
|
this.websocket.onclose = () => {
|
|
1261
1285
|
clearTimeout(connectionTimeout);
|
|
1286
|
+
if (this.initialPollTimer) {
|
|
1287
|
+
clearTimeout(this.initialPollTimer);
|
|
1288
|
+
this.initialPollTimer = null;
|
|
1289
|
+
}
|
|
1262
1290
|
this.websocket = null;
|
|
1263
1291
|
if (this.isRunning) {
|
|
1264
1292
|
this.scheduleReconnect();
|
|
@@ -1287,6 +1315,10 @@ var SwapManager = class {
|
|
|
1287
1315
|
*/
|
|
1288
1316
|
enterPollingFallback(error) {
|
|
1289
1317
|
if (!this.isRunning) return;
|
|
1318
|
+
if (this.initialPollTimer) {
|
|
1319
|
+
clearTimeout(this.initialPollTimer);
|
|
1320
|
+
this.initialPollTimer = null;
|
|
1321
|
+
}
|
|
1290
1322
|
this.isReconnecting = false;
|
|
1291
1323
|
this.websocket = null;
|
|
1292
1324
|
this.usePollingFallback = true;
|
|
@@ -1388,6 +1420,11 @@ var SwapManager = class {
|
|
|
1388
1420
|
if (this.isFinalStatus(swap)) {
|
|
1389
1421
|
this.monitoredSwaps.delete(swap.id);
|
|
1390
1422
|
this.swapSubscriptions.delete(swap.id);
|
|
1423
|
+
const retryTimer = this.pollRetryTimers.get(swap.id);
|
|
1424
|
+
if (retryTimer) {
|
|
1425
|
+
clearTimeout(retryTimer);
|
|
1426
|
+
this.pollRetryTimers.delete(swap.id);
|
|
1427
|
+
}
|
|
1391
1428
|
this.swapCompletedListeners.forEach((listener) => listener(swap));
|
|
1392
1429
|
}
|
|
1393
1430
|
}
|
|
@@ -1652,7 +1689,37 @@ var SwapManager = class {
|
|
|
1652
1689
|
);
|
|
1653
1690
|
}
|
|
1654
1691
|
} catch (error) {
|
|
1655
|
-
|
|
1692
|
+
if (error instanceof NetworkError && error.statusCode === 429) {
|
|
1693
|
+
logger.warn(
|
|
1694
|
+
`Rate-limited polling swap ${swap.id}, retrying in 2s`
|
|
1695
|
+
);
|
|
1696
|
+
const existing = this.pollRetryTimers.get(swap.id);
|
|
1697
|
+
if (existing) clearTimeout(existing);
|
|
1698
|
+
this.pollRetryTimers.set(
|
|
1699
|
+
swap.id,
|
|
1700
|
+
setTimeout(async () => {
|
|
1701
|
+
this.pollRetryTimers.delete(swap.id);
|
|
1702
|
+
try {
|
|
1703
|
+
const retry = await this.swapProvider.getSwapStatus(
|
|
1704
|
+
swap.id
|
|
1705
|
+
);
|
|
1706
|
+
if (retry.status !== swap.status) {
|
|
1707
|
+
await this.handleSwapStatusUpdate(
|
|
1708
|
+
swap,
|
|
1709
|
+
retry.status
|
|
1710
|
+
);
|
|
1711
|
+
}
|
|
1712
|
+
} catch (retryError) {
|
|
1713
|
+
logger.error(
|
|
1714
|
+
`Retry poll for swap ${swap.id} also failed:`,
|
|
1715
|
+
retryError
|
|
1716
|
+
);
|
|
1717
|
+
}
|
|
1718
|
+
}, 2e3)
|
|
1719
|
+
);
|
|
1720
|
+
} else {
|
|
1721
|
+
logger.error(`Failed to poll swap ${swap.id}:`, error);
|
|
1722
|
+
}
|
|
1656
1723
|
}
|
|
1657
1724
|
}
|
|
1658
1725
|
);
|
|
@@ -3039,6 +3106,16 @@ var ArkadeSwaps = class _ArkadeSwaps {
|
|
|
3039
3106
|
* Dispose of resources (stops SwapManager and cleans up).
|
|
3040
3107
|
* Can be called manually or automatically with `await using` syntax (TypeScript 5.2+).
|
|
3041
3108
|
*/
|
|
3109
|
+
/**
|
|
3110
|
+
* Reset all swap state: stops the SwapManager and clears the swap repository.
|
|
3111
|
+
*
|
|
3112
|
+
* **Destructive** — any swap in a non-terminal state will lose its
|
|
3113
|
+
* refund/claim path. Intended for wallet-reset / dev / test scenarios only.
|
|
3114
|
+
*/
|
|
3115
|
+
async reset() {
|
|
3116
|
+
await this.dispose();
|
|
3117
|
+
await this.swapRepository.clear();
|
|
3118
|
+
}
|
|
3042
3119
|
async dispose() {
|
|
3043
3120
|
if (this.swapManager) {
|
|
3044
3121
|
await this.stopSwapManager();
|
|
@@ -4409,16 +4486,18 @@ var ArkadeSwaps = class _ArkadeSwaps {
|
|
|
4409
4486
|
} else if (isRestoredSubmarineSwap(swap)) {
|
|
4410
4487
|
const { amount, lockupAddress, serverPublicKey, tree } = swap.refundDetails;
|
|
4411
4488
|
let preimage = "";
|
|
4412
|
-
|
|
4413
|
-
|
|
4414
|
-
|
|
4415
|
-
|
|
4416
|
-
|
|
4417
|
-
|
|
4418
|
-
|
|
4419
|
-
|
|
4420
|
-
|
|
4421
|
-
|
|
4489
|
+
if (!isSubmarineFinalStatus(status)) {
|
|
4490
|
+
try {
|
|
4491
|
+
const data = await this.swapProvider.getSwapPreimage(
|
|
4492
|
+
swap.id
|
|
4493
|
+
);
|
|
4494
|
+
preimage = data.preimage;
|
|
4495
|
+
} catch (error) {
|
|
4496
|
+
logger.warn(
|
|
4497
|
+
`Failed to restore preimage for submarine swap ${id}`,
|
|
4498
|
+
error
|
|
4499
|
+
);
|
|
4500
|
+
}
|
|
4422
4501
|
}
|
|
4423
4502
|
submarineSwaps.push({
|
|
4424
4503
|
id,
|
package/dist/expo/index.cjs
CHANGED
|
@@ -1277,6 +1277,8 @@ var init_swap_manager = __esm({
|
|
|
1277
1277
|
// All swaps passed to start(), including completed ones
|
|
1278
1278
|
pollTimer = null;
|
|
1279
1279
|
reconnectTimer = null;
|
|
1280
|
+
initialPollTimer = null;
|
|
1281
|
+
pollRetryTimers = /* @__PURE__ */ new Map();
|
|
1280
1282
|
isRunning = false;
|
|
1281
1283
|
currentReconnectDelay;
|
|
1282
1284
|
currentPollRetryDelay;
|
|
@@ -1460,6 +1462,14 @@ var init_swap_manager = __esm({
|
|
|
1460
1462
|
clearTimeout(this.reconnectTimer);
|
|
1461
1463
|
this.reconnectTimer = null;
|
|
1462
1464
|
}
|
|
1465
|
+
if (this.initialPollTimer) {
|
|
1466
|
+
clearTimeout(this.initialPollTimer);
|
|
1467
|
+
this.initialPollTimer = null;
|
|
1468
|
+
}
|
|
1469
|
+
for (const timer of this.pollRetryTimers.values()) {
|
|
1470
|
+
clearTimeout(timer);
|
|
1471
|
+
}
|
|
1472
|
+
this.pollRetryTimers.clear();
|
|
1463
1473
|
}
|
|
1464
1474
|
/**
|
|
1465
1475
|
* Set the polling interval (ms).
|
|
@@ -1515,6 +1525,11 @@ var init_swap_manager = __esm({
|
|
|
1515
1525
|
async removeSwap(swapId) {
|
|
1516
1526
|
this.monitoredSwaps.delete(swapId);
|
|
1517
1527
|
this.swapSubscriptions.delete(swapId);
|
|
1528
|
+
const retryTimer = this.pollRetryTimers.get(swapId);
|
|
1529
|
+
if (retryTimer) {
|
|
1530
|
+
clearTimeout(retryTimer);
|
|
1531
|
+
this.pollRetryTimers.delete(swapId);
|
|
1532
|
+
}
|
|
1518
1533
|
logger.log(`Removed swap ${swapId} from monitoring`);
|
|
1519
1534
|
}
|
|
1520
1535
|
/**
|
|
@@ -1665,12 +1680,25 @@ var init_swap_manager = __esm({
|
|
|
1665
1680
|
for (const swapId of this.monitoredSwaps.keys()) {
|
|
1666
1681
|
this.subscribeToSwap(swapId);
|
|
1667
1682
|
}
|
|
1668
|
-
this.
|
|
1683
|
+
if (this.initialPollTimer) {
|
|
1684
|
+
clearTimeout(this.initialPollTimer);
|
|
1685
|
+
this.initialPollTimer = null;
|
|
1686
|
+
}
|
|
1687
|
+
this.initialPollTimer = setTimeout(() => {
|
|
1688
|
+
this.initialPollTimer = null;
|
|
1689
|
+
if (this.isRunning) {
|
|
1690
|
+
this.pollAllSwaps();
|
|
1691
|
+
}
|
|
1692
|
+
}, 2e3);
|
|
1669
1693
|
this.startPolling();
|
|
1670
1694
|
this.wsConnectedListeners.forEach((listener) => listener());
|
|
1671
1695
|
};
|
|
1672
1696
|
this.websocket.onclose = () => {
|
|
1673
1697
|
clearTimeout(connectionTimeout);
|
|
1698
|
+
if (this.initialPollTimer) {
|
|
1699
|
+
clearTimeout(this.initialPollTimer);
|
|
1700
|
+
this.initialPollTimer = null;
|
|
1701
|
+
}
|
|
1674
1702
|
this.websocket = null;
|
|
1675
1703
|
if (this.isRunning) {
|
|
1676
1704
|
this.scheduleReconnect();
|
|
@@ -1699,6 +1727,10 @@ var init_swap_manager = __esm({
|
|
|
1699
1727
|
*/
|
|
1700
1728
|
enterPollingFallback(error) {
|
|
1701
1729
|
if (!this.isRunning) return;
|
|
1730
|
+
if (this.initialPollTimer) {
|
|
1731
|
+
clearTimeout(this.initialPollTimer);
|
|
1732
|
+
this.initialPollTimer = null;
|
|
1733
|
+
}
|
|
1702
1734
|
this.isReconnecting = false;
|
|
1703
1735
|
this.websocket = null;
|
|
1704
1736
|
this.usePollingFallback = true;
|
|
@@ -1800,6 +1832,11 @@ var init_swap_manager = __esm({
|
|
|
1800
1832
|
if (this.isFinalStatus(swap)) {
|
|
1801
1833
|
this.monitoredSwaps.delete(swap.id);
|
|
1802
1834
|
this.swapSubscriptions.delete(swap.id);
|
|
1835
|
+
const retryTimer = this.pollRetryTimers.get(swap.id);
|
|
1836
|
+
if (retryTimer) {
|
|
1837
|
+
clearTimeout(retryTimer);
|
|
1838
|
+
this.pollRetryTimers.delete(swap.id);
|
|
1839
|
+
}
|
|
1803
1840
|
this.swapCompletedListeners.forEach((listener) => listener(swap));
|
|
1804
1841
|
}
|
|
1805
1842
|
}
|
|
@@ -2064,7 +2101,37 @@ var init_swap_manager = __esm({
|
|
|
2064
2101
|
);
|
|
2065
2102
|
}
|
|
2066
2103
|
} catch (error) {
|
|
2067
|
-
|
|
2104
|
+
if (error instanceof NetworkError && error.statusCode === 429) {
|
|
2105
|
+
logger.warn(
|
|
2106
|
+
`Rate-limited polling swap ${swap.id}, retrying in 2s`
|
|
2107
|
+
);
|
|
2108
|
+
const existing = this.pollRetryTimers.get(swap.id);
|
|
2109
|
+
if (existing) clearTimeout(existing);
|
|
2110
|
+
this.pollRetryTimers.set(
|
|
2111
|
+
swap.id,
|
|
2112
|
+
setTimeout(async () => {
|
|
2113
|
+
this.pollRetryTimers.delete(swap.id);
|
|
2114
|
+
try {
|
|
2115
|
+
const retry = await this.swapProvider.getSwapStatus(
|
|
2116
|
+
swap.id
|
|
2117
|
+
);
|
|
2118
|
+
if (retry.status !== swap.status) {
|
|
2119
|
+
await this.handleSwapStatusUpdate(
|
|
2120
|
+
swap,
|
|
2121
|
+
retry.status
|
|
2122
|
+
);
|
|
2123
|
+
}
|
|
2124
|
+
} catch (retryError) {
|
|
2125
|
+
logger.error(
|
|
2126
|
+
`Retry poll for swap ${swap.id} also failed:`,
|
|
2127
|
+
retryError
|
|
2128
|
+
);
|
|
2129
|
+
}
|
|
2130
|
+
}, 2e3)
|
|
2131
|
+
);
|
|
2132
|
+
} else {
|
|
2133
|
+
logger.error(`Failed to poll swap ${swap.id}:`, error);
|
|
2134
|
+
}
|
|
2068
2135
|
}
|
|
2069
2136
|
}
|
|
2070
2137
|
);
|
|
@@ -3044,6 +3111,16 @@ var init_arkade_swaps = __esm({
|
|
|
3044
3111
|
* Dispose of resources (stops SwapManager and cleans up).
|
|
3045
3112
|
* Can be called manually or automatically with `await using` syntax (TypeScript 5.2+).
|
|
3046
3113
|
*/
|
|
3114
|
+
/**
|
|
3115
|
+
* Reset all swap state: stops the SwapManager and clears the swap repository.
|
|
3116
|
+
*
|
|
3117
|
+
* **Destructive** — any swap in a non-terminal state will lose its
|
|
3118
|
+
* refund/claim path. Intended for wallet-reset / dev / test scenarios only.
|
|
3119
|
+
*/
|
|
3120
|
+
async reset() {
|
|
3121
|
+
await this.dispose();
|
|
3122
|
+
await this.swapRepository.clear();
|
|
3123
|
+
}
|
|
3047
3124
|
async dispose() {
|
|
3048
3125
|
if (this.swapManager) {
|
|
3049
3126
|
await this.stopSwapManager();
|
|
@@ -4414,16 +4491,18 @@ var init_arkade_swaps = __esm({
|
|
|
4414
4491
|
} else if (isRestoredSubmarineSwap(swap)) {
|
|
4415
4492
|
const { amount, lockupAddress, serverPublicKey, tree } = swap.refundDetails;
|
|
4416
4493
|
let preimage = "";
|
|
4417
|
-
|
|
4418
|
-
|
|
4419
|
-
|
|
4420
|
-
|
|
4421
|
-
|
|
4422
|
-
|
|
4423
|
-
|
|
4424
|
-
|
|
4425
|
-
|
|
4426
|
-
|
|
4494
|
+
if (!isSubmarineFinalStatus(status)) {
|
|
4495
|
+
try {
|
|
4496
|
+
const data = await this.swapProvider.getSwapPreimage(
|
|
4497
|
+
swap.id
|
|
4498
|
+
);
|
|
4499
|
+
preimage = data.preimage;
|
|
4500
|
+
} catch (error) {
|
|
4501
|
+
logger.warn(
|
|
4502
|
+
`Failed to restore preimage for submarine swap ${id}`,
|
|
4503
|
+
error
|
|
4504
|
+
);
|
|
4505
|
+
}
|
|
4427
4506
|
}
|
|
4428
4507
|
submarineSwaps.push({
|
|
4429
4508
|
id,
|
|
@@ -4887,6 +4966,16 @@ var ExpoArkadeSwaps = class _ExpoArkadeSwaps {
|
|
|
4887
4966
|
await taskQueue.addTask(task);
|
|
4888
4967
|
}
|
|
4889
4968
|
// ── Lifecycle ────────────────────────────────────────────────────
|
|
4969
|
+
/**
|
|
4970
|
+
* Reset all swap state: stops polling and clears the swap repository.
|
|
4971
|
+
*
|
|
4972
|
+
* **Destructive** — any swap in a non-terminal state will lose its
|
|
4973
|
+
* refund/claim path. Intended for wallet-reset / dev / test scenarios only.
|
|
4974
|
+
*/
|
|
4975
|
+
async reset() {
|
|
4976
|
+
await this.dispose();
|
|
4977
|
+
await this.inner.swapRepository.clear();
|
|
4978
|
+
}
|
|
4890
4979
|
async dispose() {
|
|
4891
4980
|
if (this.foregroundIntervalId) {
|
|
4892
4981
|
clearInterval(this.foregroundIntervalId);
|
package/dist/expo/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { I as IArkadeSwaps, A as ArkadeSwaps } from '../arkade-swaps
|
|
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-
|
|
1
|
+
import { I as IArkadeSwaps, A as ArkadeSwaps } from '../arkade-swaps--vc0H2oD.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-CEmBBA71.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';
|
|
@@ -124,6 +124,13 @@ declare class ExpoArkadeSwaps implements IArkadeSwaps {
|
|
|
124
124
|
private startForegroundPolling;
|
|
125
125
|
private runForegroundPoll;
|
|
126
126
|
private seedSwapPollTask;
|
|
127
|
+
/**
|
|
128
|
+
* Reset all swap state: stops polling and clears the swap repository.
|
|
129
|
+
*
|
|
130
|
+
* **Destructive** — any swap in a non-terminal state will lose its
|
|
131
|
+
* refund/claim path. Intended for wallet-reset / dev / test scenarios only.
|
|
132
|
+
*/
|
|
133
|
+
reset(): Promise<void>;
|
|
127
134
|
dispose(): Promise<void>;
|
|
128
135
|
[Symbol.asyncDispose](): Promise<void>;
|
|
129
136
|
startSwapManager(): Promise<void>;
|
package/dist/expo/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { I as IArkadeSwaps, A as ArkadeSwaps } from '../arkade-swaps-
|
|
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-
|
|
1
|
+
import { I as IArkadeSwaps, A as ArkadeSwaps } from '../arkade-swaps-qQuX73sR.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-CEmBBA71.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';
|
|
@@ -124,6 +124,13 @@ declare class ExpoArkadeSwaps implements IArkadeSwaps {
|
|
|
124
124
|
private startForegroundPolling;
|
|
125
125
|
private runForegroundPoll;
|
|
126
126
|
private seedSwapPollTask;
|
|
127
|
+
/**
|
|
128
|
+
* Reset all swap state: stops polling and clears the swap repository.
|
|
129
|
+
*
|
|
130
|
+
* **Destructive** — any swap in a non-terminal state will lose its
|
|
131
|
+
* refund/claim path. Intended for wallet-reset / dev / test scenarios only.
|
|
132
|
+
*/
|
|
133
|
+
reset(): Promise<void>;
|
|
127
134
|
dispose(): Promise<void>;
|
|
128
135
|
[Symbol.asyncDispose](): Promise<void>;
|
|
129
136
|
startSwapManager(): Promise<void>;
|
package/dist/expo/index.js
CHANGED
|
@@ -4,10 +4,10 @@ import {
|
|
|
4
4
|
registerExpoSwapBackgroundTask,
|
|
5
5
|
swapsPollProcessor,
|
|
6
6
|
unregisterExpoSwapBackgroundTask
|
|
7
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-3XJR3RIH.js";
|
|
8
8
|
import {
|
|
9
9
|
ArkadeSwaps
|
|
10
|
-
} from "../chunk-
|
|
10
|
+
} from "../chunk-NUR5GPRK.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-
|
|
59
|
+
const { registerExpoSwapBackgroundTask: registerExpoSwapBackgroundTask2 } = await import("../background-VM6FN7TU.js");
|
|
60
60
|
await registerExpoSwapBackgroundTask2(
|
|
61
61
|
config.background.taskName,
|
|
62
62
|
{
|
|
@@ -112,6 +112,16 @@ var ExpoArkadeSwaps = class _ExpoArkadeSwaps {
|
|
|
112
112
|
await taskQueue.addTask(task);
|
|
113
113
|
}
|
|
114
114
|
// ── Lifecycle ────────────────────────────────────────────────────
|
|
115
|
+
/**
|
|
116
|
+
* Reset all swap state: stops polling and clears the swap repository.
|
|
117
|
+
*
|
|
118
|
+
* **Destructive** — any swap in a non-terminal state will lose its
|
|
119
|
+
* refund/claim path. Intended for wallet-reset / dev / test scenarios only.
|
|
120
|
+
*/
|
|
121
|
+
async reset() {
|
|
122
|
+
await this.dispose();
|
|
123
|
+
await this.inner.swapRepository.clear();
|
|
124
|
+
}
|
|
115
125
|
async dispose() {
|
|
116
126
|
if (this.foregroundIntervalId) {
|
|
117
127
|
clearInterval(this.foregroundIntervalId);
|
|
@@ -119,7 +129,7 @@ var ExpoArkadeSwaps = class _ExpoArkadeSwaps {
|
|
|
119
129
|
}
|
|
120
130
|
await this.inner.dispose();
|
|
121
131
|
try {
|
|
122
|
-
const { unregisterExpoSwapBackgroundTask: unregisterExpoSwapBackgroundTask2 } = await import("../background-
|
|
132
|
+
const { unregisterExpoSwapBackgroundTask: unregisterExpoSwapBackgroundTask2 } = await import("../background-VM6FN7TU.js");
|
|
123
133
|
await unregisterExpoSwapBackgroundTask2(this.taskName);
|
|
124
134
|
} catch (err) {
|
|
125
135
|
const message = err instanceof Error ? err.message : String(err);
|
package/dist/index.cjs
CHANGED
|
@@ -1383,6 +1383,8 @@ var SwapManager = class {
|
|
|
1383
1383
|
// All swaps passed to start(), including completed ones
|
|
1384
1384
|
pollTimer = null;
|
|
1385
1385
|
reconnectTimer = null;
|
|
1386
|
+
initialPollTimer = null;
|
|
1387
|
+
pollRetryTimers = /* @__PURE__ */ new Map();
|
|
1386
1388
|
isRunning = false;
|
|
1387
1389
|
currentReconnectDelay;
|
|
1388
1390
|
currentPollRetryDelay;
|
|
@@ -1566,6 +1568,14 @@ var SwapManager = class {
|
|
|
1566
1568
|
clearTimeout(this.reconnectTimer);
|
|
1567
1569
|
this.reconnectTimer = null;
|
|
1568
1570
|
}
|
|
1571
|
+
if (this.initialPollTimer) {
|
|
1572
|
+
clearTimeout(this.initialPollTimer);
|
|
1573
|
+
this.initialPollTimer = null;
|
|
1574
|
+
}
|
|
1575
|
+
for (const timer of this.pollRetryTimers.values()) {
|
|
1576
|
+
clearTimeout(timer);
|
|
1577
|
+
}
|
|
1578
|
+
this.pollRetryTimers.clear();
|
|
1569
1579
|
}
|
|
1570
1580
|
/**
|
|
1571
1581
|
* Set the polling interval (ms).
|
|
@@ -1621,6 +1631,11 @@ var SwapManager = class {
|
|
|
1621
1631
|
async removeSwap(swapId) {
|
|
1622
1632
|
this.monitoredSwaps.delete(swapId);
|
|
1623
1633
|
this.swapSubscriptions.delete(swapId);
|
|
1634
|
+
const retryTimer = this.pollRetryTimers.get(swapId);
|
|
1635
|
+
if (retryTimer) {
|
|
1636
|
+
clearTimeout(retryTimer);
|
|
1637
|
+
this.pollRetryTimers.delete(swapId);
|
|
1638
|
+
}
|
|
1624
1639
|
logger.log(`Removed swap ${swapId} from monitoring`);
|
|
1625
1640
|
}
|
|
1626
1641
|
/**
|
|
@@ -1771,12 +1786,25 @@ var SwapManager = class {
|
|
|
1771
1786
|
for (const swapId of this.monitoredSwaps.keys()) {
|
|
1772
1787
|
this.subscribeToSwap(swapId);
|
|
1773
1788
|
}
|
|
1774
|
-
this.
|
|
1789
|
+
if (this.initialPollTimer) {
|
|
1790
|
+
clearTimeout(this.initialPollTimer);
|
|
1791
|
+
this.initialPollTimer = null;
|
|
1792
|
+
}
|
|
1793
|
+
this.initialPollTimer = setTimeout(() => {
|
|
1794
|
+
this.initialPollTimer = null;
|
|
1795
|
+
if (this.isRunning) {
|
|
1796
|
+
this.pollAllSwaps();
|
|
1797
|
+
}
|
|
1798
|
+
}, 2e3);
|
|
1775
1799
|
this.startPolling();
|
|
1776
1800
|
this.wsConnectedListeners.forEach((listener) => listener());
|
|
1777
1801
|
};
|
|
1778
1802
|
this.websocket.onclose = () => {
|
|
1779
1803
|
clearTimeout(connectionTimeout);
|
|
1804
|
+
if (this.initialPollTimer) {
|
|
1805
|
+
clearTimeout(this.initialPollTimer);
|
|
1806
|
+
this.initialPollTimer = null;
|
|
1807
|
+
}
|
|
1780
1808
|
this.websocket = null;
|
|
1781
1809
|
if (this.isRunning) {
|
|
1782
1810
|
this.scheduleReconnect();
|
|
@@ -1805,6 +1833,10 @@ var SwapManager = class {
|
|
|
1805
1833
|
*/
|
|
1806
1834
|
enterPollingFallback(error) {
|
|
1807
1835
|
if (!this.isRunning) return;
|
|
1836
|
+
if (this.initialPollTimer) {
|
|
1837
|
+
clearTimeout(this.initialPollTimer);
|
|
1838
|
+
this.initialPollTimer = null;
|
|
1839
|
+
}
|
|
1808
1840
|
this.isReconnecting = false;
|
|
1809
1841
|
this.websocket = null;
|
|
1810
1842
|
this.usePollingFallback = true;
|
|
@@ -1906,6 +1938,11 @@ var SwapManager = class {
|
|
|
1906
1938
|
if (this.isFinalStatus(swap)) {
|
|
1907
1939
|
this.monitoredSwaps.delete(swap.id);
|
|
1908
1940
|
this.swapSubscriptions.delete(swap.id);
|
|
1941
|
+
const retryTimer = this.pollRetryTimers.get(swap.id);
|
|
1942
|
+
if (retryTimer) {
|
|
1943
|
+
clearTimeout(retryTimer);
|
|
1944
|
+
this.pollRetryTimers.delete(swap.id);
|
|
1945
|
+
}
|
|
1909
1946
|
this.swapCompletedListeners.forEach((listener) => listener(swap));
|
|
1910
1947
|
}
|
|
1911
1948
|
}
|
|
@@ -2170,7 +2207,37 @@ var SwapManager = class {
|
|
|
2170
2207
|
);
|
|
2171
2208
|
}
|
|
2172
2209
|
} catch (error) {
|
|
2173
|
-
|
|
2210
|
+
if (error instanceof NetworkError && error.statusCode === 429) {
|
|
2211
|
+
logger.warn(
|
|
2212
|
+
`Rate-limited polling swap ${swap.id}, retrying in 2s`
|
|
2213
|
+
);
|
|
2214
|
+
const existing = this.pollRetryTimers.get(swap.id);
|
|
2215
|
+
if (existing) clearTimeout(existing);
|
|
2216
|
+
this.pollRetryTimers.set(
|
|
2217
|
+
swap.id,
|
|
2218
|
+
setTimeout(async () => {
|
|
2219
|
+
this.pollRetryTimers.delete(swap.id);
|
|
2220
|
+
try {
|
|
2221
|
+
const retry = await this.swapProvider.getSwapStatus(
|
|
2222
|
+
swap.id
|
|
2223
|
+
);
|
|
2224
|
+
if (retry.status !== swap.status) {
|
|
2225
|
+
await this.handleSwapStatusUpdate(
|
|
2226
|
+
swap,
|
|
2227
|
+
retry.status
|
|
2228
|
+
);
|
|
2229
|
+
}
|
|
2230
|
+
} catch (retryError) {
|
|
2231
|
+
logger.error(
|
|
2232
|
+
`Retry poll for swap ${swap.id} also failed:`,
|
|
2233
|
+
retryError
|
|
2234
|
+
);
|
|
2235
|
+
}
|
|
2236
|
+
}, 2e3)
|
|
2237
|
+
);
|
|
2238
|
+
} else {
|
|
2239
|
+
logger.error(`Failed to poll swap ${swap.id}:`, error);
|
|
2240
|
+
}
|
|
2174
2241
|
}
|
|
2175
2242
|
}
|
|
2176
2243
|
);
|
|
@@ -3098,6 +3165,16 @@ var ArkadeSwaps = class _ArkadeSwaps {
|
|
|
3098
3165
|
* Dispose of resources (stops SwapManager and cleans up).
|
|
3099
3166
|
* Can be called manually or automatically with `await using` syntax (TypeScript 5.2+).
|
|
3100
3167
|
*/
|
|
3168
|
+
/**
|
|
3169
|
+
* Reset all swap state: stops the SwapManager and clears the swap repository.
|
|
3170
|
+
*
|
|
3171
|
+
* **Destructive** — any swap in a non-terminal state will lose its
|
|
3172
|
+
* refund/claim path. Intended for wallet-reset / dev / test scenarios only.
|
|
3173
|
+
*/
|
|
3174
|
+
async reset() {
|
|
3175
|
+
await this.dispose();
|
|
3176
|
+
await this.swapRepository.clear();
|
|
3177
|
+
}
|
|
3101
3178
|
async dispose() {
|
|
3102
3179
|
if (this.swapManager) {
|
|
3103
3180
|
await this.stopSwapManager();
|
|
@@ -4468,16 +4545,18 @@ var ArkadeSwaps = class _ArkadeSwaps {
|
|
|
4468
4545
|
} else if (isRestoredSubmarineSwap(swap)) {
|
|
4469
4546
|
const { amount, lockupAddress, serverPublicKey, tree } = swap.refundDetails;
|
|
4470
4547
|
let preimage = "";
|
|
4471
|
-
|
|
4472
|
-
|
|
4473
|
-
|
|
4474
|
-
|
|
4475
|
-
|
|
4476
|
-
|
|
4477
|
-
|
|
4478
|
-
|
|
4479
|
-
|
|
4480
|
-
|
|
4548
|
+
if (!isSubmarineFinalStatus(status)) {
|
|
4549
|
+
try {
|
|
4550
|
+
const data = await this.swapProvider.getSwapPreimage(
|
|
4551
|
+
swap.id
|
|
4552
|
+
);
|
|
4553
|
+
preimage = data.preimage;
|
|
4554
|
+
} catch (error) {
|
|
4555
|
+
logger.warn(
|
|
4556
|
+
`Failed to restore preimage for submarine swap ${id}`,
|
|
4557
|
+
error
|
|
4558
|
+
);
|
|
4559
|
+
}
|
|
4481
4560
|
}
|
|
4482
4561
|
submarineSwaps.push({
|
|
4483
4562
|
id,
|
|
@@ -5036,6 +5115,28 @@ var ArkadeSwapsMessageHandler = class _ArkadeSwapsMessageHandler {
|
|
|
5036
5115
|
};
|
|
5037
5116
|
|
|
5038
5117
|
// src/serviceWorker/arkade-swaps-runtime.ts
|
|
5118
|
+
var import_sdk10 = require("@arkade-os/sdk");
|
|
5119
|
+
function isMessageBusNotInitializedError(error) {
|
|
5120
|
+
return error instanceof Error && error.message.includes(import_sdk10.MESSAGE_BUS_NOT_INITIALIZED);
|
|
5121
|
+
}
|
|
5122
|
+
var DEDUPABLE_REQUEST_TYPES = /* @__PURE__ */ new Set([
|
|
5123
|
+
"GET_FEES",
|
|
5124
|
+
"GET_LIMITS",
|
|
5125
|
+
"GET_SWAP_STATUS",
|
|
5126
|
+
"GET_PENDING_SUBMARINE_SWAPS",
|
|
5127
|
+
"GET_PENDING_REVERSE_SWAPS",
|
|
5128
|
+
"GET_PENDING_CHAIN_SWAPS",
|
|
5129
|
+
"GET_SWAP_HISTORY",
|
|
5130
|
+
"QUOTE_SWAP",
|
|
5131
|
+
"SM-GET_PENDING_SWAPS",
|
|
5132
|
+
"SM-HAS_SWAP",
|
|
5133
|
+
"SM-IS_PROCESSING",
|
|
5134
|
+
"SM-GET_STATS"
|
|
5135
|
+
]);
|
|
5136
|
+
function getRequestDedupKey(request) {
|
|
5137
|
+
const { id, tag, ...rest } = request;
|
|
5138
|
+
return JSON.stringify(rest);
|
|
5139
|
+
}
|
|
5039
5140
|
var ServiceWorkerArkadeSwaps = class _ServiceWorkerArkadeSwaps {
|
|
5040
5141
|
constructor(messageTag, serviceWorker, swapRepository, withSwapManager) {
|
|
5041
5142
|
this.messageTag = messageTag;
|
|
@@ -5050,6 +5151,10 @@ var ServiceWorkerArkadeSwaps = class _ServiceWorkerArkadeSwaps {
|
|
|
5050
5151
|
actionExecutedListeners = /* @__PURE__ */ new Set();
|
|
5051
5152
|
wsConnectedListeners = /* @__PURE__ */ new Set();
|
|
5052
5153
|
wsDisconnectedListeners = /* @__PURE__ */ new Set();
|
|
5154
|
+
initPayload = null;
|
|
5155
|
+
reinitPromise = null;
|
|
5156
|
+
pingPromise = null;
|
|
5157
|
+
inflightRequests = /* @__PURE__ */ new Map();
|
|
5053
5158
|
static async create(config) {
|
|
5054
5159
|
const messageTag = config.messageTag ?? DEFAULT_MESSAGE_TAG;
|
|
5055
5160
|
const swapRepository = config.swapRepository ?? new IndexedDbSwapRepository();
|
|
@@ -5059,18 +5164,20 @@ var ServiceWorkerArkadeSwaps = class _ServiceWorkerArkadeSwaps {
|
|
|
5059
5164
|
swapRepository,
|
|
5060
5165
|
Boolean(config.swapManager)
|
|
5061
5166
|
);
|
|
5167
|
+
const initPayload = {
|
|
5168
|
+
network: config.network,
|
|
5169
|
+
arkServerUrl: config.arkServerUrl,
|
|
5170
|
+
swapProvider: { baseUrl: config.swapProvider.getApiUrl() },
|
|
5171
|
+
swapManager: config.swapManager
|
|
5172
|
+
};
|
|
5062
5173
|
const initMessage = {
|
|
5063
5174
|
tag: messageTag,
|
|
5064
5175
|
id: getRandomId(),
|
|
5065
5176
|
type: "INIT_ARKADE_SWAPS",
|
|
5066
|
-
payload:
|
|
5067
|
-
network: config.network,
|
|
5068
|
-
arkServerUrl: config.arkServerUrl,
|
|
5069
|
-
swapProvider: { baseUrl: config.swapProvider.getApiUrl() },
|
|
5070
|
-
swapManager: config.swapManager
|
|
5071
|
-
}
|
|
5177
|
+
payload: initPayload
|
|
5072
5178
|
};
|
|
5073
5179
|
await svcArkadeSwaps.sendMessage(initMessage);
|
|
5180
|
+
svcArkadeSwaps.initPayload = initPayload;
|
|
5074
5181
|
return svcArkadeSwaps;
|
|
5075
5182
|
}
|
|
5076
5183
|
async startSwapManager() {
|
|
@@ -5602,6 +5709,16 @@ var ServiceWorkerArkadeSwaps = class _ServiceWorkerArkadeSwaps {
|
|
|
5602
5709
|
type: "REFRESH_SWAPS_STATUS"
|
|
5603
5710
|
});
|
|
5604
5711
|
}
|
|
5712
|
+
/**
|
|
5713
|
+
* Reset all swap state: stops the SwapManager and clears the swap repository.
|
|
5714
|
+
*
|
|
5715
|
+
* **Destructive** — any swap in a non-terminal state will lose its
|
|
5716
|
+
* refund/claim path. Intended for wallet-reset / dev / test scenarios only.
|
|
5717
|
+
*/
|
|
5718
|
+
async reset() {
|
|
5719
|
+
await this.dispose();
|
|
5720
|
+
await this.swapRepository.clear();
|
|
5721
|
+
}
|
|
5605
5722
|
async dispose() {
|
|
5606
5723
|
if (this.withSwapManager) {
|
|
5607
5724
|
await this.stopSwapManager().catch(() => {
|
|
@@ -5611,17 +5728,23 @@ var ServiceWorkerArkadeSwaps = class _ServiceWorkerArkadeSwaps {
|
|
|
5611
5728
|
async [Symbol.asyncDispose]() {
|
|
5612
5729
|
return this.dispose();
|
|
5613
5730
|
}
|
|
5614
|
-
|
|
5731
|
+
sendMessageDirect(request) {
|
|
5615
5732
|
return new Promise((resolve, reject) => {
|
|
5616
|
-
const timeoutMs = 3e4;
|
|
5617
|
-
let timeout;
|
|
5618
5733
|
const cleanup = () => {
|
|
5619
|
-
|
|
5734
|
+
clearTimeout(timeoutId);
|
|
5620
5735
|
navigator.serviceWorker.removeEventListener(
|
|
5621
5736
|
"message",
|
|
5622
5737
|
messageHandler
|
|
5623
5738
|
);
|
|
5624
5739
|
};
|
|
5740
|
+
const timeoutId = setTimeout(() => {
|
|
5741
|
+
cleanup();
|
|
5742
|
+
reject(
|
|
5743
|
+
new import_sdk10.ServiceWorkerTimeoutError(
|
|
5744
|
+
`Service worker message timed out (${request.type})`
|
|
5745
|
+
)
|
|
5746
|
+
);
|
|
5747
|
+
}, 3e4);
|
|
5625
5748
|
const messageHandler = (event) => {
|
|
5626
5749
|
const response = event.data;
|
|
5627
5750
|
if (!response || response.tag !== this.messageTag || response.id !== request.id) {
|
|
@@ -5634,17 +5757,97 @@ var ServiceWorkerArkadeSwaps = class _ServiceWorkerArkadeSwaps {
|
|
|
5634
5757
|
resolve(response);
|
|
5635
5758
|
}
|
|
5636
5759
|
};
|
|
5637
|
-
|
|
5760
|
+
navigator.serviceWorker.addEventListener("message", messageHandler);
|
|
5761
|
+
this.serviceWorker.postMessage(request);
|
|
5762
|
+
});
|
|
5763
|
+
}
|
|
5764
|
+
async sendMessage(request) {
|
|
5765
|
+
if (!DEDUPABLE_REQUEST_TYPES.has(request.type)) {
|
|
5766
|
+
return this.sendMessageWithRetry(request);
|
|
5767
|
+
}
|
|
5768
|
+
const key = getRequestDedupKey(request);
|
|
5769
|
+
const existing = this.inflightRequests.get(key);
|
|
5770
|
+
if (existing) return existing;
|
|
5771
|
+
const promise = this.sendMessageWithRetry(request).finally(() => {
|
|
5772
|
+
this.inflightRequests.delete(key);
|
|
5773
|
+
});
|
|
5774
|
+
this.inflightRequests.set(key, promise);
|
|
5775
|
+
return promise;
|
|
5776
|
+
}
|
|
5777
|
+
pingServiceWorker() {
|
|
5778
|
+
if (this.pingPromise) return this.pingPromise;
|
|
5779
|
+
this.pingPromise = new Promise((resolve, reject) => {
|
|
5780
|
+
const pingId = getRandomId();
|
|
5781
|
+
const cleanup = () => {
|
|
5782
|
+
clearTimeout(timeoutId);
|
|
5783
|
+
navigator.serviceWorker.removeEventListener(
|
|
5784
|
+
"message",
|
|
5785
|
+
onMessage
|
|
5786
|
+
);
|
|
5787
|
+
};
|
|
5788
|
+
const timeoutId = setTimeout(() => {
|
|
5638
5789
|
cleanup();
|
|
5639
5790
|
reject(
|
|
5640
|
-
new
|
|
5641
|
-
|
|
5791
|
+
new import_sdk10.ServiceWorkerTimeoutError(
|
|
5792
|
+
"Service worker ping timed out"
|
|
5642
5793
|
)
|
|
5643
5794
|
);
|
|
5644
|
-
},
|
|
5645
|
-
|
|
5646
|
-
|
|
5795
|
+
}, 2e3);
|
|
5796
|
+
const onMessage = (event) => {
|
|
5797
|
+
if (event.data?.id === pingId && event.data?.tag === "PONG") {
|
|
5798
|
+
cleanup();
|
|
5799
|
+
resolve();
|
|
5800
|
+
}
|
|
5801
|
+
};
|
|
5802
|
+
navigator.serviceWorker.addEventListener("message", onMessage);
|
|
5803
|
+
this.serviceWorker.postMessage({
|
|
5804
|
+
id: pingId,
|
|
5805
|
+
tag: "PING"
|
|
5806
|
+
});
|
|
5807
|
+
}).finally(() => {
|
|
5808
|
+
this.pingPromise = null;
|
|
5809
|
+
});
|
|
5810
|
+
return this.pingPromise;
|
|
5811
|
+
}
|
|
5812
|
+
// Send a message, retrying up to 2 times if the service worker was
|
|
5813
|
+
// killed and restarted by the OS (mobile browsers do this aggressively).
|
|
5814
|
+
async sendMessageWithRetry(request) {
|
|
5815
|
+
if (this.initPayload) {
|
|
5816
|
+
try {
|
|
5817
|
+
await this.pingServiceWorker();
|
|
5818
|
+
} catch {
|
|
5819
|
+
await this.reinitialize();
|
|
5820
|
+
}
|
|
5821
|
+
}
|
|
5822
|
+
const maxRetries = 2;
|
|
5823
|
+
for (let attempt = 0; ; attempt++) {
|
|
5824
|
+
try {
|
|
5825
|
+
return await this.sendMessageDirect(request);
|
|
5826
|
+
} catch (error) {
|
|
5827
|
+
if (!isMessageBusNotInitializedError(error) || attempt >= maxRetries) {
|
|
5828
|
+
throw error;
|
|
5829
|
+
}
|
|
5830
|
+
await this.reinitialize();
|
|
5831
|
+
}
|
|
5832
|
+
}
|
|
5833
|
+
}
|
|
5834
|
+
async reinitialize() {
|
|
5835
|
+
if (this.reinitPromise) return this.reinitPromise;
|
|
5836
|
+
this.reinitPromise = (async () => {
|
|
5837
|
+
if (!this.initPayload) {
|
|
5838
|
+
throw new Error("Cannot re-initialize: missing configuration");
|
|
5839
|
+
}
|
|
5840
|
+
const initMessage = {
|
|
5841
|
+
tag: this.messageTag,
|
|
5842
|
+
type: "INIT_ARKADE_SWAPS",
|
|
5843
|
+
id: getRandomId(),
|
|
5844
|
+
payload: this.initPayload
|
|
5845
|
+
};
|
|
5846
|
+
await this.sendMessageDirect(initMessage);
|
|
5847
|
+
})().finally(() => {
|
|
5848
|
+
this.reinitPromise = null;
|
|
5647
5849
|
});
|
|
5850
|
+
return this.reinitPromise;
|
|
5648
5851
|
}
|
|
5649
5852
|
initEventStream() {
|
|
5650
5853
|
if (this.eventListenerInitialized) return;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { I as IArkadeSwaps } from './arkade-swaps
|
|
2
|
-
export { A as ArkadeSwaps } from './arkade-swaps
|
|
3
|
-
import { P as PendingSwap, D as DecodedInvoice, a as PendingChainSwap, b as PendingReverseSwap, c as PendingSubmarineSwap, A as ArkadeSwapsConfig, N as Network, C as CreateLightningInvoiceRequest, S as SendLightningPaymentRequest, F as FeesResponse, d as Chain, e as CreateLightningInvoiceResponse, f as SendLightningPaymentResponse, g as ChainFeesResponse, L as LimitsResponse, G as GetSwapStatusResponse, h as ArkToBtcResponse, B as BtcToArkResponse, i as SwapRepository, j as SwapManagerClient, k as GetSwapsFilter } from './types-
|
|
4
|
-
export { X as ArkadeSwapsCreateConfig, l as BoltzSwapProvider, m as BoltzSwapStatus, W as IncomingPaymentSubscription, V as SwapManager, $ as SwapManagerCallbacks, Z as SwapManagerConfig, _ as SwapManagerEvents, Y as Vtxo, n as isChainClaimableStatus, o as isChainFailedStatus, p as isChainFinalStatus, q as isChainPendingStatus, r as isChainRefundableStatus, s as isChainSignableStatus, t as isChainSuccessStatus, u as isChainSwapClaimable, v as isChainSwapRefundable, w as isPendingChainSwap, x as isPendingReverseSwap, y as isPendingSubmarineSwap, z as isReverseClaimableStatus, E as isReverseFailedStatus, H as isReverseFinalStatus, I as isReversePendingStatus, J as isReverseSuccessStatus, K as isReverseSwapClaimable, M as isSubmarineFailedStatus, O as isSubmarineFinalStatus, Q as isSubmarinePendingStatus, T as isSubmarineRefundableStatus, R as isSubmarineSuccessStatus, U as isSubmarineSwapRefundable } from './types-
|
|
1
|
+
import { I as IArkadeSwaps } from './arkade-swaps--vc0H2oD.cjs';
|
|
2
|
+
export { A as ArkadeSwaps } from './arkade-swaps--vc0H2oD.cjs';
|
|
3
|
+
import { P as PendingSwap, D as DecodedInvoice, a as PendingChainSwap, b as PendingReverseSwap, c as PendingSubmarineSwap, A as ArkadeSwapsConfig, N as Network, C as CreateLightningInvoiceRequest, S as SendLightningPaymentRequest, F as FeesResponse, d as Chain, e as CreateLightningInvoiceResponse, f as SendLightningPaymentResponse, g as ChainFeesResponse, L as LimitsResponse, G as GetSwapStatusResponse, h as ArkToBtcResponse, B as BtcToArkResponse, i as SwapRepository, j as SwapManagerClient, k as GetSwapsFilter } from './types-CEmBBA71.cjs';
|
|
4
|
+
export { X as ArkadeSwapsCreateConfig, l as BoltzSwapProvider, m as BoltzSwapStatus, W as IncomingPaymentSubscription, V as SwapManager, $ as SwapManagerCallbacks, Z as SwapManagerConfig, _ as SwapManagerEvents, Y as Vtxo, n as isChainClaimableStatus, o as isChainFailedStatus, p as isChainFinalStatus, q as isChainPendingStatus, r as isChainRefundableStatus, s as isChainSignableStatus, t as isChainSuccessStatus, u as isChainSwapClaimable, v as isChainSwapRefundable, w as isPendingChainSwap, x as isPendingReverseSwap, y as isPendingSubmarineSwap, z as isReverseClaimableStatus, E as isReverseFailedStatus, H as isReverseFinalStatus, I as isReversePendingStatus, J as isReverseSuccessStatus, K as isReverseSwapClaimable, M as isSubmarineFailedStatus, O as isSubmarineFinalStatus, Q as isSubmarinePendingStatus, T as isSubmarineRefundableStatus, R as isSubmarineSuccessStatus, U as isSubmarineSwapRefundable } from './types-CEmBBA71.cjs';
|
|
5
5
|
import { Transaction } from '@scure/btc-signer';
|
|
6
6
|
import { MessageHandler, RequestEnvelope, ArkInfo, ResponseEnvelope, IWallet, IReadonlyWallet, VHTLC, Identity, ArkTxInput } from '@arkade-os/sdk';
|
|
7
7
|
import { TransactionOutput } from '@scure/btc-signer/psbt.js';
|
|
@@ -562,6 +562,10 @@ declare class ServiceWorkerArkadeSwaps implements IArkadeSwaps {
|
|
|
562
562
|
private actionExecutedListeners;
|
|
563
563
|
private wsConnectedListeners;
|
|
564
564
|
private wsDisconnectedListeners;
|
|
565
|
+
private initPayload;
|
|
566
|
+
private reinitPromise;
|
|
567
|
+
private pingPromise;
|
|
568
|
+
private inflightRequests;
|
|
565
569
|
private constructor();
|
|
566
570
|
static create(config: SvcWrkArkadeSwapsConfig): Promise<ServiceWorkerArkadeSwaps>;
|
|
567
571
|
startSwapManager(): Promise<void>;
|
|
@@ -652,9 +656,20 @@ declare class ServiceWorkerArkadeSwaps implements IArkadeSwaps {
|
|
|
652
656
|
getPendingChainSwaps(): Promise<PendingChainSwap[]>;
|
|
653
657
|
getSwapHistory(): Promise<(PendingReverseSwap | PendingSubmarineSwap | PendingChainSwap)[]>;
|
|
654
658
|
refreshSwapsStatus(): Promise<void>;
|
|
659
|
+
/**
|
|
660
|
+
* Reset all swap state: stops the SwapManager and clears the swap repository.
|
|
661
|
+
*
|
|
662
|
+
* **Destructive** — any swap in a non-terminal state will lose its
|
|
663
|
+
* refund/claim path. Intended for wallet-reset / dev / test scenarios only.
|
|
664
|
+
*/
|
|
665
|
+
reset(): Promise<void>;
|
|
655
666
|
dispose(): Promise<void>;
|
|
656
667
|
[Symbol.asyncDispose](): Promise<void>;
|
|
668
|
+
private sendMessageDirect;
|
|
657
669
|
private sendMessage;
|
|
670
|
+
private pingServiceWorker;
|
|
671
|
+
private sendMessageWithRetry;
|
|
672
|
+
private reinitialize;
|
|
658
673
|
private initEventStream;
|
|
659
674
|
private handleEventMessage;
|
|
660
675
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { I as IArkadeSwaps } from './arkade-swaps-
|
|
2
|
-
export { A as ArkadeSwaps } from './arkade-swaps-
|
|
3
|
-
import { P as PendingSwap, D as DecodedInvoice, a as PendingChainSwap, b as PendingReverseSwap, c as PendingSubmarineSwap, A as ArkadeSwapsConfig, N as Network, C as CreateLightningInvoiceRequest, S as SendLightningPaymentRequest, F as FeesResponse, d as Chain, e as CreateLightningInvoiceResponse, f as SendLightningPaymentResponse, g as ChainFeesResponse, L as LimitsResponse, G as GetSwapStatusResponse, h as ArkToBtcResponse, B as BtcToArkResponse, i as SwapRepository, j as SwapManagerClient, k as GetSwapsFilter } from './types-
|
|
4
|
-
export { X as ArkadeSwapsCreateConfig, l as BoltzSwapProvider, m as BoltzSwapStatus, W as IncomingPaymentSubscription, V as SwapManager, $ as SwapManagerCallbacks, Z as SwapManagerConfig, _ as SwapManagerEvents, Y as Vtxo, n as isChainClaimableStatus, o as isChainFailedStatus, p as isChainFinalStatus, q as isChainPendingStatus, r as isChainRefundableStatus, s as isChainSignableStatus, t as isChainSuccessStatus, u as isChainSwapClaimable, v as isChainSwapRefundable, w as isPendingChainSwap, x as isPendingReverseSwap, y as isPendingSubmarineSwap, z as isReverseClaimableStatus, E as isReverseFailedStatus, H as isReverseFinalStatus, I as isReversePendingStatus, J as isReverseSuccessStatus, K as isReverseSwapClaimable, M as isSubmarineFailedStatus, O as isSubmarineFinalStatus, Q as isSubmarinePendingStatus, T as isSubmarineRefundableStatus, R as isSubmarineSuccessStatus, U as isSubmarineSwapRefundable } from './types-
|
|
1
|
+
import { I as IArkadeSwaps } from './arkade-swaps-qQuX73sR.js';
|
|
2
|
+
export { A as ArkadeSwaps } from './arkade-swaps-qQuX73sR.js';
|
|
3
|
+
import { P as PendingSwap, D as DecodedInvoice, a as PendingChainSwap, b as PendingReverseSwap, c as PendingSubmarineSwap, A as ArkadeSwapsConfig, N as Network, C as CreateLightningInvoiceRequest, S as SendLightningPaymentRequest, F as FeesResponse, d as Chain, e as CreateLightningInvoiceResponse, f as SendLightningPaymentResponse, g as ChainFeesResponse, L as LimitsResponse, G as GetSwapStatusResponse, h as ArkToBtcResponse, B as BtcToArkResponse, i as SwapRepository, j as SwapManagerClient, k as GetSwapsFilter } from './types-CEmBBA71.js';
|
|
4
|
+
export { X as ArkadeSwapsCreateConfig, l as BoltzSwapProvider, m as BoltzSwapStatus, W as IncomingPaymentSubscription, V as SwapManager, $ as SwapManagerCallbacks, Z as SwapManagerConfig, _ as SwapManagerEvents, Y as Vtxo, n as isChainClaimableStatus, o as isChainFailedStatus, p as isChainFinalStatus, q as isChainPendingStatus, r as isChainRefundableStatus, s as isChainSignableStatus, t as isChainSuccessStatus, u as isChainSwapClaimable, v as isChainSwapRefundable, w as isPendingChainSwap, x as isPendingReverseSwap, y as isPendingSubmarineSwap, z as isReverseClaimableStatus, E as isReverseFailedStatus, H as isReverseFinalStatus, I as isReversePendingStatus, J as isReverseSuccessStatus, K as isReverseSwapClaimable, M as isSubmarineFailedStatus, O as isSubmarineFinalStatus, Q as isSubmarinePendingStatus, T as isSubmarineRefundableStatus, R as isSubmarineSuccessStatus, U as isSubmarineSwapRefundable } from './types-CEmBBA71.js';
|
|
5
5
|
import { Transaction } from '@scure/btc-signer';
|
|
6
6
|
import { MessageHandler, RequestEnvelope, ArkInfo, ResponseEnvelope, IWallet, IReadonlyWallet, VHTLC, Identity, ArkTxInput } from '@arkade-os/sdk';
|
|
7
7
|
import { TransactionOutput } from '@scure/btc-signer/psbt.js';
|
|
@@ -562,6 +562,10 @@ declare class ServiceWorkerArkadeSwaps implements IArkadeSwaps {
|
|
|
562
562
|
private actionExecutedListeners;
|
|
563
563
|
private wsConnectedListeners;
|
|
564
564
|
private wsDisconnectedListeners;
|
|
565
|
+
private initPayload;
|
|
566
|
+
private reinitPromise;
|
|
567
|
+
private pingPromise;
|
|
568
|
+
private inflightRequests;
|
|
565
569
|
private constructor();
|
|
566
570
|
static create(config: SvcWrkArkadeSwapsConfig): Promise<ServiceWorkerArkadeSwaps>;
|
|
567
571
|
startSwapManager(): Promise<void>;
|
|
@@ -652,9 +656,20 @@ declare class ServiceWorkerArkadeSwaps implements IArkadeSwaps {
|
|
|
652
656
|
getPendingChainSwaps(): Promise<PendingChainSwap[]>;
|
|
653
657
|
getSwapHistory(): Promise<(PendingReverseSwap | PendingSubmarineSwap | PendingChainSwap)[]>;
|
|
654
658
|
refreshSwapsStatus(): Promise<void>;
|
|
659
|
+
/**
|
|
660
|
+
* Reset all swap state: stops the SwapManager and clears the swap repository.
|
|
661
|
+
*
|
|
662
|
+
* **Destructive** — any swap in a non-terminal state will lose its
|
|
663
|
+
* refund/claim path. Intended for wallet-reset / dev / test scenarios only.
|
|
664
|
+
*/
|
|
665
|
+
reset(): Promise<void>;
|
|
655
666
|
dispose(): Promise<void>;
|
|
656
667
|
[Symbol.asyncDispose](): Promise<void>;
|
|
668
|
+
private sendMessageDirect;
|
|
657
669
|
private sendMessage;
|
|
670
|
+
private pingServiceWorker;
|
|
671
|
+
private sendMessageWithRetry;
|
|
672
|
+
private reinitialize;
|
|
658
673
|
private initEventStream;
|
|
659
674
|
private handleEventMessage;
|
|
660
675
|
}
|
package/dist/index.js
CHANGED
|
@@ -49,7 +49,7 @@ import {
|
|
|
49
49
|
updateReverseSwapStatus,
|
|
50
50
|
updateSubmarineSwapStatus,
|
|
51
51
|
verifySignatures
|
|
52
|
-
} from "./chunk-
|
|
52
|
+
} from "./chunk-NUR5GPRK.js";
|
|
53
53
|
import "./chunk-3RG5ZIWI.js";
|
|
54
54
|
|
|
55
55
|
// src/serviceWorker/arkade-swaps-message-handler.ts
|
|
@@ -526,6 +526,31 @@ var ArkadeSwapsMessageHandler = class _ArkadeSwapsMessageHandler {
|
|
|
526
526
|
};
|
|
527
527
|
|
|
528
528
|
// src/serviceWorker/arkade-swaps-runtime.ts
|
|
529
|
+
import {
|
|
530
|
+
MESSAGE_BUS_NOT_INITIALIZED,
|
|
531
|
+
ServiceWorkerTimeoutError
|
|
532
|
+
} from "@arkade-os/sdk";
|
|
533
|
+
function isMessageBusNotInitializedError(error) {
|
|
534
|
+
return error instanceof Error && error.message.includes(MESSAGE_BUS_NOT_INITIALIZED);
|
|
535
|
+
}
|
|
536
|
+
var DEDUPABLE_REQUEST_TYPES = /* @__PURE__ */ new Set([
|
|
537
|
+
"GET_FEES",
|
|
538
|
+
"GET_LIMITS",
|
|
539
|
+
"GET_SWAP_STATUS",
|
|
540
|
+
"GET_PENDING_SUBMARINE_SWAPS",
|
|
541
|
+
"GET_PENDING_REVERSE_SWAPS",
|
|
542
|
+
"GET_PENDING_CHAIN_SWAPS",
|
|
543
|
+
"GET_SWAP_HISTORY",
|
|
544
|
+
"QUOTE_SWAP",
|
|
545
|
+
"SM-GET_PENDING_SWAPS",
|
|
546
|
+
"SM-HAS_SWAP",
|
|
547
|
+
"SM-IS_PROCESSING",
|
|
548
|
+
"SM-GET_STATS"
|
|
549
|
+
]);
|
|
550
|
+
function getRequestDedupKey(request) {
|
|
551
|
+
const { id, tag, ...rest } = request;
|
|
552
|
+
return JSON.stringify(rest);
|
|
553
|
+
}
|
|
529
554
|
var ServiceWorkerArkadeSwaps = class _ServiceWorkerArkadeSwaps {
|
|
530
555
|
constructor(messageTag, serviceWorker, swapRepository, withSwapManager) {
|
|
531
556
|
this.messageTag = messageTag;
|
|
@@ -540,6 +565,10 @@ var ServiceWorkerArkadeSwaps = class _ServiceWorkerArkadeSwaps {
|
|
|
540
565
|
actionExecutedListeners = /* @__PURE__ */ new Set();
|
|
541
566
|
wsConnectedListeners = /* @__PURE__ */ new Set();
|
|
542
567
|
wsDisconnectedListeners = /* @__PURE__ */ new Set();
|
|
568
|
+
initPayload = null;
|
|
569
|
+
reinitPromise = null;
|
|
570
|
+
pingPromise = null;
|
|
571
|
+
inflightRequests = /* @__PURE__ */ new Map();
|
|
543
572
|
static async create(config) {
|
|
544
573
|
const messageTag = config.messageTag ?? DEFAULT_MESSAGE_TAG;
|
|
545
574
|
const swapRepository = config.swapRepository ?? new IndexedDbSwapRepository();
|
|
@@ -549,18 +578,20 @@ var ServiceWorkerArkadeSwaps = class _ServiceWorkerArkadeSwaps {
|
|
|
549
578
|
swapRepository,
|
|
550
579
|
Boolean(config.swapManager)
|
|
551
580
|
);
|
|
581
|
+
const initPayload = {
|
|
582
|
+
network: config.network,
|
|
583
|
+
arkServerUrl: config.arkServerUrl,
|
|
584
|
+
swapProvider: { baseUrl: config.swapProvider.getApiUrl() },
|
|
585
|
+
swapManager: config.swapManager
|
|
586
|
+
};
|
|
552
587
|
const initMessage = {
|
|
553
588
|
tag: messageTag,
|
|
554
589
|
id: getRandomId(),
|
|
555
590
|
type: "INIT_ARKADE_SWAPS",
|
|
556
|
-
payload:
|
|
557
|
-
network: config.network,
|
|
558
|
-
arkServerUrl: config.arkServerUrl,
|
|
559
|
-
swapProvider: { baseUrl: config.swapProvider.getApiUrl() },
|
|
560
|
-
swapManager: config.swapManager
|
|
561
|
-
}
|
|
591
|
+
payload: initPayload
|
|
562
592
|
};
|
|
563
593
|
await svcArkadeSwaps.sendMessage(initMessage);
|
|
594
|
+
svcArkadeSwaps.initPayload = initPayload;
|
|
564
595
|
return svcArkadeSwaps;
|
|
565
596
|
}
|
|
566
597
|
async startSwapManager() {
|
|
@@ -1092,6 +1123,16 @@ var ServiceWorkerArkadeSwaps = class _ServiceWorkerArkadeSwaps {
|
|
|
1092
1123
|
type: "REFRESH_SWAPS_STATUS"
|
|
1093
1124
|
});
|
|
1094
1125
|
}
|
|
1126
|
+
/**
|
|
1127
|
+
* Reset all swap state: stops the SwapManager and clears the swap repository.
|
|
1128
|
+
*
|
|
1129
|
+
* **Destructive** — any swap in a non-terminal state will lose its
|
|
1130
|
+
* refund/claim path. Intended for wallet-reset / dev / test scenarios only.
|
|
1131
|
+
*/
|
|
1132
|
+
async reset() {
|
|
1133
|
+
await this.dispose();
|
|
1134
|
+
await this.swapRepository.clear();
|
|
1135
|
+
}
|
|
1095
1136
|
async dispose() {
|
|
1096
1137
|
if (this.withSwapManager) {
|
|
1097
1138
|
await this.stopSwapManager().catch(() => {
|
|
@@ -1101,17 +1142,23 @@ var ServiceWorkerArkadeSwaps = class _ServiceWorkerArkadeSwaps {
|
|
|
1101
1142
|
async [Symbol.asyncDispose]() {
|
|
1102
1143
|
return this.dispose();
|
|
1103
1144
|
}
|
|
1104
|
-
|
|
1145
|
+
sendMessageDirect(request) {
|
|
1105
1146
|
return new Promise((resolve, reject) => {
|
|
1106
|
-
const timeoutMs = 3e4;
|
|
1107
|
-
let timeout;
|
|
1108
1147
|
const cleanup = () => {
|
|
1109
|
-
|
|
1148
|
+
clearTimeout(timeoutId);
|
|
1110
1149
|
navigator.serviceWorker.removeEventListener(
|
|
1111
1150
|
"message",
|
|
1112
1151
|
messageHandler
|
|
1113
1152
|
);
|
|
1114
1153
|
};
|
|
1154
|
+
const timeoutId = setTimeout(() => {
|
|
1155
|
+
cleanup();
|
|
1156
|
+
reject(
|
|
1157
|
+
new ServiceWorkerTimeoutError(
|
|
1158
|
+
`Service worker message timed out (${request.type})`
|
|
1159
|
+
)
|
|
1160
|
+
);
|
|
1161
|
+
}, 3e4);
|
|
1115
1162
|
const messageHandler = (event) => {
|
|
1116
1163
|
const response = event.data;
|
|
1117
1164
|
if (!response || response.tag !== this.messageTag || response.id !== request.id) {
|
|
@@ -1124,17 +1171,97 @@ var ServiceWorkerArkadeSwaps = class _ServiceWorkerArkadeSwaps {
|
|
|
1124
1171
|
resolve(response);
|
|
1125
1172
|
}
|
|
1126
1173
|
};
|
|
1127
|
-
|
|
1174
|
+
navigator.serviceWorker.addEventListener("message", messageHandler);
|
|
1175
|
+
this.serviceWorker.postMessage(request);
|
|
1176
|
+
});
|
|
1177
|
+
}
|
|
1178
|
+
async sendMessage(request) {
|
|
1179
|
+
if (!DEDUPABLE_REQUEST_TYPES.has(request.type)) {
|
|
1180
|
+
return this.sendMessageWithRetry(request);
|
|
1181
|
+
}
|
|
1182
|
+
const key = getRequestDedupKey(request);
|
|
1183
|
+
const existing = this.inflightRequests.get(key);
|
|
1184
|
+
if (existing) return existing;
|
|
1185
|
+
const promise = this.sendMessageWithRetry(request).finally(() => {
|
|
1186
|
+
this.inflightRequests.delete(key);
|
|
1187
|
+
});
|
|
1188
|
+
this.inflightRequests.set(key, promise);
|
|
1189
|
+
return promise;
|
|
1190
|
+
}
|
|
1191
|
+
pingServiceWorker() {
|
|
1192
|
+
if (this.pingPromise) return this.pingPromise;
|
|
1193
|
+
this.pingPromise = new Promise((resolve, reject) => {
|
|
1194
|
+
const pingId = getRandomId();
|
|
1195
|
+
const cleanup = () => {
|
|
1196
|
+
clearTimeout(timeoutId);
|
|
1197
|
+
navigator.serviceWorker.removeEventListener(
|
|
1198
|
+
"message",
|
|
1199
|
+
onMessage
|
|
1200
|
+
);
|
|
1201
|
+
};
|
|
1202
|
+
const timeoutId = setTimeout(() => {
|
|
1128
1203
|
cleanup();
|
|
1129
1204
|
reject(
|
|
1130
|
-
new
|
|
1131
|
-
|
|
1205
|
+
new ServiceWorkerTimeoutError(
|
|
1206
|
+
"Service worker ping timed out"
|
|
1132
1207
|
)
|
|
1133
1208
|
);
|
|
1134
|
-
},
|
|
1135
|
-
|
|
1136
|
-
|
|
1209
|
+
}, 2e3);
|
|
1210
|
+
const onMessage = (event) => {
|
|
1211
|
+
if (event.data?.id === pingId && event.data?.tag === "PONG") {
|
|
1212
|
+
cleanup();
|
|
1213
|
+
resolve();
|
|
1214
|
+
}
|
|
1215
|
+
};
|
|
1216
|
+
navigator.serviceWorker.addEventListener("message", onMessage);
|
|
1217
|
+
this.serviceWorker.postMessage({
|
|
1218
|
+
id: pingId,
|
|
1219
|
+
tag: "PING"
|
|
1220
|
+
});
|
|
1221
|
+
}).finally(() => {
|
|
1222
|
+
this.pingPromise = null;
|
|
1223
|
+
});
|
|
1224
|
+
return this.pingPromise;
|
|
1225
|
+
}
|
|
1226
|
+
// Send a message, retrying up to 2 times if the service worker was
|
|
1227
|
+
// killed and restarted by the OS (mobile browsers do this aggressively).
|
|
1228
|
+
async sendMessageWithRetry(request) {
|
|
1229
|
+
if (this.initPayload) {
|
|
1230
|
+
try {
|
|
1231
|
+
await this.pingServiceWorker();
|
|
1232
|
+
} catch {
|
|
1233
|
+
await this.reinitialize();
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1236
|
+
const maxRetries = 2;
|
|
1237
|
+
for (let attempt = 0; ; attempt++) {
|
|
1238
|
+
try {
|
|
1239
|
+
return await this.sendMessageDirect(request);
|
|
1240
|
+
} catch (error) {
|
|
1241
|
+
if (!isMessageBusNotInitializedError(error) || attempt >= maxRetries) {
|
|
1242
|
+
throw error;
|
|
1243
|
+
}
|
|
1244
|
+
await this.reinitialize();
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
async reinitialize() {
|
|
1249
|
+
if (this.reinitPromise) return this.reinitPromise;
|
|
1250
|
+
this.reinitPromise = (async () => {
|
|
1251
|
+
if (!this.initPayload) {
|
|
1252
|
+
throw new Error("Cannot re-initialize: missing configuration");
|
|
1253
|
+
}
|
|
1254
|
+
const initMessage = {
|
|
1255
|
+
tag: this.messageTag,
|
|
1256
|
+
type: "INIT_ARKADE_SWAPS",
|
|
1257
|
+
id: getRandomId(),
|
|
1258
|
+
payload: this.initPayload
|
|
1259
|
+
};
|
|
1260
|
+
await this.sendMessageDirect(initMessage);
|
|
1261
|
+
})().finally(() => {
|
|
1262
|
+
this.reinitPromise = null;
|
|
1137
1263
|
});
|
|
1264
|
+
return this.reinitPromise;
|
|
1138
1265
|
}
|
|
1139
1266
|
initEventStream() {
|
|
1140
1267
|
if (this.eventListenerInitialized) return;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SQLExecutor } from '@arkade-os/sdk/repositories/sqlite';
|
|
2
|
-
import { i as SwapRepository, P as PendingSwap, k as GetSwapsFilter } from '../../types-
|
|
2
|
+
import { i as SwapRepository, P as PendingSwap, k as GetSwapsFilter } from '../../types-CEmBBA71.cjs';
|
|
3
3
|
import '@arkade-os/sdk';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SQLExecutor } from '@arkade-os/sdk/repositories/sqlite';
|
|
2
|
-
import { i as SwapRepository, P as PendingSwap, k as GetSwapsFilter } from '../../types-
|
|
2
|
+
import { i as SwapRepository, P as PendingSwap, k as GetSwapsFilter } from '../../types-CEmBBA71.js';
|
|
3
3
|
import '@arkade-os/sdk';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -489,6 +489,8 @@ declare class SwapManager implements SwapManagerClient {
|
|
|
489
489
|
private initialSwaps;
|
|
490
490
|
private pollTimer;
|
|
491
491
|
private reconnectTimer;
|
|
492
|
+
private initialPollTimer;
|
|
493
|
+
private pollRetryTimers;
|
|
492
494
|
private isRunning;
|
|
493
495
|
private currentReconnectDelay;
|
|
494
496
|
private currentPollRetryDelay;
|
|
@@ -489,6 +489,8 @@ declare class SwapManager implements SwapManagerClient {
|
|
|
489
489
|
private initialSwaps;
|
|
490
490
|
private pollTimer;
|
|
491
491
|
private reconnectTimer;
|
|
492
|
+
private initialPollTimer;
|
|
493
|
+
private pollRetryTimers;
|
|
492
494
|
private isRunning;
|
|
493
495
|
private currentReconnectDelay;
|
|
494
496
|
private currentPollRetryDelay;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arkade-os/boltz-swap",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.9",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A production-ready TypeScript package that brings Boltz submarine-swaps to Arkade.",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"author": "Arkade-OS",
|
|
61
61
|
"license": "MIT",
|
|
62
62
|
"dependencies": {
|
|
63
|
-
"@arkade-os/sdk": "0.4.
|
|
63
|
+
"@arkade-os/sdk": "0.4.10",
|
|
64
64
|
"@noble/hashes": "2.0.1",
|
|
65
65
|
"@scure/base": "2.0.0",
|
|
66
66
|
"@scure/btc-signer": "2.0.1",
|