mirror of
https://github.com/aljazceru/nsecbunkerd.git
synced 2025-12-17 06:04:22 +01:00
improvements around nip89 announcement
This commit is contained in:
24
README.md
24
README.md
@@ -119,6 +119,18 @@ To enable this you'll need to configure a few things on your `nsecbunker.json` c
|
|||||||
"your-domain-here": {
|
"your-domain-here": {
|
||||||
"nip05": "/your-nip05-nostr.json-file", // The location where NIP-05 entries to your domain are stored
|
"nip05": "/your-nip05-nostr.json-file", // The location where NIP-05 entries to your domain are stored
|
||||||
|
|
||||||
|
"nip89": {
|
||||||
|
"profile": { // a kind:0-like profile
|
||||||
|
"name": "my cool nsecbunker instance", // The name of your nsecBunker instance
|
||||||
|
"about": "...",
|
||||||
|
},
|
||||||
|
"operator": "npub1l2vyh47mk2p0qlsku7hg0vn29faehy9hy34ygaclpn66ukqp3afqutajft", // (optional) npub of the operator of this nsecbunker
|
||||||
|
"relays": [ // list of relays where to publush the nip89 announcement
|
||||||
|
"https://relay.damus.io",
|
||||||
|
"https://pyramid.fiatjaf.com"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
// Wallet configuration (optional)
|
// Wallet configuration (optional)
|
||||||
"wallet": {
|
"wallet": {
|
||||||
"lnbits": {
|
"lnbits": {
|
||||||
@@ -142,6 +154,18 @@ For this to work you'll need to run, in addition to `nsecbunkerd`, an lnbits ins
|
|||||||
|
|
||||||
- [ ] TODO: Add NWC support
|
- [ ] TODO: Add NWC support
|
||||||
|
|
||||||
|
When booting up, the nsecbunkerd will publish a NIP-89 announcement (`kind:31990`), which is the way clients find out about your nsecbunker.
|
||||||
|
|
||||||
|
When a bunker provides a wallet and zapping service (`wallet` and `nostdressUrl` are configured), it will add tags:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"tags": [
|
||||||
|
[ "f", "wallet" ],
|
||||||
|
[ "f", "zaps" ]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
# Authors
|
# Authors
|
||||||
|
|
||||||
* [pablof7z](nostr:npub1l2vyh47mk2p0qlsku7hg0vn29faehy9hy34ygaclpn66ukqp3afqutajft)
|
* [pablof7z](nostr:npub1l2vyh47mk2p0qlsku7hg0vn29faehy9hy34ygaclpn66ukqp3afqutajft)
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
import readline from 'readline';
|
import readline from 'readline';
|
||||||
import { getCurrentConfig, saveCurrentConfig } from '../config/index.js';
|
import { DomainConfig, IConfig, getCurrentConfig, saveCurrentConfig } from '../config/index.js';
|
||||||
import { decryptNsec } from '../config/keys.js';
|
import { decryptNsec } from '../config/keys.js';
|
||||||
import { fork } from 'child_process';
|
import { fork } from 'child_process';
|
||||||
import { resolve } from 'path';
|
import { resolve } from 'path';
|
||||||
|
import NDK, { NDKAppHandlerEvent, NDKKind, NDKPrivateKeySigner, NDKUser, NostrEvent } from '@nostr-dev-kit/ndk';
|
||||||
|
import { debug } from 'console';
|
||||||
|
|
||||||
interface IOpts {
|
interface IOpts {
|
||||||
keys: string[];
|
keys: string[];
|
||||||
@@ -11,6 +13,77 @@ interface IOpts {
|
|||||||
adminNpubs: string[];
|
adminNpubs: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function nip89announcement(configData: IConfig) {
|
||||||
|
const domains = configData.domains as Record<string, DomainConfig>;
|
||||||
|
for (const [ domain, config ] of Object.entries(domains)) {
|
||||||
|
const hasNip89 = !!config.nip89;
|
||||||
|
if (!hasNip89) continue;
|
||||||
|
|
||||||
|
const profile = config.nip89!.profile;
|
||||||
|
const relays = config.nip89!.relays;
|
||||||
|
|
||||||
|
if (!profile) {
|
||||||
|
console.log(`❌ No NIP-89 profile in configuration of ${domain}!`);
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!relays || relays.length === 0) {
|
||||||
|
console.log(`❌ No relays in NIP-89 configuration of ${domain}!`);
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
const hasWallet = !!config.wallet;
|
||||||
|
const hasNostrdress = !!config.wallet?.lnbits?.nostdressUrl;
|
||||||
|
|
||||||
|
const ndk = new NDK({explicitRelayUrls: relays});
|
||||||
|
ndk.signer = new NDKPrivateKeySigner(configData.admin.key);
|
||||||
|
ndk.connect(5000).then(async () => {
|
||||||
|
const event = new NDKAppHandlerEvent(ndk, {
|
||||||
|
tags: [
|
||||||
|
[ "alt", "This is an nsecBunker announcement" ]
|
||||||
|
]
|
||||||
|
} as NostrEvent);
|
||||||
|
|
||||||
|
const operator = config.nip89!.operator;
|
||||||
|
if (operator) {
|
||||||
|
try {
|
||||||
|
const opUser = new NDKUser({npub: operator});
|
||||||
|
event.tags.push(["p", opUser.pubkey]);
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const user = await ndk.signer!.user();
|
||||||
|
const existingEvent = await ndk.fetchEvent({
|
||||||
|
authors: [user.pubkey],
|
||||||
|
kinds: [NDKKind.AppHandler],
|
||||||
|
"#k": [NDKKind.NostrConnect.toString()]
|
||||||
|
});
|
||||||
|
|
||||||
|
if (existingEvent) {
|
||||||
|
debug(`🔍 Found existing NIP-89 announcement for ${domain}:`, existingEvent.encode());
|
||||||
|
// update existing event
|
||||||
|
const dTag = existingEvent.tagValue("d");
|
||||||
|
event.tags.push(["d", dTag!])
|
||||||
|
} else {
|
||||||
|
debug(`🔍 No existing NIP-89 announcement for ${domain} found.`);
|
||||||
|
event.tags.push(["d", NDKKind.NostrConnect.toString()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
event.content = JSON.stringify(profile);
|
||||||
|
event.tags.push(["k", NDKKind.NostrConnect.toString()])
|
||||||
|
if (hasWallet && hasNostrdress) {
|
||||||
|
// add wallet and zaps feature tags
|
||||||
|
event.tags.push(["f", "wallet"]);
|
||||||
|
event.tags.push(["f", "zaps"]);
|
||||||
|
}
|
||||||
|
await event.publish();
|
||||||
|
debug(`✅ Published NIP-89 announcement for ${domain}:`, event.encode());
|
||||||
|
} catch(e: any) { console.log(`❌ Failed to publish NIP-89 announcement for ${domain}!`, e.message); }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This command starts the nsecbunkerd process with an (optional)
|
* This command starts the nsecbunkerd process with an (optional)
|
||||||
* admin interface over websockets or redis.
|
* admin interface over websockets or redis.
|
||||||
@@ -24,6 +97,8 @@ export async function start(opts: IOpts) {
|
|||||||
|
|
||||||
await saveCurrentConfig(opts.config, configData);
|
await saveCurrentConfig(opts.config, configData);
|
||||||
|
|
||||||
|
nip89announcement(configData);
|
||||||
|
|
||||||
if (opts.verbose) {
|
if (opts.verbose) {
|
||||||
configData.verbose = opts.verbose;
|
configData.verbose = opts.verbose;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,11 @@ export interface IWalletConfig {
|
|||||||
|
|
||||||
export interface DomainConfig {
|
export interface DomainConfig {
|
||||||
nip05: string;
|
nip05: string;
|
||||||
|
nip89?: {
|
||||||
|
profile: Record<string, string>;
|
||||||
|
operator?: string;
|
||||||
|
relays: string[];
|
||||||
|
},
|
||||||
wallet?: IWalletConfig;
|
wallet?: IWalletConfig;
|
||||||
defaultProfile?: Record<string, string>;
|
defaultProfile?: Record<string, string>;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user