From 229dea361b719128cf2657b6ab51aad9aca463b1 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Tue, 15 Sep 2026 21:18:17 -0700 Subject: A tiny coin's renewal chip says "under 1 sat", not "1 sat". MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The server prices a renewal on all the coins together: ppm accumulates sub-satoshi across every input and rounds up once. The per-coin chip rounded each coin's share up on its own, so nine 1-sat coins each showed "renewal cost 1 sat" under a total of 4 sats — as if the page were skipping them. The chip now shows the coin's real share: "under 1 sat" for a sub-satoshi one, rounded otherwise, and its tooltip says how the fee is priced. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01JuwQqNWtDJcxPWtEm9134z --- src/features/ark.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'src/features/ark.js') diff --git a/src/features/ark.js b/src/features/ark.js index e0c8f19..fe1fe90 100644 --- a/src/features/ark.js +++ b/src/features/ark.js @@ -2044,7 +2044,15 @@ export function arkFeature(ctx) { // bracket it's free, where the wallet renews on its own anyway. const table = ((mgr.info || {}).refreshFees || {}).ppmExpiryTable || []; const ppmFor = (blocks) => (table.filter((e) => e.thresholdBlocks <= blocks).pop()?.ppm) ?? 0; - const feeNowOf = (v) => Math.ceil((v.amountSat * ppmFor((v.expiryHeight || 0) - tip)) / 1_000_000); + // A coin's SHARE of the renewal fee, fractional: the server totals the + // ppm across every coin in the round and rounds up once (refreshFee), so + // a 1-sat coin costs a few thousandths of a sat, not the 1 sat a + // per-coin ceiling used to print — nine such chips summing past the + // real total made it look as if the page were skipping them. + const feeNowOf = (v) => (v.amountSat * ppmFor((v.expiryHeight || 0) - tip)) / 1_000_000; + const renewChip = (share) => share <= 0 ? t('arkDepthFree') + : share < 1 ? t('arkCoinsChipRenewTiny') + : fmtAmount(Math.round(share)) + ' ' + unitLabel(); const span = (blocks) => { if (blocks >= 144) { const d = Math.round(blocks / 144); @@ -2125,7 +2133,7 @@ export function arkFeature(ctx) { h('span', { class: 'coin-chip', title: t('arkCoinsChipExitTitle') }, t('arkCoinsChipExit', { fee: xf == null ? '—' : fmtAmount(xf) + ' ' + unitLabel() })), h('span', { class: 'coin-chip', title: t('arkCoinsChipRenewTitle') }, - t('arkCoinsChipRenew', { fee: f > 0 ? fmtAmount(f) + ' ' + unitLabel() : t('arkDepthFree') }))))); + t('arkCoinsChipRenew', { fee: renewChip(f) }))))); })), h('p', { class: 'small faint', style: 'margin:4px 0 0' }, t('arkCoinsExpiryNote'))), h('div', { class: 'card col', style: 'gap:8px' }, -- cgit v1.2.3