diff options
| author | Adam Soltys <[email protected]> | 2026-10-02 23:20:42 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-10-02 23:20:42 -0700 |
| commit | d4d5a8b65dde249bc6eb27b7c120b7f5c9b238fe (patch) | |
| tree | 127276077dc776827ee73c90bf8166dc27cc03be /src/features | |
| parent | 9e12335231f3fa4c4222bea71c4a1737a15a4994 (diff) | |
| download | coinosv3-d4d5a8b65dde249bc6eb27b7c120b7f5c9b238fe.tar.gz coinosv3-d4d5a8b65dde249bc6eb27b7c120b7f5c9b238fe.zip | |
Zaps find lightning addresses our relays have pruned
Zapping a post looked the author's lightning address up on our four home
relays only. Those prune old events, so anyone whose kind 0 hadn't changed
in a while (1776, Brad Mills) came back as "no Lightning address or Ark
address" — while their profile page, which also asks the index relays and
the author's own relays, showed the address right there. The zap lookup
now asks both ways at once and takes whichever carries a lightning address.
And when someone does have one but Lightning can't be paid right now, the
toast says that instead of claiming they have no address.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VKv2uEFRR42Gp6NyqcN3A9
Diffstat (limited to 'src/features')
| -rw-r--r-- | src/features/ark.js | 3 | ||||
| -rw-r--r-- | src/features/messages.js | 15 | ||||
| -rw-r--r-- | src/features/sync.js | 10 |
3 files changed, 26 insertions, 2 deletions
diff --git a/src/features/ark.js b/src/features/ark.js index 16786ec..fb6d2a3 100644 --- a/src/features/ark.js +++ b/src/features/ark.js @@ -1724,7 +1724,8 @@ export function arkFeature(ctx) { // A post's author with no Lightning or Ark address can't be zapped: // a gift DM is for paying a person on purpose (Pay, the send form), // not something a tap on a post should send. - if (z.eventId) { bail(t('arkZapNoPostZap')); render(); return; } + // They do have a lightning address — it's paying it that isn't possible right now. + if (z.eventId) { bail(t(z.lnOk ? 'arkZapLnDown' : 'arkZapNoPostZap')); render(); return; } // 4. last resort: an ark gift locked to their nostr key, DMed to them. // To the payer it's just a zap. if (z.autoSat && zapGiftOk(z.autoSat)) { diff --git a/src/features/messages.js b/src/features/messages.js index 1c0dab8..b0f4526 100644 --- a/src/features/messages.js +++ b/src/features/messages.js @@ -3430,6 +3430,21 @@ export function messagesFeature(ctx) { return pending; } + // A person's profile the way their profile page finds it: index relays and + // their own relays, not just ours. The zap path asks here — a lightning + // address on a kind 0 that our relays have long since pruned is still + // somebody's lightning address. + wallet.deepProfile = async (pk) => { + await fetchFullProfile(pk); + const m = fullProfiles.get(pk); + if (!m || typeof m !== 'object') return null; + const str = (v) => (typeof v === 'string' && v.trim() ? v.trim() : null); + return { + name: str(m.display_name) || str(m.name), picture: str(m.picture), about: str(m.about), nip05: str(m.nip05), + lud16: str(m.lud16), lud06: str(m.lud06), + }; + }; + // Warm a profile PAGE (full kind-0 + latest notes + relay list) before // anyone taps it, so the page opens complete instead of behind spinners. // Queued with a small concurrency cap: likely tap-targets only, never a diff --git a/src/features/sync.js b/src/features/sync.js index ed22322..44f5809 100644 --- a/src/features/sync.js +++ b/src/features/sync.js @@ -163,7 +163,15 @@ export function installSyncWallet(wallet, { outbox = syncOutbox() } = {}) { // broad profile relays — independent of whether cross-device sync is on. async nostrProfile(pkHex) { if (this.offline) return null; - return fetchNostrProfile(pkHex); + // Our relays prune: an old kind 0 (and the lightning address on it) + // may only survive on index relays or the person's own. Ask both ways + // at once; a lightning address from either wins. + const [near, deep] = await Promise.all([ + fetchNostrProfile(pkHex).catch(() => null), + this.deepProfile ? this.deepProfile(pkHex).catch(() => null) : null, + ]); + const pays = (p) => p && (p.lud16 || p.lud06); + return pays(near) ? near : pays(deep) ? deep : near || deep; }, // Relays to advertise in a zap request so we can later find the receipt: |
