aboutsummaryrefslogtreecommitdiffstats
path: root/src/features/zaps.js
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-10-19 22:13:54 -0700
committerAdam Soltys <[email protected]>2026-10-19 22:13:54 -0700
commita0829612b8751e85f28d066fbaa0c2308a85fbda (patch)
treee9d81ffe0d37023cefbecd1bdf35cf0bf39a5e83 /src/features/zaps.js
parent1a85347b0a37886e550497eab5ece05410fce923 (diff)
downloadcoinosv3-a0829612b8751e85f28d066fbaa0c2308a85fbda.tar.gz
coinosv3-a0829612b8751e85f28d066fbaa0c2308a85fbda.zip
Zaps are signed as the person zapping: the login identity (extension, bunker, passkey, Google) when there is one, else the wallet's key. They were always signed by the wallet's own key, so a signed-in person's zaps showed in stream chats and streamers' overlays under a stranger npub. Zap requests also carry created_at now (a real signer refused them without it).
Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_013ZDf1cyCQLkfjftYhymZAg
Diffstat (limited to 'src/features/zaps.js')
-rw-r--r--src/features/zaps.js20
1 files changed, 16 insertions, 4 deletions
diff --git a/src/features/zaps.js b/src/features/zaps.js
index b501c76..76296cf 100644
--- a/src/features/zaps.js
+++ b/src/features/zaps.js
@@ -196,6 +196,16 @@ export function zapsFeature(ctx) {
render();
}
+ // A zap request is signed as the person zapping: the login identity when
+ // there is one (the face their chat line and the streamer's overlay
+ // show), else the wallet's own key. It used to be the wallet key always,
+ // and a signed-in person's zaps showed under a stranger's npub.
+ async function zapSigner() {
+ const id = hook('nostrLoginIdentity');
+ const signer = id && (id.signer || await Promise.resolve(hook('nostrLoginResume')).catch(() => null));
+ return signer ? (e) => signer.signEvent(e) : (e) => wallet.nostrSign(e);
+ }
+
// One-tap zap at the user's default amount: resolve, invoice, pay through
// the ark seam (its quote + retries included), and report by toast — the
// whole flow without a single screen.
@@ -214,10 +224,11 @@ export function zapsFeature(ctx) {
}
let zapRequest = null;
if (p.allowsNostr && t2.pk && wallet.nostrSign) {
- zapRequest = buildZapRequest({
+ const sign = await zapSigner();
+ zapRequest = await buildZapRequest({
amountMsat: msat, relays: wallet.nostrRelays(), lnurlBech32: t2.lnurlBech32,
recipientPk: t2.pk, eventId: t2.eventId || null, moment: t2.moment, comment: '',
- signFn: (partial) => wallet.nostrSign(partial),
+ signFn: sign,
});
}
const invoice = await requestInvoice(p, { amountMsat: msat, zapRequest, lnurlBech32: t2.lnurlBech32 });
@@ -272,10 +283,11 @@ export function zapsFeature(ctx) {
let zapRequest = null;
const canZap = p.allowsNostr && z.target.pk && wallet.nostrSign;
if (canZap) {
- zapRequest = buildZapRequest({
+ const sign = await zapSigner();
+ zapRequest = await buildZapRequest({
amountMsat: msat, relays: wallet.nostrRelays(), lnurlBech32: z.target.lnurlBech32,
recipientPk: z.target.pk, eventId: z.target.eventId || null, moment: z.target.moment, comment: z.comment,
- signFn: (partial) => wallet.nostrSign(partial),
+ signFn: sign,
});
}
const invoice = await requestInvoice(p, { amountMsat: msat, zapRequest, lnurlBech32: z.target.lnurlBech32, comment: z.comment });