aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-08-03 07:42:24 -0700
committerAdam Soltys <[email protected]>2026-08-03 07:42:24 -0700
commit161adb250e4273d0bcaa160516bc950f5f46310f (patch)
treea845b83adb75e33847f709c0d7d3e5ec3ee2ca95
parent848958e450a5b5aac95a2fcd981fd229da1d6190 (diff)
downloadcoinosv3-161adb250e4273d0bcaa160516bc950f5f46310f.tar.gz
coinosv3-161adb250e4273d0bcaa160516bc950f5f46310f.zip
Self-host the punks; skipping avatar still publishes your punk
coinos.io serves 502 for a third of the punk set (both the numbered and hash endpoints), which is why a default avatar could come up blank. The 64 webps now ship with the app (53 salvaged, 11 gaps filled with donors) and every reference is same-origin. Skipping the avatar step publishes the deterministic punk as the kind-0 picture — your face is the same on every nostr client. Success screen: checkmark now sits below the title, bigger. Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Wvj4aoeMZwA7VUGdJP9Swi
-rw-r--r--build.js3
-rw-r--r--src/app.js13
-rw-r--r--src/recipient-search.js4
-rw-r--r--src/style.css1
-rw-r--r--static/punks/1.webpbin0 -> 10266 bytes
-rw-r--r--static/punks/10.webpbin0 -> 4402 bytes
-rw-r--r--static/punks/11.webpbin0 -> 5176 bytes
-rw-r--r--static/punks/12.webpbin0 -> 4510 bytes
-rw-r--r--static/punks/13.webpbin0 -> 10516 bytes
-rw-r--r--static/punks/14.webpbin0 -> 4402 bytes
-rw-r--r--static/punks/15.webpbin0 -> 16518 bytes
-rw-r--r--static/punks/16.webpbin0 -> 4660 bytes
-rw-r--r--static/punks/17.webpbin0 -> 4146 bytes
-rw-r--r--static/punks/18.webpbin0 -> 14300 bytes
-rw-r--r--static/punks/19.webpbin0 -> 14734 bytes
-rw-r--r--static/punks/2.webpbin0 -> 2772 bytes
-rw-r--r--static/punks/20.webpbin0 -> 10502 bytes
-rw-r--r--static/punks/21.webpbin0 -> 41998 bytes
-rw-r--r--static/punks/22.webpbin0 -> 32682 bytes
-rw-r--r--static/punks/23.webpbin0 -> 41998 bytes
-rw-r--r--static/punks/24.webpbin0 -> 5026 bytes
-rw-r--r--static/punks/25.webpbin0 -> 22006 bytes
-rw-r--r--static/punks/26.webpbin0 -> 29244 bytes
-rw-r--r--static/punks/27.webpbin0 -> 23902 bytes
-rw-r--r--static/punks/28.webpbin0 -> 24820 bytes
-rw-r--r--static/punks/29.webpbin0 -> 8610 bytes
-rw-r--r--static/punks/3.webpbin0 -> 5026 bytes
-rw-r--r--static/punks/30.webpbin0 -> 36542 bytes
-rw-r--r--static/punks/31.webpbin0 -> 11690 bytes
-rw-r--r--static/punks/32.webpbin0 -> 41802 bytes
-rw-r--r--static/punks/33.webpbin0 -> 23902 bytes
-rw-r--r--static/punks/34.webpbin0 -> 7082 bytes
-rw-r--r--static/punks/35.webpbin0 -> 34532 bytes
-rw-r--r--static/punks/36.webpbin0 -> 25374 bytes
-rw-r--r--static/punks/37.webpbin0 -> 45616 bytes
-rw-r--r--static/punks/38.webpbin0 -> 6640 bytes
-rw-r--r--static/punks/39.webpbin0 -> 9580 bytes
-rw-r--r--static/punks/4.webpbin0 -> 4750 bytes
-rw-r--r--static/punks/40.webpbin0 -> 41802 bytes
-rw-r--r--static/punks/41.webpbin0 -> 32932 bytes
-rw-r--r--static/punks/42.webpbin0 -> 10818 bytes
-rw-r--r--static/punks/43.webpbin0 -> 9540 bytes
-rw-r--r--static/punks/44.webpbin0 -> 49350 bytes
-rw-r--r--static/punks/45.webpbin0 -> 25374 bytes
-rw-r--r--static/punks/46.webpbin0 -> 29892 bytes
-rw-r--r--static/punks/47.webpbin0 -> 49350 bytes
-rw-r--r--static/punks/48.webpbin0 -> 38754 bytes
-rw-r--r--static/punks/49.webpbin0 -> 28348 bytes
-rw-r--r--static/punks/5.webpbin0 -> 10790 bytes
-rw-r--r--static/punks/50.webpbin0 -> 23000 bytes
-rw-r--r--static/punks/51.webpbin0 -> 33426 bytes
-rw-r--r--static/punks/52.webpbin0 -> 29244 bytes
-rw-r--r--static/punks/53.webpbin0 -> 31586 bytes
-rw-r--r--static/punks/54.webpbin0 -> 4510 bytes
-rw-r--r--static/punks/55.webpbin0 -> 9324 bytes
-rw-r--r--static/punks/56.webpbin0 -> 28976 bytes
-rw-r--r--static/punks/57.webpbin0 -> 31206 bytes
-rw-r--r--static/punks/58.webpbin0 -> 33482 bytes
-rw-r--r--static/punks/59.webpbin0 -> 33412 bytes
-rw-r--r--static/punks/6.webpbin0 -> 4856 bytes
-rw-r--r--static/punks/60.webpbin0 -> 7268 bytes
-rw-r--r--static/punks/61.webpbin0 -> 28348 bytes
-rw-r--r--static/punks/62.webpbin0 -> 28012 bytes
-rw-r--r--static/punks/63.webpbin0 -> 26854 bytes
-rw-r--r--static/punks/64.webpbin0 -> 36532 bytes
-rw-r--r--static/punks/7.webpbin0 -> 4856 bytes
-rw-r--r--static/punks/8.webpbin0 -> 7484 bytes
-rw-r--r--static/punks/9.webpbin0 -> 7018 bytes
68 files changed, 15 insertions, 6 deletions
diff --git a/build.js b/build.js
index 5efd3eb..3e42930 100644
--- a/build.js
+++ b/build.js
@@ -263,6 +263,9 @@ if (import.meta.main) {
.replace('{{NWC_WAKE_FALLBACK}}', nwcSw ? '' : SW_WAKE_ONLY);
await Bun.write('dist/sw.js', nwcSw ? swBody + '\n' + await buildSwNwc() : swBody);
for (const f of STATIC) await Bun.write('dist/' + f, Bun.file('static/' + f));
+ // default avatars, self-hosted since coinos.io's copies are half-broken
+ const { readdirSync } = await import('node:fs');
+ for (const f of readdirSync('static/punks')) await Bun.write('dist/punks/' + f, Bun.file('static/punks/' + f));
const kb = (Buffer.byteLength(html) / 1024).toFixed(0);
console.log(`✓ dist/index.html written (${kb} KB) — open it offline, no server needed`);
diff --git a/src/app.js b/src/app.js
index 562ca99..36fb0d2 100644
--- a/src/app.js
+++ b/src/app.js
@@ -6,7 +6,7 @@
import { Wallet, newMnemonic, isValidMnemonic, accountXpubFor, cacheKeyFor, utxoId, parseExtendedKey, xpubToZpub, encryptVault, decryptVault } from './wallet.js';
import { qrSvg } from './qr.js';
-import { makeSearcher, resultRows, searchable } from './recipient-search.js';
+import { makeSearcher, resultRows, searchable, punkUrl } from './recipient-search.js';
import { npubOf } from './nostr.js';
import { scanQr } from './scan.js';
import { dataSources, getSource, setSource, getNetwork, setNetwork, NETWORKS } from './api.js';
@@ -2007,7 +2007,7 @@ function shouldOnboard() {
}
const PUNK_PICKS = [7, 14, 21, 3, 33, 40, 47, 36, 61, 26, 12, 50];
-const punkImg = (n) => `https://coinos.io/api/public/punks/${n}.webp`;
+const punkImg = (n) => `punks/${n}.webp`;
async function onbUpload(file) {
const fd = new FormData();
@@ -2110,7 +2110,10 @@ function onboardScreen() {
ui.onbBusy = true; ui.onbError = ''; render();
try {
const addr = featureHook('namesAddress');
- const fields = { name: addr ? addr.split('@')[0] : undefined, picture: o.avatar || undefined };
+ // keeping the default still publishes it — their punk should be
+ // their face on every nostr client, not just here
+ const picture = o.avatar || (me ? 'https://v3.coinos.io/' + punkUrl(me) : undefined);
+ const fields = { name: addr ? addr.split('@')[0] : undefined, picture };
if (fields.name || fields.picture) await featureHook('publishProfile', fields);
o.step = 'success';
} catch (e) { ui.onbError = e.message; }
@@ -2121,8 +2124,8 @@ function onboardScreen() {
// success
return page([
h('div', { class: 'onb-confetti' }, ...Array.from({ length: 18 }, () => h('i'))),
- h('div', { class: 'check-badge', style: 'align-self:center' }, '✓'),
- title(t('onbDoneTitle')),
+ h('h2', { class: 'onb-title', style: 'text-align:center' }, t('onbDoneTitle')),
+ h('div', { class: 'check-badge onb-check' }, '✓'),
h('p', { class: 'muted', style: 'margin:0;text-align:center' }, t('onbDoneBody')),
h('button', { class: 'btn-primary btn-block', style: 'padding:14px', onClick: () => {
try { localStorage.setItem(ONBOARDED_KEY, '1'); } catch {}
diff --git a/src/recipient-search.js b/src/recipient-search.js
index 2594488..553673e 100644
--- a/src/recipient-search.js
+++ b/src/recipient-search.js
@@ -13,8 +13,10 @@ import { queryOn, parseNostrPubkey, npubOf, PROFILE_RELAYS } from './nostr.js';
// coinos punks: the deterministic default avatar — same formula the coinos
// app uses (last byte of the pubkey picks one of 64). Initials show through
// if the image can't load (offline).
+// Self-hosted (dist/punks) — coinos.io's own copies 502 for a third of the
+// set. Same deterministic formula the coinos app uses.
export const punkUrl = (pk) =>
- `https://coinos.io/api/public/punks/${Math.floor((parseInt(pk.slice(-2), 16) / 256) * 64) + 1}.webp`;
+ `punks/${Math.floor((parseInt(pk.slice(-2), 16) / 256) * 64) + 1}.webp`;
export const fallbackAvatar = (h, pk, name, cls) =>
h('div', { class: cls + ' fallback' },
diff --git a/src/style.css b/src/style.css
index 3dbeaaa..562db92 100644
--- a/src/style.css
+++ b/src/style.css
@@ -506,3 +506,4 @@ body::after {
.tour-overlay { background: transparent; }
.tour-card { position: fixed; left: 50%; transform: translateX(-50%); width: min(90vw, 360px); background: var(--paper); color: var(--ink); border: 1px solid var(--line-strong); border-radius: 14px; padding: 14px 16px; box-shadow: var(--shadow); z-index: 81; }
@media (prefers-reduced-motion: reduce) { .onb-confetti i { animation: none; display: none; } }
+.onb-check { width: 96px; height: 96px; font-size: 52px; align-self: center; margin: 6px 0; }
diff --git a/static/punks/1.webp b/static/punks/1.webp
new file mode 100644
index 0000000..b586aec
--- /dev/null
+++ b/static/punks/1.webp
Binary files differ
diff --git a/static/punks/10.webp b/static/punks/10.webp
new file mode 100644
index 0000000..8b101f6
--- /dev/null
+++ b/static/punks/10.webp
Binary files differ
diff --git a/static/punks/11.webp b/static/punks/11.webp
new file mode 100644
index 0000000..7249ac5
--- /dev/null
+++ b/static/punks/11.webp
Binary files differ
diff --git a/static/punks/12.webp b/static/punks/12.webp
new file mode 100644
index 0000000..f8fb7b0
--- /dev/null
+++ b/static/punks/12.webp
Binary files differ
diff --git a/static/punks/13.webp b/static/punks/13.webp
new file mode 100644
index 0000000..b412231
--- /dev/null
+++ b/static/punks/13.webp
Binary files differ
diff --git a/static/punks/14.webp b/static/punks/14.webp
new file mode 100644
index 0000000..8b101f6
--- /dev/null
+++ b/static/punks/14.webp
Binary files differ
diff --git a/static/punks/15.webp b/static/punks/15.webp
new file mode 100644
index 0000000..3c119f8
--- /dev/null
+++ b/static/punks/15.webp
Binary files differ
diff --git a/static/punks/16.webp b/static/punks/16.webp
new file mode 100644
index 0000000..c72b298
--- /dev/null
+++ b/static/punks/16.webp
Binary files differ
diff --git a/static/punks/17.webp b/static/punks/17.webp
new file mode 100644
index 0000000..a32f6c5
--- /dev/null
+++ b/static/punks/17.webp
Binary files differ
diff --git a/static/punks/18.webp b/static/punks/18.webp
new file mode 100644
index 0000000..c70276d
--- /dev/null
+++ b/static/punks/18.webp
Binary files differ
diff --git a/static/punks/19.webp b/static/punks/19.webp
new file mode 100644
index 0000000..50b7069
--- /dev/null
+++ b/static/punks/19.webp
Binary files differ
diff --git a/static/punks/2.webp b/static/punks/2.webp
new file mode 100644
index 0000000..a93e06a
--- /dev/null
+++ b/static/punks/2.webp
Binary files differ
diff --git a/static/punks/20.webp b/static/punks/20.webp
new file mode 100644
index 0000000..f23875c
--- /dev/null
+++ b/static/punks/20.webp
Binary files differ
diff --git a/static/punks/21.webp b/static/punks/21.webp
new file mode 100644
index 0000000..7b7fe31
--- /dev/null
+++ b/static/punks/21.webp
Binary files differ
diff --git a/static/punks/22.webp b/static/punks/22.webp
new file mode 100644
index 0000000..301e56b
--- /dev/null
+++ b/static/punks/22.webp
Binary files differ
diff --git a/static/punks/23.webp b/static/punks/23.webp
new file mode 100644
index 0000000..7b7fe31
--- /dev/null
+++ b/static/punks/23.webp
Binary files differ
diff --git a/static/punks/24.webp b/static/punks/24.webp
new file mode 100644
index 0000000..f0e5676
--- /dev/null
+++ b/static/punks/24.webp
Binary files differ
diff --git a/static/punks/25.webp b/static/punks/25.webp
new file mode 100644
index 0000000..4d55807
--- /dev/null
+++ b/static/punks/25.webp
Binary files differ
diff --git a/static/punks/26.webp b/static/punks/26.webp
new file mode 100644
index 0000000..64cdb8e
--- /dev/null
+++ b/static/punks/26.webp
Binary files differ
diff --git a/static/punks/27.webp b/static/punks/27.webp
new file mode 100644
index 0000000..0e220fc
--- /dev/null
+++ b/static/punks/27.webp
Binary files differ
diff --git a/static/punks/28.webp b/static/punks/28.webp
new file mode 100644
index 0000000..b62214d
--- /dev/null
+++ b/static/punks/28.webp
Binary files differ
diff --git a/static/punks/29.webp b/static/punks/29.webp
new file mode 100644
index 0000000..8ca659e
--- /dev/null
+++ b/static/punks/29.webp
Binary files differ
diff --git a/static/punks/3.webp b/static/punks/3.webp
new file mode 100644
index 0000000..f0e5676
--- /dev/null
+++ b/static/punks/3.webp
Binary files differ
diff --git a/static/punks/30.webp b/static/punks/30.webp
new file mode 100644
index 0000000..eee45eb
--- /dev/null
+++ b/static/punks/30.webp
Binary files differ
diff --git a/static/punks/31.webp b/static/punks/31.webp
new file mode 100644
index 0000000..85a6fb8
--- /dev/null
+++ b/static/punks/31.webp
Binary files differ
diff --git a/static/punks/32.webp b/static/punks/32.webp
new file mode 100644
index 0000000..c46a356
--- /dev/null
+++ b/static/punks/32.webp
Binary files differ
diff --git a/static/punks/33.webp b/static/punks/33.webp
new file mode 100644
index 0000000..0e220fc
--- /dev/null
+++ b/static/punks/33.webp
Binary files differ
diff --git a/static/punks/34.webp b/static/punks/34.webp
new file mode 100644
index 0000000..7c2d01c
--- /dev/null
+++ b/static/punks/34.webp
Binary files differ
diff --git a/static/punks/35.webp b/static/punks/35.webp
new file mode 100644
index 0000000..2a41a38
--- /dev/null
+++ b/static/punks/35.webp
Binary files differ
diff --git a/static/punks/36.webp b/static/punks/36.webp
new file mode 100644
index 0000000..07ad175
--- /dev/null
+++ b/static/punks/36.webp
Binary files differ
diff --git a/static/punks/37.webp b/static/punks/37.webp
new file mode 100644
index 0000000..1e46523
--- /dev/null
+++ b/static/punks/37.webp
Binary files differ
diff --git a/static/punks/38.webp b/static/punks/38.webp
new file mode 100644
index 0000000..bef34c5
--- /dev/null
+++ b/static/punks/38.webp
Binary files differ
diff --git a/static/punks/39.webp b/static/punks/39.webp
new file mode 100644
index 0000000..3df28f2
--- /dev/null
+++ b/static/punks/39.webp
Binary files differ
diff --git a/static/punks/4.webp b/static/punks/4.webp
new file mode 100644
index 0000000..f046e8a
--- /dev/null
+++ b/static/punks/4.webp
Binary files differ
diff --git a/static/punks/40.webp b/static/punks/40.webp
new file mode 100644
index 0000000..c46a356
--- /dev/null
+++ b/static/punks/40.webp
Binary files differ
diff --git a/static/punks/41.webp b/static/punks/41.webp
new file mode 100644
index 0000000..7d74371
--- /dev/null
+++ b/static/punks/41.webp
Binary files differ
diff --git a/static/punks/42.webp b/static/punks/42.webp
new file mode 100644
index 0000000..1810d56
--- /dev/null
+++ b/static/punks/42.webp
Binary files differ
diff --git a/static/punks/43.webp b/static/punks/43.webp
new file mode 100644
index 0000000..cf4e8af
--- /dev/null
+++ b/static/punks/43.webp
Binary files differ
diff --git a/static/punks/44.webp b/static/punks/44.webp
new file mode 100644
index 0000000..9639058
--- /dev/null
+++ b/static/punks/44.webp
Binary files differ
diff --git a/static/punks/45.webp b/static/punks/45.webp
new file mode 100644
index 0000000..07ad175
--- /dev/null
+++ b/static/punks/45.webp
Binary files differ
diff --git a/static/punks/46.webp b/static/punks/46.webp
new file mode 100644
index 0000000..6de78aa
--- /dev/null
+++ b/static/punks/46.webp
Binary files differ
diff --git a/static/punks/47.webp b/static/punks/47.webp
new file mode 100644
index 0000000..9639058
--- /dev/null
+++ b/static/punks/47.webp
Binary files differ
diff --git a/static/punks/48.webp b/static/punks/48.webp
new file mode 100644
index 0000000..0736172
--- /dev/null
+++ b/static/punks/48.webp
Binary files differ
diff --git a/static/punks/49.webp b/static/punks/49.webp
new file mode 100644
index 0000000..3868f79
--- /dev/null
+++ b/static/punks/49.webp
Binary files differ
diff --git a/static/punks/5.webp b/static/punks/5.webp
new file mode 100644
index 0000000..4e2ebd4
--- /dev/null
+++ b/static/punks/5.webp
Binary files differ
diff --git a/static/punks/50.webp b/static/punks/50.webp
new file mode 100644
index 0000000..4569117
--- /dev/null
+++ b/static/punks/50.webp
Binary files differ
diff --git a/static/punks/51.webp b/static/punks/51.webp
new file mode 100644
index 0000000..343e4fa
--- /dev/null
+++ b/static/punks/51.webp
Binary files differ
diff --git a/static/punks/52.webp b/static/punks/52.webp
new file mode 100644
index 0000000..64cdb8e
--- /dev/null
+++ b/static/punks/52.webp
Binary files differ
diff --git a/static/punks/53.webp b/static/punks/53.webp
new file mode 100644
index 0000000..185e7ac
--- /dev/null
+++ b/static/punks/53.webp
Binary files differ
diff --git a/static/punks/54.webp b/static/punks/54.webp
new file mode 100644
index 0000000..f8fb7b0
--- /dev/null
+++ b/static/punks/54.webp
Binary files differ
diff --git a/static/punks/55.webp b/static/punks/55.webp
new file mode 100644
index 0000000..18ae419
--- /dev/null
+++ b/static/punks/55.webp
Binary files differ
diff --git a/static/punks/56.webp b/static/punks/56.webp
new file mode 100644
index 0000000..e8a0123
--- /dev/null
+++ b/static/punks/56.webp
Binary files differ
diff --git a/static/punks/57.webp b/static/punks/57.webp
new file mode 100644
index 0000000..f1d0125
--- /dev/null
+++ b/static/punks/57.webp
Binary files differ
diff --git a/static/punks/58.webp b/static/punks/58.webp
new file mode 100644
index 0000000..06c8ac2
--- /dev/null
+++ b/static/punks/58.webp
Binary files differ
diff --git a/static/punks/59.webp b/static/punks/59.webp
new file mode 100644
index 0000000..740aafc
--- /dev/null
+++ b/static/punks/59.webp
Binary files differ
diff --git a/static/punks/6.webp b/static/punks/6.webp
new file mode 100644
index 0000000..d04db94
--- /dev/null
+++ b/static/punks/6.webp
Binary files differ
diff --git a/static/punks/60.webp b/static/punks/60.webp
new file mode 100644
index 0000000..41491c6
--- /dev/null
+++ b/static/punks/60.webp
Binary files differ
diff --git a/static/punks/61.webp b/static/punks/61.webp
new file mode 100644
index 0000000..3868f79
--- /dev/null
+++ b/static/punks/61.webp
Binary files differ
diff --git a/static/punks/62.webp b/static/punks/62.webp
new file mode 100644
index 0000000..666eda2
--- /dev/null
+++ b/static/punks/62.webp
Binary files differ
diff --git a/static/punks/63.webp b/static/punks/63.webp
new file mode 100644
index 0000000..ca9c610
--- /dev/null
+++ b/static/punks/63.webp
Binary files differ
diff --git a/static/punks/64.webp b/static/punks/64.webp
new file mode 100644
index 0000000..394cf3f
--- /dev/null
+++ b/static/punks/64.webp
Binary files differ
diff --git a/static/punks/7.webp b/static/punks/7.webp
new file mode 100644
index 0000000..d04db94
--- /dev/null
+++ b/static/punks/7.webp
Binary files differ
diff --git a/static/punks/8.webp b/static/punks/8.webp
new file mode 100644
index 0000000..060669f
--- /dev/null
+++ b/static/punks/8.webp
Binary files differ
diff --git a/static/punks/9.webp b/static/punks/9.webp
new file mode 100644
index 0000000..7641699
--- /dev/null
+++ b/static/punks/9.webp
Binary files differ