aboutsummaryrefslogtreecommitdiffstats
path: root/src/features
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-08-04 08:31:21 -0700
committerAdam Soltys <[email protected]>2026-08-04 08:31:21 -0700
commit9fd8887dcdd5e0fc1067a91032bfd18eb25f0202 (patch)
tree0ab3da2a80bb69a71139697852da646576f4f23f /src/features
parent40c26324c556dc47be7e392391420183a36a6c3d (diff)
downloadcoinosv3-9fd8887dcdd5e0fc1067a91032bfd18eb25f0202.tar.gz
coinosv3-9fd8887dcdd5e0fc1067a91032bfd18eb25f0202.zip
Ark gifts go down to 1 sat; negative amounts can't OOM the encoder
Regtest-proven (tools/ark/dust-gift-test.js): the ASP cosigns all-dust arkoor sends, so a sub-dust bearer vtxo sweeps to its claimer fine, and dust folds into rounds alongside bigger siblings. The 330-sat gift floor guarded a failure that can't happen — dropped to 1 sat. The experiment also caught a live bug: refresh() of a balance smaller than the round fee computed a negative output amount, and pbWriter's varint sign-extends negatives into an infinite loop — auto-refresh would OOM the tab of any wallet too small to renew. varint now throws on negatives and refresh() refuses cleanly, before marking coins pending, when balance minus fee is under the server's 330-sat output minimum. Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_015QwAtBSpKvECqp1rHLHjJk
Diffstat (limited to 'src/features')
-rw-r--r--src/features/gifts.js7
1 files changed, 6 insertions, 1 deletions
diff --git a/src/features/gifts.js b/src/features/gifts.js
index bc16619..0543030 100644
--- a/src/features/gifts.js
+++ b/src/features/gifts.js
@@ -402,11 +402,16 @@ export function giftsFeature(ctx) {
// An ark gift: send the amount to a fresh bearer identity, off-chain and
// instant — no coin locking, no split logic, no claim fee.
+ // Gifts go down to 1 sat: the ASP cosigns all-dust arkoor sends, so a
+ // sub-dust bearer vtxo sweeps to the claimer fine (regtest-proven —
+ // tools/ark/dust-gift-test.js). The trade a sub-330 coin carries — no
+ // unilateral exit on its own, renewable in rounds only alongside bigger
+ // siblings — is the same one dust zaps already make.
async function doCreateArkGift() {
const info = hook('arkGiftInfo');
const avail = info ? info.spendableSat : 0;
const amt = ui.giftMax ? avail : parseAmount(ui.giftAmount, getUnit());
- if (!amt || amt < 330) { ui.giftError = t('giftAmountInvalid', { n: fmtAmount(330) + ' ' + unitLabel() }); render(); return; }
+ if (!amt || amt < 1) { ui.giftError = t('giftAmountInvalid', { n: fmtAmount(1) + ' ' + unitLabel() }); render(); return; }
if (amt > avail) { ui.giftError = t('giftExceedsBalance'); render(); return; }
ui.busy = true; ui.giftError = ''; render();
try {