aboutsummaryrefslogtreecommitdiffstats
path: root/src/features
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-08-14 21:37:23 -0700
committerAdam Soltys <[email protected]>2026-08-14 21:37:23 -0700
commit07ac3d010a74f1aa84c463817c0a7ed7d510dbb6 (patch)
treecc383348384e045942e1cad1f2f040cf0a3c85ff /src/features
parent222391a31361e42db713d1737d5a6e15cf8d5ed2 (diff)
downloadcoinosv3-07ac3d010a74f1aa84c463817c0a7ed7d510dbb6.tar.gz
coinosv3-07ac3d010a74f1aa84c463817c0a7ed7d510dbb6.zip
Zaps too gather what they need: several coins each lock an HTLC under one payment hash and the server sums them — the fragmented-balance error is gone from Lightning as well
Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_014tE4U5nEjGTQy8PwYqamfv
Diffstat (limited to 'src/features')
-rw-r--r--src/features/ark.js16
1 files changed, 13 insertions, 3 deletions
diff --git a/src/features/ark.js b/src/features/ark.js
index 9e0902a..aa9623b 100644
--- a/src/features/ark.js
+++ b/src/features/ark.js
@@ -629,14 +629,24 @@ export function arkFeature(ctx) {
const routing = await mgr.lnRouteFee(invoice, p.amountSat);
if (!ui.arkLnPay || ui.arkLnPay !== p || p.invoice !== invoice) return;
p.routingFeeSat = routing;
- const candidates = mgr.vtxos().filter((v) => v.state === 'spendable')
- .sort((a, b) => a.amountSat - b.amountSat);
+ const spendables = mgr.vtxos().filter((v) => v.state === 'spendable');
let fee = null;
- for (const v of candidates) {
+ for (const v of [...spendables].sort((a, b) => a.amountSat - b.amountSat)) {
const f = lnSendFee(p.amountSat, mgr.info.lnSendFees, [v], tip) + routing;
if (v.amountSat >= p.amountSat + f) { fee = f; break; }
}
if (fee == null) {
+ // no single coin covers it — the pay path gathers several, so quote for
+ // the same largest-first set it will pick
+ const picked = [];
+ let sum = 0;
+ for (const v of [...spendables].sort((a, b) => b.amountSat - a.amountSat)) {
+ picked.push(v); sum += v.amountSat;
+ const f = lnSendFee(p.amountSat, mgr.info.lnSendFees, picked, tip) + routing;
+ if (sum >= p.amountSat + f) { fee = f; break; }
+ }
+ }
+ if (fee == null) {
const pendingCover = mgr.vtxos().some((v) => v.state === 'pending' && v.amountSat >= p.amountSat);
if (pendingCover) {
p.status = 'fundsPending';