@arkade-os/boltz-swap 0.3.29 → 0.3.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +34 -3
- package/dist/{chunk-LWUXSE5N.js → chunk-B3Q4TFWT.js} +1 -1
- package/dist/chunk-NHBWNN6H.js +117 -0
- package/dist/expo/background.cjs +5407 -0
- package/dist/expo/background.d.cts +61 -0
- package/dist/expo/background.d.ts +61 -0
- package/dist/expo/background.js +127 -0
- package/dist/expo/index.cjs +4673 -5077
- package/dist/expo/index.d.cts +24 -140
- package/dist/expo/index.d.ts +24 -140
- package/dist/expo/index.js +23 -55
- package/dist/index.cjs +14 -3
- package/dist/index.js +14 -4
- package/dist/repositories/realm/index.js +0 -2
- package/dist/repositories/sqlite/index.js +0 -2
- package/dist/swapsPollProcessor-BF3uTFae.d.cts +93 -0
- package/dist/swapsPollProcessor-wYOMzldd.d.ts +93 -0
- package/package.json +25 -3
- package/dist/background-UQDFQCGM.js +0 -12
- package/dist/chunk-3RG5ZIWI.js +0 -10
- package/dist/chunk-X3JNWDAR.js +0 -261
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { AsyncStorageTaskQueue, TaskProcessor } from '@arkade-os/sdk/worker/expo';
|
|
2
|
+
import { ArkProvider, IndexerProvider, Identity, IWallet } from '@arkade-os/sdk';
|
|
3
|
+
import { m as SwapRepository, p as BoltzSwapProvider, N as Network, A as ArkadeSwapsConfig } from './types-BBI7-KJ0.cjs';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Dependencies injected into every swap processor at runtime.
|
|
7
|
+
*
|
|
8
|
+
* Unlike the wallet's `TaskDependencies`, these are swap-specific:
|
|
9
|
+
* we need the Boltz provider, swap repository, and identity to
|
|
10
|
+
* poll status and attempt claim/refund.
|
|
11
|
+
*/
|
|
12
|
+
interface SwapTaskDependencies {
|
|
13
|
+
swapRepository: SwapRepository;
|
|
14
|
+
swapProvider: BoltzSwapProvider;
|
|
15
|
+
arkProvider: ArkProvider;
|
|
16
|
+
indexerProvider: IndexerProvider;
|
|
17
|
+
identity: Identity;
|
|
18
|
+
wallet: IWallet;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Minimal config persisted to AsyncStorage for background rehydration.
|
|
22
|
+
*
|
|
23
|
+
* The background handler runs in a fresh JS context without access to
|
|
24
|
+
* the foreground's in-memory state, so we persist just enough to
|
|
25
|
+
* reconstruct providers and identity.
|
|
26
|
+
*/
|
|
27
|
+
interface PersistedSwapBackgroundConfig {
|
|
28
|
+
boltzApiUrl: string;
|
|
29
|
+
arkServerUrl: string;
|
|
30
|
+
network: Network;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Background scheduling configuration for {@link ExpoArkadeSwaps}.
|
|
34
|
+
*
|
|
35
|
+
* OS-level task registration is **not** part of this config — call
|
|
36
|
+
* `registerExpoSwapBackgroundTask` from `@arkade-os/boltz-swap/expo/background`
|
|
37
|
+
* explicitly. Splitting that step out keeps `/expo` free of the
|
|
38
|
+
* `expo-task-manager` / `expo-background-task` dependencies.
|
|
39
|
+
*/
|
|
40
|
+
interface ExpoSwapBackgroundConfig {
|
|
41
|
+
/** Persistence layer for foreground ↔ background handoff. */
|
|
42
|
+
taskQueue: AsyncStorageTaskQueue;
|
|
43
|
+
/** If set, acknowledges background results at this interval (ms) while the app is in the foreground. */
|
|
44
|
+
foregroundIntervalMs?: number;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Options for {@link defineExpoSwapBackgroundTask}.
|
|
48
|
+
*/
|
|
49
|
+
interface DefineSwapBackgroundTaskOptions {
|
|
50
|
+
/** AsyncStorage-backed queue (must match the one passed to ExpoArkadeSwaps.setup). */
|
|
51
|
+
taskQueue: AsyncStorageTaskQueue;
|
|
52
|
+
/** Swap repository (fresh instance is fine — connects to the same DB). */
|
|
53
|
+
swapRepository: SwapRepository;
|
|
54
|
+
/** Factory to reconstruct Identity from secure storage in the background. */
|
|
55
|
+
identityFactory: () => Promise<Identity>;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Configuration for {@link ExpoArkadeSwaps.setup}.
|
|
59
|
+
*/
|
|
60
|
+
interface ExpoArkadeSwapsConfig extends ArkadeSwapsConfig {
|
|
61
|
+
/**
|
|
62
|
+
* Ark server base URL (e.g. "https://ark.example.com").
|
|
63
|
+
*
|
|
64
|
+
* Recommended for type-safe background rehydration. If omitted,
|
|
65
|
+
* ExpoArkadeSwaps will attempt to derive it from the ArkProvider.
|
|
66
|
+
*/
|
|
67
|
+
arkServerUrl?: string;
|
|
68
|
+
background: ExpoSwapBackgroundConfig;
|
|
69
|
+
}
|
|
70
|
+
/** @deprecated Use ExpoArkadeSwapsConfig instead */
|
|
71
|
+
type ExpoArkadeLightningConfig = ExpoArkadeSwapsConfig;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Task type identifier for {@link swapsPollProcessor}.
|
|
75
|
+
*/
|
|
76
|
+
declare const SWAP_POLL_TASK_TYPE = "swap-poll";
|
|
77
|
+
/**
|
|
78
|
+
* Stateless processor that polls Boltz for swap status updates and
|
|
79
|
+
* attempts best-effort claim/refund for actionable swaps.
|
|
80
|
+
*
|
|
81
|
+
* Designed for Expo background tasks (~30s window) and follows the
|
|
82
|
+
* same `TaskProcessor` pattern as `contractPollProcessor` in ts-sdk.
|
|
83
|
+
*
|
|
84
|
+
* Steps:
|
|
85
|
+
* 1. Read all non-final swaps from SwapRepository
|
|
86
|
+
* 2. Poll Boltz HTTP API for each swap's current status
|
|
87
|
+
* 3. Persist status changes immediately
|
|
88
|
+
* 4. For actionable statuses: attempt claimVHTLC / refundVHTLC (best-effort)
|
|
89
|
+
* 5. Return summary metrics
|
|
90
|
+
*/
|
|
91
|
+
declare const swapsPollProcessor: TaskProcessor<SwapTaskDependencies>;
|
|
92
|
+
|
|
93
|
+
export { type DefineSwapBackgroundTaskOptions as D, type ExpoArkadeSwapsConfig as E, type PersistedSwapBackgroundConfig as P, SWAP_POLL_TASK_TYPE as S, type SwapTaskDependencies as a, type ExpoSwapBackgroundConfig as b, type ExpoArkadeLightningConfig as c, swapsPollProcessor as s };
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { AsyncStorageTaskQueue, TaskProcessor } from '@arkade-os/sdk/worker/expo';
|
|
2
|
+
import { ArkProvider, IndexerProvider, Identity, IWallet } from '@arkade-os/sdk';
|
|
3
|
+
import { m as SwapRepository, p as BoltzSwapProvider, N as Network, A as ArkadeSwapsConfig } from './types-BBI7-KJ0.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Dependencies injected into every swap processor at runtime.
|
|
7
|
+
*
|
|
8
|
+
* Unlike the wallet's `TaskDependencies`, these are swap-specific:
|
|
9
|
+
* we need the Boltz provider, swap repository, and identity to
|
|
10
|
+
* poll status and attempt claim/refund.
|
|
11
|
+
*/
|
|
12
|
+
interface SwapTaskDependencies {
|
|
13
|
+
swapRepository: SwapRepository;
|
|
14
|
+
swapProvider: BoltzSwapProvider;
|
|
15
|
+
arkProvider: ArkProvider;
|
|
16
|
+
indexerProvider: IndexerProvider;
|
|
17
|
+
identity: Identity;
|
|
18
|
+
wallet: IWallet;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Minimal config persisted to AsyncStorage for background rehydration.
|
|
22
|
+
*
|
|
23
|
+
* The background handler runs in a fresh JS context without access to
|
|
24
|
+
* the foreground's in-memory state, so we persist just enough to
|
|
25
|
+
* reconstruct providers and identity.
|
|
26
|
+
*/
|
|
27
|
+
interface PersistedSwapBackgroundConfig {
|
|
28
|
+
boltzApiUrl: string;
|
|
29
|
+
arkServerUrl: string;
|
|
30
|
+
network: Network;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Background scheduling configuration for {@link ExpoArkadeSwaps}.
|
|
34
|
+
*
|
|
35
|
+
* OS-level task registration is **not** part of this config — call
|
|
36
|
+
* `registerExpoSwapBackgroundTask` from `@arkade-os/boltz-swap/expo/background`
|
|
37
|
+
* explicitly. Splitting that step out keeps `/expo` free of the
|
|
38
|
+
* `expo-task-manager` / `expo-background-task` dependencies.
|
|
39
|
+
*/
|
|
40
|
+
interface ExpoSwapBackgroundConfig {
|
|
41
|
+
/** Persistence layer for foreground ↔ background handoff. */
|
|
42
|
+
taskQueue: AsyncStorageTaskQueue;
|
|
43
|
+
/** If set, acknowledges background results at this interval (ms) while the app is in the foreground. */
|
|
44
|
+
foregroundIntervalMs?: number;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Options for {@link defineExpoSwapBackgroundTask}.
|
|
48
|
+
*/
|
|
49
|
+
interface DefineSwapBackgroundTaskOptions {
|
|
50
|
+
/** AsyncStorage-backed queue (must match the one passed to ExpoArkadeSwaps.setup). */
|
|
51
|
+
taskQueue: AsyncStorageTaskQueue;
|
|
52
|
+
/** Swap repository (fresh instance is fine — connects to the same DB). */
|
|
53
|
+
swapRepository: SwapRepository;
|
|
54
|
+
/** Factory to reconstruct Identity from secure storage in the background. */
|
|
55
|
+
identityFactory: () => Promise<Identity>;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Configuration for {@link ExpoArkadeSwaps.setup}.
|
|
59
|
+
*/
|
|
60
|
+
interface ExpoArkadeSwapsConfig extends ArkadeSwapsConfig {
|
|
61
|
+
/**
|
|
62
|
+
* Ark server base URL (e.g. "https://ark.example.com").
|
|
63
|
+
*
|
|
64
|
+
* Recommended for type-safe background rehydration. If omitted,
|
|
65
|
+
* ExpoArkadeSwaps will attempt to derive it from the ArkProvider.
|
|
66
|
+
*/
|
|
67
|
+
arkServerUrl?: string;
|
|
68
|
+
background: ExpoSwapBackgroundConfig;
|
|
69
|
+
}
|
|
70
|
+
/** @deprecated Use ExpoArkadeSwapsConfig instead */
|
|
71
|
+
type ExpoArkadeLightningConfig = ExpoArkadeSwapsConfig;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Task type identifier for {@link swapsPollProcessor}.
|
|
75
|
+
*/
|
|
76
|
+
declare const SWAP_POLL_TASK_TYPE = "swap-poll";
|
|
77
|
+
/**
|
|
78
|
+
* Stateless processor that polls Boltz for swap status updates and
|
|
79
|
+
* attempts best-effort claim/refund for actionable swaps.
|
|
80
|
+
*
|
|
81
|
+
* Designed for Expo background tasks (~30s window) and follows the
|
|
82
|
+
* same `TaskProcessor` pattern as `contractPollProcessor` in ts-sdk.
|
|
83
|
+
*
|
|
84
|
+
* Steps:
|
|
85
|
+
* 1. Read all non-final swaps from SwapRepository
|
|
86
|
+
* 2. Poll Boltz HTTP API for each swap's current status
|
|
87
|
+
* 3. Persist status changes immediately
|
|
88
|
+
* 4. For actionable statuses: attempt claimVHTLC / refundVHTLC (best-effort)
|
|
89
|
+
* 5. Return summary metrics
|
|
90
|
+
*/
|
|
91
|
+
declare const swapsPollProcessor: TaskProcessor<SwapTaskDependencies>;
|
|
92
|
+
|
|
93
|
+
export { type DefineSwapBackgroundTaskOptions as D, type ExpoArkadeSwapsConfig as E, type PersistedSwapBackgroundConfig as P, SWAP_POLL_TASK_TYPE as S, type SwapTaskDependencies as a, type ExpoSwapBackgroundConfig as b, type ExpoArkadeLightningConfig as c, swapsPollProcessor as s };
|
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.31",
|
|
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",
|
|
@@ -26,6 +26,16 @@
|
|
|
26
26
|
"default": "./dist/expo/index.cjs"
|
|
27
27
|
}
|
|
28
28
|
},
|
|
29
|
+
"./expo/background": {
|
|
30
|
+
"import": {
|
|
31
|
+
"types": "./dist/expo/background.d.ts",
|
|
32
|
+
"default": "./dist/expo/background.js"
|
|
33
|
+
},
|
|
34
|
+
"require": {
|
|
35
|
+
"types": "./dist/expo/background.d.ts",
|
|
36
|
+
"default": "./dist/expo/background.cjs"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
29
39
|
"./repositories/sqlite": {
|
|
30
40
|
"import": {
|
|
31
41
|
"types": "./dist/repositories/sqlite/index.d.ts",
|
|
@@ -60,7 +70,7 @@
|
|
|
60
70
|
"author": "Arkade-OS",
|
|
61
71
|
"license": "MIT",
|
|
62
72
|
"dependencies": {
|
|
63
|
-
"@arkade-os/sdk": "0.4.
|
|
73
|
+
"@arkade-os/sdk": "0.4.26",
|
|
64
74
|
"@noble/hashes": "2.0.1",
|
|
65
75
|
"@scure/base": "2.0.0",
|
|
66
76
|
"@scure/btc-signer": "2.0.1",
|
|
@@ -68,6 +78,18 @@
|
|
|
68
78
|
"@noble/curves": "^2.0.1",
|
|
69
79
|
"light-bolt11-decoder": "3.2.0"
|
|
70
80
|
},
|
|
81
|
+
"peerDependencies": {
|
|
82
|
+
"expo-task-manager": ">=3.0.0",
|
|
83
|
+
"expo-background-task": ">=0.1.0"
|
|
84
|
+
},
|
|
85
|
+
"peerDependenciesMeta": {
|
|
86
|
+
"expo-task-manager": {
|
|
87
|
+
"optional": true
|
|
88
|
+
},
|
|
89
|
+
"expo-background-task": {
|
|
90
|
+
"optional": true
|
|
91
|
+
}
|
|
92
|
+
},
|
|
71
93
|
"devDependencies": {
|
|
72
94
|
"@eslint/js": "^9.35.0",
|
|
73
95
|
"@types/node": "^24.3.1",
|
|
@@ -91,7 +113,7 @@
|
|
|
91
113
|
"access": "public"
|
|
92
114
|
},
|
|
93
115
|
"scripts": {
|
|
94
|
-
"build": "tsup src/index.ts src/expo/index.ts src/repositories/sqlite/index.ts src/repositories/realm/index.ts --format esm,cjs --dts --clean",
|
|
116
|
+
"build": "tsup src/index.ts src/expo/index.ts src/expo/background.ts src/repositories/sqlite/index.ts src/repositories/realm/index.ts --format esm,cjs --dts --clean",
|
|
95
117
|
"format": "prettier --write src test",
|
|
96
118
|
"lint": "prettier --check src test",
|
|
97
119
|
"test": "vitest run",
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
defineExpoSwapBackgroundTask,
|
|
3
|
-
registerExpoSwapBackgroundTask,
|
|
4
|
-
unregisterExpoSwapBackgroundTask
|
|
5
|
-
} from "./chunk-X3JNWDAR.js";
|
|
6
|
-
import "./chunk-LWUXSE5N.js";
|
|
7
|
-
import "./chunk-3RG5ZIWI.js";
|
|
8
|
-
export {
|
|
9
|
-
defineExpoSwapBackgroundTask,
|
|
10
|
-
registerExpoSwapBackgroundTask,
|
|
11
|
-
unregisterExpoSwapBackgroundTask
|
|
12
|
-
};
|
package/dist/chunk-3RG5ZIWI.js
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
-
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
-
}) : x)(function(x) {
|
|
4
|
-
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
5
|
-
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
|
-
});
|
|
7
|
-
|
|
8
|
-
export {
|
|
9
|
-
__require
|
|
10
|
-
};
|
package/dist/chunk-X3JNWDAR.js
DELETED
|
@@ -1,261 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ArkadeSwaps,
|
|
3
|
-
BoltzSwapProvider,
|
|
4
|
-
isPendingReverseSwap,
|
|
5
|
-
isPendingSubmarineSwap,
|
|
6
|
-
isReverseClaimableStatus,
|
|
7
|
-
isReverseFinalStatus,
|
|
8
|
-
isSubmarineFinalStatus,
|
|
9
|
-
isSubmarineSwapRefundable,
|
|
10
|
-
logger
|
|
11
|
-
} from "./chunk-LWUXSE5N.js";
|
|
12
|
-
import {
|
|
13
|
-
__require
|
|
14
|
-
} from "./chunk-3RG5ZIWI.js";
|
|
15
|
-
|
|
16
|
-
// src/expo/background.ts
|
|
17
|
-
import { runTasks } from "@arkade-os/sdk/worker/expo";
|
|
18
|
-
import {
|
|
19
|
-
ExpoArkProvider,
|
|
20
|
-
ExpoIndexerProvider
|
|
21
|
-
} from "@arkade-os/sdk/adapters/expo";
|
|
22
|
-
|
|
23
|
-
// src/expo/swapsPollProcessor.ts
|
|
24
|
-
var SWAP_POLL_TASK_TYPE = "swap-poll";
|
|
25
|
-
var swapsPollProcessor = {
|
|
26
|
-
taskType: SWAP_POLL_TASK_TYPE,
|
|
27
|
-
async execute(item, deps) {
|
|
28
|
-
const {
|
|
29
|
-
swapRepository,
|
|
30
|
-
swapProvider,
|
|
31
|
-
wallet,
|
|
32
|
-
arkProvider,
|
|
33
|
-
indexerProvider
|
|
34
|
-
} = deps;
|
|
35
|
-
const allSwaps = await swapRepository.getAllSwaps();
|
|
36
|
-
const pendingSwaps = allSwaps.filter((swap) => {
|
|
37
|
-
if (isPendingReverseSwap(swap))
|
|
38
|
-
return !isReverseFinalStatus(swap.status);
|
|
39
|
-
if (isPendingSubmarineSwap(swap))
|
|
40
|
-
return !isSubmarineFinalStatus(swap.status);
|
|
41
|
-
return false;
|
|
42
|
-
});
|
|
43
|
-
let polled = 0;
|
|
44
|
-
let updated = 0;
|
|
45
|
-
let claimed = 0;
|
|
46
|
-
let refunded = 0;
|
|
47
|
-
let errors = 0;
|
|
48
|
-
const tempSwaps = new ArkadeSwaps({
|
|
49
|
-
wallet,
|
|
50
|
-
arkProvider,
|
|
51
|
-
indexerProvider,
|
|
52
|
-
swapProvider,
|
|
53
|
-
swapManager: false,
|
|
54
|
-
swapRepository
|
|
55
|
-
});
|
|
56
|
-
try {
|
|
57
|
-
for (const swap of pendingSwaps) {
|
|
58
|
-
try {
|
|
59
|
-
const { status: currentStatus } = await swapProvider.getSwapStatus(swap.id);
|
|
60
|
-
polled++;
|
|
61
|
-
if (currentStatus !== swap.status) {
|
|
62
|
-
await swapRepository.saveSwap({
|
|
63
|
-
...swap,
|
|
64
|
-
status: currentStatus
|
|
65
|
-
});
|
|
66
|
-
updated++;
|
|
67
|
-
}
|
|
68
|
-
if (isPendingReverseSwap(swap) && isReverseClaimableStatus(currentStatus)) {
|
|
69
|
-
if (!swap.preimage) {
|
|
70
|
-
logger.warn(
|
|
71
|
-
`[swap-poll] Skipping claim for ${swap.id}: no preimage`
|
|
72
|
-
);
|
|
73
|
-
continue;
|
|
74
|
-
}
|
|
75
|
-
try {
|
|
76
|
-
await tempSwaps.claimVHTLC(swap);
|
|
77
|
-
claimed++;
|
|
78
|
-
} catch (claimError) {
|
|
79
|
-
logger.error(
|
|
80
|
-
`[swap-poll] Claim failed for ${swap.id}:`,
|
|
81
|
-
claimError
|
|
82
|
-
);
|
|
83
|
-
errors++;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
const swapWithStatus = isPendingSubmarineSwap(swap) ? { ...swap, status: currentStatus } : null;
|
|
87
|
-
if (isPendingSubmarineSwap(swap) && isSubmarineSwapRefundable(swapWithStatus)) {
|
|
88
|
-
if (!swap.request.invoice && !swap.preimageHash) {
|
|
89
|
-
logger.warn(
|
|
90
|
-
`[swap-poll] Skipping refund for ${swap.id}: no invoice or preimageHash`
|
|
91
|
-
);
|
|
92
|
-
continue;
|
|
93
|
-
}
|
|
94
|
-
try {
|
|
95
|
-
await tempSwaps.refundVHTLC(swapWithStatus);
|
|
96
|
-
refunded++;
|
|
97
|
-
} catch (refundError) {
|
|
98
|
-
logger.error(
|
|
99
|
-
`[swap-poll] Refund failed for ${swap.id}:`,
|
|
100
|
-
refundError
|
|
101
|
-
);
|
|
102
|
-
errors++;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
} catch (swapError) {
|
|
106
|
-
logger.error(
|
|
107
|
-
`[swap-poll] Error processing swap ${swap.id}:`,
|
|
108
|
-
swapError
|
|
109
|
-
);
|
|
110
|
-
errors++;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
} finally {
|
|
114
|
-
await tempSwaps.dispose();
|
|
115
|
-
}
|
|
116
|
-
return {
|
|
117
|
-
taskItemId: item.id,
|
|
118
|
-
type: SWAP_POLL_TASK_TYPE,
|
|
119
|
-
status: errors > 0 && polled === 0 ? "failed" : "success",
|
|
120
|
-
data: { polled, updated, claimed, refunded, errors }
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
// src/expo/background.ts
|
|
126
|
-
function requireTaskManager() {
|
|
127
|
-
try {
|
|
128
|
-
return __require("expo-task-manager");
|
|
129
|
-
} catch {
|
|
130
|
-
throw new Error(
|
|
131
|
-
"expo-task-manager is required for background tasks. Install it with: npx expo install expo-task-manager"
|
|
132
|
-
);
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
function requireBackgroundTask() {
|
|
136
|
-
try {
|
|
137
|
-
return __require("expo-background-task");
|
|
138
|
-
} catch {
|
|
139
|
-
throw new Error(
|
|
140
|
-
"expo-background-task is required for background tasks. Install it with: npx expo install expo-background-task"
|
|
141
|
-
);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
function getRandomId() {
|
|
145
|
-
return Math.random().toString(36).slice(2) + Date.now().toString(36);
|
|
146
|
-
}
|
|
147
|
-
function createBackgroundWalletShim(args) {
|
|
148
|
-
const notImplemented = (method) => {
|
|
149
|
-
throw new Error(
|
|
150
|
-
`[boltz-swap] Background wallet shim: "${String(method)}" is not implemented`
|
|
151
|
-
);
|
|
152
|
-
};
|
|
153
|
-
return {
|
|
154
|
-
identity: args.identity,
|
|
155
|
-
getAddress: args.getAddress,
|
|
156
|
-
getBoardingAddress: async () => notImplemented("getBoardingAddress"),
|
|
157
|
-
getBalance: async () => notImplemented("getBalance"),
|
|
158
|
-
getVtxos: async () => notImplemented("getVtxos"),
|
|
159
|
-
getBoardingUtxos: async () => notImplemented("getBoardingUtxos"),
|
|
160
|
-
getTransactionHistory: async () => notImplemented("getTransactionHistory"),
|
|
161
|
-
getContractManager: async () => notImplemented("getContractManager"),
|
|
162
|
-
getDelegatorManager: async () => notImplemented("getDelegatorManager"),
|
|
163
|
-
sendBitcoin: async () => notImplemented("sendBitcoin"),
|
|
164
|
-
send: async () => notImplemented("send"),
|
|
165
|
-
settle: async () => notImplemented("settle"),
|
|
166
|
-
assetManager: new Proxy({}, {
|
|
167
|
-
get: () => notImplemented("assetManager")
|
|
168
|
-
})
|
|
169
|
-
};
|
|
170
|
-
}
|
|
171
|
-
function defineExpoSwapBackgroundTask(taskName, options) {
|
|
172
|
-
const TaskManager = requireTaskManager();
|
|
173
|
-
const BackgroundTask = requireBackgroundTask();
|
|
174
|
-
const { taskQueue, swapRepository, identityFactory } = options;
|
|
175
|
-
TaskManager.defineTask(taskName, async () => {
|
|
176
|
-
try {
|
|
177
|
-
const config = await taskQueue.loadConfig();
|
|
178
|
-
if (!config) {
|
|
179
|
-
return BackgroundTask.BackgroundTaskResult.Success;
|
|
180
|
-
}
|
|
181
|
-
const identity = await identityFactory();
|
|
182
|
-
const arkProvider = new ExpoArkProvider(config.arkServerUrl);
|
|
183
|
-
const indexerProvider = new ExpoIndexerProvider(
|
|
184
|
-
config.arkServerUrl
|
|
185
|
-
);
|
|
186
|
-
const swapProvider = new BoltzSwapProvider({
|
|
187
|
-
network: config.network,
|
|
188
|
-
apiUrl: config.boltzApiUrl
|
|
189
|
-
});
|
|
190
|
-
const wallet = createBackgroundWalletShim({
|
|
191
|
-
identity,
|
|
192
|
-
getAddress: async () => {
|
|
193
|
-
const { ArkAddress } = await import("@arkade-os/sdk");
|
|
194
|
-
const { hex } = await import("@scure/base");
|
|
195
|
-
const info = await arkProvider.getInfo();
|
|
196
|
-
const pubkey = await identity.xOnlyPublicKey();
|
|
197
|
-
const serverPubKey = hex.decode(info.signerPubkey);
|
|
198
|
-
const xOnlyServerPubKey = serverPubKey.length === 33 ? serverPubKey.slice(1) : serverPubKey;
|
|
199
|
-
const hrp = info.network === "bitcoin" ? "ark" : "tark";
|
|
200
|
-
return new ArkAddress(
|
|
201
|
-
xOnlyServerPubKey,
|
|
202
|
-
pubkey,
|
|
203
|
-
hrp
|
|
204
|
-
).encode();
|
|
205
|
-
}
|
|
206
|
-
});
|
|
207
|
-
const deps = {
|
|
208
|
-
swapRepository,
|
|
209
|
-
swapProvider,
|
|
210
|
-
arkProvider,
|
|
211
|
-
indexerProvider,
|
|
212
|
-
identity,
|
|
213
|
-
wallet
|
|
214
|
-
};
|
|
215
|
-
await runTasks(taskQueue, [swapsPollProcessor], deps);
|
|
216
|
-
const results = await taskQueue.getResults();
|
|
217
|
-
if (results.length > 0) {
|
|
218
|
-
await taskQueue.acknowledgeResults(
|
|
219
|
-
results.map((r) => r.id)
|
|
220
|
-
);
|
|
221
|
-
}
|
|
222
|
-
const existing = await taskQueue.getTasks(SWAP_POLL_TASK_TYPE);
|
|
223
|
-
if (existing.length === 0) {
|
|
224
|
-
const task = {
|
|
225
|
-
id: getRandomId(),
|
|
226
|
-
type: SWAP_POLL_TASK_TYPE,
|
|
227
|
-
data: {},
|
|
228
|
-
createdAt: Date.now()
|
|
229
|
-
};
|
|
230
|
-
await taskQueue.addTask(task);
|
|
231
|
-
}
|
|
232
|
-
return BackgroundTask.BackgroundTaskResult.Success;
|
|
233
|
-
} catch (error) {
|
|
234
|
-
console.error(
|
|
235
|
-
"[boltz-swap] Background task failed:",
|
|
236
|
-
error instanceof Error ? error.message : error
|
|
237
|
-
);
|
|
238
|
-
return BackgroundTask.BackgroundTaskResult.Failed;
|
|
239
|
-
}
|
|
240
|
-
});
|
|
241
|
-
}
|
|
242
|
-
async function registerExpoSwapBackgroundTask(taskName, options) {
|
|
243
|
-
const BackgroundTask = requireBackgroundTask();
|
|
244
|
-
await BackgroundTask.registerTaskAsync(taskName, {
|
|
245
|
-
// expo-background-task expects minutes:
|
|
246
|
-
// https://docs.expo.dev/versions/latest/sdk/background-task/#backgroundtaskoptions
|
|
247
|
-
minimumInterval: options?.minimumInterval ?? 15
|
|
248
|
-
});
|
|
249
|
-
}
|
|
250
|
-
async function unregisterExpoSwapBackgroundTask(taskName) {
|
|
251
|
-
const BackgroundTask = requireBackgroundTask();
|
|
252
|
-
await BackgroundTask.unregisterTaskAsync(taskName);
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
export {
|
|
256
|
-
SWAP_POLL_TASK_TYPE,
|
|
257
|
-
swapsPollProcessor,
|
|
258
|
-
defineExpoSwapBackgroundTask,
|
|
259
|
-
registerExpoSwapBackgroundTask,
|
|
260
|
-
unregisterExpoSwapBackgroundTask
|
|
261
|
-
};
|