aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-08-30 20:00:27 -0700
committerAdam Soltys <[email protected]>2026-08-30 20:00:27 -0700
commitb64eb328134503865500ccf8ab58741fea864452 (patch)
tree6baa61159dac9611d3bdfa82fa1f3f664e76cc4a /src
parent470a37ca9cddc6ef03e06c873f59c4ffc699de48 (diff)
downloadcoinosv3-b64eb328134503865500ccf8ab58741fea864452.tar.gz
coinosv3-b64eb328134503865500ccf8ab58741fea864452.zip
Max on the board form stops promising sats the funding transaction can't carry: the sweep draft now prices against a taproot output (the board funding address's real shape) instead of the wallet's 12-vbytes-smaller P2WPKH change — tapping Max then Move earned 'insufficient funds for amount + fee' by exactly that margin
Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01MrkLsNScXe9b6BviUSdmMr
Diffstat (limited to 'src')
-rw-r--r--src/features/ark.js13
1 files changed, 10 insertions, 3 deletions
diff --git a/src/features/ark.js b/src/features/ark.js
index 9cc2222..0e307b1 100644
--- a/src/features/ark.js
+++ b/src/features/ark.js
@@ -8,7 +8,7 @@ import { hex, base32nopad, bech32 } from '@scure/base';
import { sha256 } from '@noble/hashes/sha256';
import { ArkManager } from '../ark/manager.js';
import { loadBg, saveBg, buildBg, disarmSiblingRecords } from '../nwc-bg.js';
-import { boardFee } from '../ark/board.js';
+import { boardFee, p2trAddress } from '../ark/board.js';
import { maybeBolt11, maybeLnInvoice, lnSendFee } from '../ark/lightning.js';
import { decodeVtxo, getVtxoStatus, VTXO_STATE_SPENT, concatBytes } from '../ark/proto.js';
import { signedExitTxs, buildBumpChild, buildExitClaim, submitPackage } from '../ark/exit.js';
@@ -2321,11 +2321,18 @@ export function arkFeature(ctx) {
}
// Boarding drains an on-chain balance, so Max must leave room for the
- // mining fee: ask the tx builder what a sweep would actually deliver.
+ // mining fee: ask the tx builder what a sweep would actually deliver — TO
+ // THE REAL OUTPUT SHAPE. The board funding address is P2TR, 12 vbytes
+ // bigger than this wallet's P2WPKH change; drafting the sweep against
+ // change priced Max a dozen sats past what the funding transaction could
+ // carry, and tapping Max earned "insufficient funds". The manager's own
+ // key stands in for the funding key — same size, always a valid point.
function maxBoardSat() {
try {
const feeRate = (wallet.feeRates && wallet.feeRates.halfHourFee) || 5;
- const draft = wallet.buildTx({ recipients: [{ address: wallet.freshChange().address, amount: 0 }], feeRate, sendMax: true });
+ const hrp = { bitcoin: 'bc', regtest: 'bcrt' }[ark && ark.info && ark.info.network] || 'tb';
+ const dest = ark ? p2trAddress(ark._key(0).pubkey, hrp) : wallet.freshChange().address;
+ const draft = wallet.buildTx({ recipients: [{ address: dest, amount: 0 }], feeRate, sendMax: true });
return Math.max(0, (draft.outputs[0]?.amount || 0));
} catch {
return 0;