aboutsummaryrefslogtreecommitdiffstats
path: root/src/features/gifts.js
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-11-07 13:47:19 -0700
committerAdam Soltys <[email protected]>2026-11-07 13:47:19 -0700
commit48eb895cfb21c7e679344eaafebd446c4ccd949b (patch)
tree8a6fa9ae62c770097857abab2e4a19e470d38972 /src/features/gifts.js
parente905e5be5b2a0385e89de5ab3c0d95a917307314 (diff)
downloadcoinosv3-48eb895cfb21c7e679344eaafebd446c4ccd949b.tar.gz
coinosv3-48eb895cfb21c7e679344eaafebd446c4ccd949b.zip
Prepaid Lightning withdraw links: Send → ⚡ Withdraw link makes an LNURL (QR + copy) that anyone can withdraw sats from, like a voucher, with this wallet asleep. "Do we have lnurl withdraw links somewhere? can we add them?" → "Prepaid" (Adam, 2026-11-07); redeeming them already worked (38ce0b4), making them didn't. Amount per withdrawal, how many withdrawals (1–1000), an optional description; the whole amount is paid up front from Spending over Lightning to the coinos registrar (coinosv3-server 912944d, names/withdraw.js), which pays each claim out of it, so it works with any Lightning wallet while the phone is off; "Your withdraw links" lists them (what's left, used up, closed) and a link's page has Take back {what's left}, paid to a fresh Lightning receive of this wallet, which closes the link. Links belong to the wallet's nostr key (NIP-98), so every device with the seed sees them. Lives with the gift link (deferred gifts chunk, ui.giftMode === 'lnurl'). tools/lnurl-withdraw-links-test.js: makes one against the real service behind a stand-in server with a fake node, claims it through our own redeem flow, takes the rest backHEADmaster
Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01VMan6Ts5Tktega8VbLg31q
Diffstat (limited to 'src/features/gifts.js')
-rw-r--r--src/features/gifts.js8
1 files changed, 6 insertions, 2 deletions
diff --git a/src/features/gifts.js b/src/features/gifts.js
index f23ecc8..c6ccbd9 100644
--- a/src/features/gifts.js
+++ b/src/features/gifts.js
@@ -8,6 +8,7 @@ import { decryptWithCode, npubOf } from '../nostr.js';
import { installGiftWallet, previewGift, giftOutpoints, giftClaimTxs, isRetiredGift, giftMinimum, lockGift, previewLockedGift } from './gifts-wallet.js';
import { t } from '../i18n.js';
import { qrSvg } from '../qr.js';
+import { withdrawLinks } from './withdraw-links.js';
import { fmtBtc, timeAgo, shortAddr } from '../format.js';
import { getEventHash, verifyEvent } from 'nostr-tools/pure';
import { sha256 } from '@noble/hashes/sha256';
@@ -26,6 +27,7 @@ export function giftsFeature(ctx) {
// every call degrades to null in an on-chain-only build.
const hook = ctx.hook || (() => null);
const arkGiftOf = (code) => hook('arkGiftDecode', code);
+ const wl = withdrawLinks(ctx); // prepaid LNURL-withdraw links, the gift link's sibling on Send
// ================================================================ GIFT / CLAIM
// Read a gift link, returning the code (and scrubbing it from the URL so the
@@ -1085,9 +1087,11 @@ export function giftsFeature(ctx) {
return { blob, claimCode, url: `${location.origin}/lg/${blob}` };
},
receiveTakeover() { return claimCelebration(); },
- sendView() { return ui.giftMode ? giftView() : null; },
+ sendView() { return ui.giftMode === 'lnurl' ? wl.view() : ui.giftMode ? giftView() : null; },
sendFormExtras() {
- return h('button', { class: 'linklike small', style: 'align-self:center;margin-top:2px', onClick: () => { ui.giftMode = true; ui.sendError = ''; render(); } }, '🎁 ' + t('giftLink'));
+ return h('div', { class: 'row gap6 wrap', style: 'justify-content:center;column-gap:18px' },
+ h('button', { class: 'linklike small', style: 'margin-top:2px', onClick: () => { ui.giftMode = true; ui.sendError = ''; render(); } }, '🎁 ' + t('giftLink')),
+ wl.entry());
},
balanceLines() {
const locked = wallet.giftLockedValue();