Skip to content

Commit bd803c8

Browse files
committed
refactor: update @arkade-os/boltz-swap to version 0.3.8 and adjust related code
1 parent bbbe386 commit bd803c8

File tree

7 files changed

+102
-77
lines changed

7 files changed

+102
-77
lines changed

cli/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"dev": "tsx src/index.ts"
1919
},
2020
"dependencies": {
21-
"@arkade-os/boltz-swap": "^0.2.18",
21+
"@arkade-os/boltz-swap": "^0.3.8",
2222
"@arkade-os/sdk": "^0.4.10",
2323
"@lendasat/lendaswap-sdk-pure": "^0.0.2",
2424
"@noble/hashes": "^2.0.1",

cli/src/context.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
SqliteWalletStorage,
1414
SqliteSwapStorage,
1515
} from "@lendasat/lendaswap-sdk-pure/node";
16+
import { SQLiteSwapRepository } from "@arkade-os/boltz-swap/repositories/sqlite";
1617
import {
1718
ArkadeBitcoinSkill,
1819
ArkadeLightningSkill,
@@ -72,6 +73,7 @@ export async function createContext(config: CashConfig, opts?: CreateContextOpts
7273
wallet,
7374
network: config.network as NetworkName,
7475
enableSwapManager: opts?.enableSwapManager,
76+
swapRepository: new SQLiteSwapRepository(executor),
7577
});
7678

7779
// Persistent SQLite storage for LendaSwap

cli/src/daemon.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,13 @@ export async function startDaemonInBackground(port: number): Promise<{ pid: numb
6060

6161
const logFd = openSync(LOG_FILE, "a");
6262

63-
// Use the same node binary and entrypoint that's currently running
64-
// This works both in dev (tsx cli/src/index.ts) and production (node dist/index.js)
63+
// Reproduce the exact node invocation that's currently running.
64+
// process.execArgv carries tsx loader flags in dev (e.g. --import tsx/esm)
65+
// and is empty in production (node dist/index.js).
6566
const nodeBin = process.execPath;
6667
const entrypoint = process.argv[1];
6768

68-
const child = spawn(nodeBin, [entrypoint, "--daemon-internal", "--port", String(port)], {
69+
const child = spawn(nodeBin, [...process.execArgv, entrypoint, "--daemon-internal", "--port", String(port)], {
6970
cwd: process.cwd(),
7071
env: { ...process.env },
7172
detached: true,

cli/src/index.ts

Lines changed: 54 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -304,18 +304,32 @@ async function runDaemon() {
304304
const authMonitor = new AuthMonitor();
305305
const server = createDaemonServer({ port, ctx, monitor, authMonitor, webhookRegistry });
306306

307-
// Start Lightning SwapManager
308-
await ctx.lightning.startSwapManager();
309-
console.error("[daemon] lightning swap manager started");
307+
// Start HTTP server first — so the parent's /health poll succeeds immediately
308+
// (startSwapManager and getDelegatorManager are awaited below in the background)
309+
server.listen(port, "127.0.0.1", () => {
310+
saveDaemonPid(process.pid, port);
311+
console.error(`[daemon] listening on http://127.0.0.1:${port}`);
312+
});
310313

311314
// Start LendaSwap poller
312315
monitor.start();
313316
console.error("[daemon] lendaswap monitor started");
314317

315-
// Recover swept VTXOs on startup
316-
const wallet = ctx.bitcoin.getWallet();
317-
const vtxoManager = new VtxoManager(wallet);
318+
let stopVtxoDelegate: (() => void) | undefined;
319+
320+
// Background init: Lightning swap manager + VTXO recovery + auto-delegation
318321
void (async () => {
322+
// Start Lightning SwapManager
323+
try {
324+
await ctx.lightning.startSwapManager();
325+
console.error("[daemon] lightning swap manager started");
326+
} catch (err) {
327+
console.error(`[daemon] lightning swap manager error: ${err instanceof Error ? err.message : err}`);
328+
}
329+
330+
// Recover swept VTXOs on startup
331+
const wallet = ctx.bitcoin.getWallet();
332+
const vtxoManager = new VtxoManager(wallet);
319333
try {
320334
const recoverable = await vtxoManager.getRecoverableBalance();
321335
if (recoverable.recoverable > 0n) {
@@ -326,48 +340,45 @@ async function runDaemon() {
326340
} catch (err) {
327341
console.error(`[daemon] vtxo recovery error: ${err instanceof Error ? err.message : err}`);
328342
}
329-
})();
330-
331-
// Auto-delegate VTXOs when delegator is configured
332-
let stopVtxoDelegate: (() => void) | undefined;
333-
const delegatorManager = await wallet.getDelegatorManager();
334-
if (delegatorManager) {
335-
const delegateSettled = async () => {
336-
try {
337-
const vtxos = (await wallet.getVtxos({ withRecoverable: false })).filter(
338-
(v: ExtendedVirtualCoin) => v.virtualStatus.state === "settled"
339-
);
340-
if (vtxos.length === 0) return;
341-
const address = await wallet.getAddress();
342-
const result = await delegatorManager.delegate(vtxos, address);
343-
if (result.delegated.length > 0) {
344-
console.error(`[daemon] delegated ${result.delegated.length} vtxo(s) for auto-renewal`);
345-
}
346-
} catch (err) {
347-
console.error(`[daemon] vtxo delegation error: ${err instanceof Error ? err.message : err}`);
348-
}
349-
};
350343

351-
// Delegate any existing settled VTXOs on startup
352-
void delegateSettled();
344+
// Auto-delegate VTXOs when delegator is configured
345+
try {
346+
const delegatorManager = await wallet.getDelegatorManager();
347+
if (delegatorManager) {
348+
const delegateSettled = async () => {
349+
try {
350+
const vtxos = (await wallet.getVtxos({ withRecoverable: false })).filter(
351+
(v: ExtendedVirtualCoin) => v.virtualStatus.state === "settled"
352+
);
353+
if (vtxos.length === 0) return;
354+
const address = await wallet.getAddress();
355+
const result = await delegatorManager.delegate(vtxos, address);
356+
if (result.delegated.length > 0) {
357+
console.error(`[daemon] delegated ${result.delegated.length} vtxo(s) for auto-renewal`);
358+
}
359+
} catch (err) {
360+
console.error(`[daemon] vtxo delegation error: ${err instanceof Error ? err.message : err}`);
361+
}
362+
};
353363

354-
// Subscribe and delegate on every incoming VTXO
355-
wallet.notifyIncomingFunds((funds: IncomingFunds) => {
356-
if (funds.type === "vtxo" && funds.newVtxos.length > 0) {
364+
// Delegate any existing settled VTXOs on startup
357365
void delegateSettled();
358-
}
359-
}).then((stop: () => void) => { stopVtxoDelegate = stop; }).catch((err: unknown) => {
360-
console.error(`[daemon] vtxo delegate subscription error: ${err instanceof Error ? err.message : err}`);
361-
});
362366

363-
console.error("[daemon] vtxo auto-delegation started");
364-
}
367+
// Subscribe and delegate on every incoming VTXO
368+
wallet.notifyIncomingFunds((funds: IncomingFunds) => {
369+
if (funds.type === "vtxo" && funds.newVtxos.length > 0) {
370+
void delegateSettled();
371+
}
372+
}).then((stop: () => void) => { stopVtxoDelegate = stop; }).catch((err: unknown) => {
373+
console.error(`[daemon] vtxo delegate subscription error: ${err instanceof Error ? err.message : err}`);
374+
});
365375

366-
// Start HTTP server
367-
server.listen(port, "127.0.0.1", () => {
368-
saveDaemonPid(process.pid, port);
369-
console.error(`[daemon] listening on http://127.0.0.1:${port}`);
370-
});
376+
console.error("[daemon] vtxo auto-delegation started");
377+
}
378+
} catch (err) {
379+
console.error(`[daemon] delegator init error: ${err instanceof Error ? err.message : err}`);
380+
}
381+
})();
371382

372383
// Graceful shutdown
373384
const shutdown = async () => {

pnpm-lock.yaml

Lines changed: 17 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

skills/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010
"typecheck": "tsc --noEmit"
1111
},
1212
"dependencies": {
13-
"@clw-cash/sdk": "workspace:*",
13+
"@arkade-os/boltz-swap": "^0.3.8",
1414
"@arkade-os/sdk": "^0.4.10",
15-
"@arkade-os/boltz-swap": "^0.2.18",
15+
"@clw-cash/sdk": "workspace:*",
1616
"@lendasat/lendaswap-sdk-pure": "^0.0.2"
1717
},
1818
"devDependencies": {

skills/src/skills/lightning.ts

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import {
2-
ArkadeLightning,
2+
ArkadeSwaps,
33
BoltzSwapProvider,
44
decodeInvoice,
5+
type SwapRepository,
56
type PendingReverseSwap,
67
type PendingSubmarineSwap,
78
} from "@arkade-os/boltz-swap";
@@ -36,6 +37,7 @@ export interface ArkadeLightningSkillConfig {
3637
boltzApiUrl?: string;
3738
referralId?: string;
3839
enableSwapManager?: boolean;
40+
swapRepository?: SwapRepository;
3941
}
4042

4143
export class ArkadeLightningSkill implements LightningSkill {
@@ -44,7 +46,7 @@ export class ArkadeLightningSkill implements LightningSkill {
4446
"Lightning Network payments via Boltz submarine swaps for Arkade wallets";
4547
readonly version = "1.0.0";
4648

47-
private readonly arkadeLightning: ArkadeLightning;
49+
private readonly arkadeSwaps: ArkadeSwaps;
4850
private readonly swapProvider: BoltzSwapProvider;
4951
private readonly network: NetworkName;
5052
private readonly swapErrors = new Map<string, string>();
@@ -63,20 +65,21 @@ export class ArkadeLightningSkill implements LightningSkill {
6365
referralId: config.referralId,
6466
});
6567

66-
this.arkadeLightning = new ArkadeLightning({
68+
this.arkadeSwaps = new ArkadeSwaps({
6769
wallet: config.wallet as ConstructorParameters<
68-
typeof ArkadeLightning
70+
typeof ArkadeSwaps
6971
>[0]["wallet"],
7072
swapProvider: this.swapProvider,
7173
arkProvider: config.arkProvider,
7274
indexerProvider: config.indexerProvider,
75+
swapRepository: config.swapRepository,
7376
swapManager: config.enableSwapManager
74-
? { enableAutoActions: true, autoStart: true }
75-
: undefined,
77+
? { autoStart: true }
78+
: false,
7679
});
7780

7881
// Track swap errors from SwapManager for debugging
79-
const manager = this.arkadeLightning.getSwapManager?.();
82+
const manager = this.arkadeSwaps.getSwapManager?.();
8083
if (manager) {
8184
manager.onSwapFailed?.((swap: { id: string }, error: unknown) => {
8285
const msg = error instanceof Error ? error.message : String(error);
@@ -96,7 +99,7 @@ export class ArkadeLightningSkill implements LightningSkill {
9699
}
97100

98101
async createInvoice(params: CreateInvoiceParams): Promise<LightningInvoice> {
99-
const response = await this.arkadeLightning.createLightningInvoice({
102+
const response = await this.arkadeSwaps.createLightningInvoice({
100103
amount: params.amount,
101104
description: params.description,
102105
});
@@ -115,7 +118,7 @@ export class ArkadeLightningSkill implements LightningSkill {
115118
}
116119

117120
async payInvoice(params: PayInvoiceParams): Promise<PaymentResult> {
118-
const response = await this.arkadeLightning.sendLightningPayment({
121+
const response = await this.arkadeSwaps.sendLightningPayment({
119122
invoice: params.bolt11,
120123
});
121124

@@ -127,17 +130,17 @@ export class ArkadeLightningSkill implements LightningSkill {
127130
}
128131

129132
async getFees(): Promise<LightningFees> {
130-
return this.arkadeLightning.getFees();
133+
return this.arkadeSwaps.getFees();
131134
}
132135

133136
async getLimits(): Promise<LightningLimits> {
134-
return this.arkadeLightning.getLimits();
137+
return this.arkadeSwaps.getLimits();
135138
}
136139

137140
async getPendingSwaps(): Promise<SwapInfo[]> {
138141
// Refresh statuses from Boltz API before returning
139142
try {
140-
await this.arkadeLightning.refreshSwapsStatus();
143+
await this.arkadeSwaps.refreshSwapsStatus();
141144
} catch {
142145
// Non-fatal: return stale data if refresh fails
143146
}
@@ -147,7 +150,7 @@ export class ArkadeLightningSkill implements LightningSkill {
147150
}
148151

149152
async getSwapHistory(): Promise<SwapInfo[]> {
150-
const history = await this.arkadeLightning.getSwapHistory();
153+
const history = await this.arkadeSwaps.getSwapHistory();
151154
return history.map((swap) =>
152155
swap.type === "reverse"
153156
? this.mapReverseSwap(swap as PendingReverseSwap)
@@ -158,27 +161,27 @@ export class ArkadeLightningSkill implements LightningSkill {
158161
async waitAndClaim(
159162
pendingSwap: PendingReverseSwap
160163
): Promise<{ txid: string }> {
161-
return this.arkadeLightning.waitAndClaim(pendingSwap);
164+
return this.arkadeSwaps.waitAndClaim(pendingSwap);
162165
}
163166

164-
getArkadeLightning(): ArkadeLightning {
165-
return this.arkadeLightning;
167+
getArkadeSwaps(): ArkadeSwaps {
168+
return this.arkadeSwaps;
166169
}
167170

168171
getSwapProvider(): BoltzSwapProvider {
169172
return this.swapProvider;
170173
}
171174

172175
async startSwapManager(): Promise<void> {
173-
await this.arkadeLightning.startSwapManager();
176+
await this.arkadeSwaps.startSwapManager();
174177
}
175178

176179
async stopSwapManager(): Promise<void> {
177-
await this.arkadeLightning.stopSwapManager();
180+
await this.arkadeSwaps.stopSwapManager();
178181
}
179182

180183
async dispose(): Promise<void> {
181-
await this.arkadeLightning.dispose();
184+
await this.arkadeSwaps.dispose();
182185
}
183186

184187
private mapReverseSwap(swap: PendingReverseSwap): SwapInfo {

0 commit comments

Comments
 (0)