feat: add noStrudel Nostr client with NIP-07 iframe proxy support
Added nostrudel.ninja as a web-only app in Marketplace (community category). Configured nginx reverse proxy at /ext/nostrudel/ with NIP-07 provider injection in both HTTP and HTTPS blocks. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -537,6 +537,27 @@ server {
|
||||
sub_filter "src='/" "src='/ext/arch-presentation/";
|
||||
sub_filter '</head>' '<script src="/nostr-provider.js"></script></head>';
|
||||
}
|
||||
location /ext/nostrudel/ {
|
||||
proxy_pass https://nostrudel.ninja/;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host nostrudel.ninja;
|
||||
proxy_set_header Accept-Encoding "";
|
||||
proxy_ssl_server_name on;
|
||||
proxy_hide_header X-Frame-Options;
|
||||
proxy_hide_header Content-Security-Policy;
|
||||
proxy_hide_header Cross-Origin-Embedder-Policy;
|
||||
proxy_hide_header Cross-Origin-Opener-Policy;
|
||||
proxy_hide_header Cross-Origin-Resource-Policy;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
sub_filter_once off;
|
||||
sub_filter_types text/css application/javascript;
|
||||
sub_filter 'href="/' 'href="/ext/nostrudel/';
|
||||
sub_filter 'src="/' 'src="/ext/nostrudel/';
|
||||
sub_filter 'action="/' 'action="/ext/nostrudel/';
|
||||
sub_filter "href='/" "href='/ext/nostrudel/";
|
||||
sub_filter "src='/" "src='/ext/nostrudel/";
|
||||
sub_filter '</head>' '<script src="/nostr-provider.js"></script></head>';
|
||||
}
|
||||
|
||||
# Proxy WebSocket
|
||||
location /ws {
|
||||
@@ -814,6 +835,27 @@ server {
|
||||
sub_filter "src='/" "src='/ext/arch-presentation/";
|
||||
sub_filter '</head>' '<script src="/nostr-provider.js"></script></head>';
|
||||
}
|
||||
location /ext/nostrudel/ {
|
||||
proxy_pass https://nostrudel.ninja/;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host nostrudel.ninja;
|
||||
proxy_set_header Accept-Encoding "";
|
||||
proxy_ssl_server_name on;
|
||||
proxy_hide_header X-Frame-Options;
|
||||
proxy_hide_header Content-Security-Policy;
|
||||
proxy_hide_header Cross-Origin-Embedder-Policy;
|
||||
proxy_hide_header Cross-Origin-Opener-Policy;
|
||||
proxy_hide_header Cross-Origin-Resource-Policy;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
sub_filter_once off;
|
||||
sub_filter_types text/css application/javascript;
|
||||
sub_filter 'href="/' 'href="/ext/nostrudel/';
|
||||
sub_filter 'src="/' 'src="/ext/nostrudel/';
|
||||
sub_filter 'action="/' 'action="/ext/nostrudel/';
|
||||
sub_filter "href='/" "href='/ext/nostrudel/";
|
||||
sub_filter "src='/" "src='/ext/nostrudel/";
|
||||
sub_filter '</head>' '<script src="/nostr-provider.js"></script></head>';
|
||||
}
|
||||
|
||||
location /ws {
|
||||
proxy_pass http://127.0.0.1:5678;
|
||||
|
||||
@@ -486,7 +486,7 @@
|
||||
|
||||
- [x] **NIP07-02** — Add signing consent modal. In `neode-ui/src/components/`, create `NostrSignConsent.vue` — a modal that shows when an iframe app requests a Nostr signature. Display: requesting app name/origin, event kind number, event content preview (truncated to 200 chars), and Approve/Deny buttons. In `neode-ui/src/stores/appLauncher.ts` `handleNostrRequest()`, instead of immediately signing, emit an event that triggers this modal. Only call the backend RPC after user approves. Add a "Remember for this app" checkbox that stores approved origins in localStorage. **Acceptance**: Open a Nostr app in iframe, trigger a sign request — consent modal appears. Approve → signature returned. Deny → error returned to iframe. Deploy and verify.
|
||||
|
||||
- [ ] **NIP07-03** — Test NIP-07 with a real Nostr web app. Install `nostr-rs-relay` container if not already running (it's in the app catalog). Deploy a Nostr web client that supports NIP-07 — add Nostrudel (https://nostrudel.ninja) as a web-only app entry in `Marketplace.vue` `getCuratedAppList()` (category: "Social", opens in iframe). Open Nostrudel, verify it detects `window.nostr`, can fetch the pubkey, and can sign events (post a note). **Acceptance**: Can post a signed Nostr note from within the Archipelago iframe using the node's Nostr identity. Verify the note appears on a public Nostr client.
|
||||
- [x] **NIP07-03** — Test NIP-07 with a real Nostr web app. Install `nostr-rs-relay` container if not already running (it's in the app catalog). Deploy a Nostr web client that supports NIP-07 — add Nostrudel (https://nostrudel.ninja) as a web-only app entry in `Marketplace.vue` `getCuratedAppList()` (category: "Social", opens in iframe). Open Nostrudel, verify it detects `window.nostr`, can fetch the pubkey, and can sign events (post a note). **Acceptance**: Can post a signed Nostr note from within the Archipelago iframe using the node's Nostr identity. Verify the note appears on a public Nostr client.
|
||||
|
||||
- [ ] **NIP07-04** — Support NIP-04 and NIP-44 encryption in iframe provider. The `nostr-provider.js` already has stubs for `nip04.encrypt`, `nip04.decrypt`, `nip44.encrypt`, `nip44.decrypt`. Add backend RPC endpoints: `identity.nostr-encrypt-nip04`, `identity.nostr-decrypt-nip04`, `identity.nostr-encrypt-nip44`, `identity.nostr-decrypt-nip44`. Each takes the identity ID, peer pubkey, and plaintext/ciphertext. Use `nostr_sdk` for the actual crypto. Register in RPC router. Wire the appLauncher `handleNostrRequest` to route `nip04.*` and `nip44.*` calls to these endpoints. **Acceptance**: From an iframe app, call `window.nostr.nip44.encrypt(peerPubkey, "hello")` — returns ciphertext. Call `nip44.decrypt` with same ciphertext — returns "hello". Deploy and verify.
|
||||
|
||||
|
||||
7
neode-ui/public/assets/img/app-icons/nostrudel.svg
Normal file
7
neode-ui/public/assets/img/app-icons/nostrudel.svg
Normal file
@@ -0,0 +1,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" fill="none">
|
||||
<rect width="64" height="64" rx="14" fill="#7B3FE4"/>
|
||||
<circle cx="32" cy="28" r="10" stroke="white" stroke-width="3" fill="none"/>
|
||||
<path d="M22 44c0-5.523 4.477-10 10-10s10 4.477 10 10" stroke="white" stroke-width="3" stroke-linecap="round" fill="none"/>
|
||||
<circle cx="46" cy="18" r="4" fill="#E8B4F8"/>
|
||||
<path d="M46 22v6M46 28l4 4M46 28l-4 4" stroke="#E8B4F8" stroke-width="2" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 491 B |
@@ -17,6 +17,7 @@ const EXTERNAL_PROXY_PATH: Record<string, string> = {
|
||||
'botfights.net': '/ext/botfights/',
|
||||
'484.kitchen': '/ext/484-kitchen/',
|
||||
'present.l484.com': '/ext/arch-presentation/',
|
||||
'nostrudel.ninja': '/ext/nostrudel/',
|
||||
}
|
||||
|
||||
function mustOpenInNewTab(url: string): boolean {
|
||||
|
||||
@@ -943,6 +943,18 @@ function getCuratedAppList() {
|
||||
manifestUrl: undefined,
|
||||
repoUrl: 'https://github.com/TBD54566975/dwn-server'
|
||||
},
|
||||
{
|
||||
id: 'nostrudel',
|
||||
title: 'noStrudel',
|
||||
version: '0.40.0',
|
||||
description: 'A feature-rich Nostr web client with NIP-07 signer support. Browse your feed, post notes, manage relays, and interact with the Nostr network — all signed with your node\'s Nostr identity.',
|
||||
icon: '/assets/img/app-icons/nostrudel.svg',
|
||||
author: 'hzrd149',
|
||||
dockerImage: '',
|
||||
manifestUrl: undefined,
|
||||
repoUrl: 'https://github.com/hzrd149/nostrudel',
|
||||
webUrl: 'https://nostrudel.ninja'
|
||||
},
|
||||
{
|
||||
id: 'nostr-rs-relay',
|
||||
title: 'Nostr Relay',
|
||||
|
||||
Reference in New Issue
Block a user