diff options
| author | Adam Soltys <[email protected]> | 2026-06-24 14:12:46 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-06-24 14:12:46 -0700 |
| commit | 3463af1d81c2712d657bbf30ecba98ffe5873729 (patch) | |
| tree | 897aa78d3aa3f9227b6a3de00132ded16607033a /src/wallet.js | |
| parent | 1a92d81b792f9e6d2ecb284aab979985a36d34c7 (diff) | |
| download | coinosv3-3463af1d81c2712d657bbf30ecba98ffe5873729.tar.gz coinosv3-3463af1d81c2712d657bbf30ecba98ffe5873729.zip | |
Fee-aware gift minimum; move gift entrypoint to Send page
Minimum: the flat 546-sat floor is replaced by a fee-aware minimum
(dust + one claim fee of headroom, floored at 546) via giftMinimum(),
so the recipient clears dust comfortably even if fees rise before they
claim — e.g. ~1000 sats at 5 sat/vB, ~7300 at 50. The create form shows
the live minimum and rejects below it; buildClaimTx keeps the hard
294-sat dust guard as a final backstop (claim fails rather than handing
over dust).
UI: the gift entrypoint moves from Settings to a "Gift some Bitcoin"
link on the Send page, opening the gift view as a send sub-view with a
back button.
New strings translated across all 19 locales.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Diffstat (limited to 'src/wallet.js')
| -rw-r--r-- | src/wallet.js | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/src/wallet.js b/src/wallet.js index ad890d3..39848e8 100644 --- a/src/wallet.js +++ b/src/wallet.js @@ -838,10 +838,12 @@ export class Wallet { // direct to their own fresh address. Reserves the coin. Returns { code, ... }. createGift(amountSats, feeRate) { const gift = BigInt(Math.round(amountSats)); - if (gift < 546n) throw new Error('Gift amount is too small.'); const rate = Math.max(1, Math.round(feeRate)); const claimFee = BigInt(Math.ceil((11 + 68 + 31 * 2) * rate)); // claimer's 1-in 2-out tx const DUST = 294n; + // Require dust + one claim fee of headroom so the recipient stays well above + // dust even if fees rise before they claim. + if (gift < BigInt(giftMinimum(rate))) throw new Error('Gift amount is too small.'); const need = gift + claimFee + DUST; const coin = this.utxos .filter((u) => u.confirmed && !this.isReserved(utxoId(u))) @@ -1293,6 +1295,14 @@ export function utxoId(u) { // base64url PSBT: one SIGHASH_SINGLE-signed input + the sender's change output. // previewGift reports the room available to the claimer (before their fee); // buildClaimTx adds the claimer's output and finalizes a broadcastable tx. +// Smallest sensible gift at a given fee rate: dust + one claim fee of headroom +// (floored at 546 sats), so the recipient clears dust even if fees climb. +export function giftMinimum(feeRate) { + const rate = Math.max(1, Math.round(feeRate)); + const claimFee = Math.ceil((11 + 68 + 31 * 2) * rate); + return Math.max(546, 294 + claimFee); +} + export function previewGift(code) { try { const tx = btc.Transaction.fromPSBT(base64urlnopad.decode(code)); |
