Add files via upload
This commit is contained in:
163
counter.md
Normal file
163
counter.md
Normal file
@@ -0,0 +1,163 @@
|
||||
|
||||
## Purpose
|
||||
|
||||
This guide explains how to create and publish "Days Since / Until" counter events on Nostr using NDK (Nostr Development Kit).
|
||||
|
||||
Counters are stored as `kind: 30078` events with metadata tags for rendering.
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
* NDK installed
|
||||
* Signer available (via NIP-07, NIP-46, or npub/nsec input)
|
||||
* Relay pool configured and connected
|
||||
|
||||
---
|
||||
|
||||
## Example Setup
|
||||
|
||||
```ts
|
||||
import NDK, { NDKEvent, NDKPrivateKeySigner } from "@nostr-dev-kit/ndk";
|
||||
|
||||
const ndk = new NDK({
|
||||
explicitRelayUrls: [
|
||||
"wss://relay.azzamo.net",
|
||||
"wss://relay.damus.io"
|
||||
]
|
||||
});
|
||||
await ndk.connect();
|
||||
|
||||
// Login with nsec
|
||||
const signer = new NDKPrivateKeySigner("nsec1...");
|
||||
ndk.signer = signer;
|
||||
await ndk.signer.user();
|
||||
```
|
||||
|
||||
You can also support login via npub (read-only) or NIP-07 browser extension.
|
||||
|
||||
---
|
||||
|
||||
## Create Counter Function
|
||||
|
||||
```ts
|
||||
async function publishCounter({
|
||||
title,
|
||||
date,
|
||||
type = "since", // or "until"
|
||||
visibility = "public", // or "private"
|
||||
}: {
|
||||
title: string;
|
||||
date: string; // format YYYY-MM-DD
|
||||
type?: "since" | "until";
|
||||
visibility?: "public" | "private";
|
||||
}) {
|
||||
const event = new NDKEvent(ndk);
|
||||
event.kind = 30078;
|
||||
event.tags = [
|
||||
["type", type],
|
||||
["title", title],
|
||||
["date", date],
|
||||
["visibility", visibility],
|
||||
];
|
||||
event.content = "";
|
||||
|
||||
await event.sign();
|
||||
await event.publish();
|
||||
return event;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Public Counter Example
|
||||
|
||||
```ts
|
||||
const ev = await publishCounter({
|
||||
title: "Quit smoking",
|
||||
date: "2024-12-01",
|
||||
type: "since",
|
||||
visibility: "public",
|
||||
});
|
||||
console.log("View at /counter/" + ev.id);
|
||||
```
|
||||
|
||||
### Published JSON Output:
|
||||
|
||||
```json
|
||||
{
|
||||
"kind": 30078,
|
||||
"content": "",
|
||||
"tags": [
|
||||
["type", "since"],
|
||||
["title", "Quit smoking"],
|
||||
["date", "2024-12-01"],
|
||||
["visibility", "public"]
|
||||
],
|
||||
"created_at": 1725000000,
|
||||
"id": "note1...",
|
||||
"pubkey": "npub1..."
|
||||
}
|
||||
```
|
||||
|
||||
### Slug / Permalink
|
||||
|
||||
Use the full event ID as the URL slug:
|
||||
|
||||
```
|
||||
/counter/note1xyz... ← based on event.id (NIP-19 encoded)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Private Counter Example
|
||||
|
||||
```ts
|
||||
await publishCounter({
|
||||
title: "Last relapse",
|
||||
date: "2025-07-01",
|
||||
type: "since",
|
||||
visibility: "private",
|
||||
});
|
||||
```
|
||||
|
||||
> Note: Private counters are still published to relays but can be filtered out in the app logic.
|
||||
|
||||
---
|
||||
|
||||
## Reading Events
|
||||
|
||||
To fetch all public counters:
|
||||
|
||||
```ts
|
||||
const events = await ndk.fetchEvents({
|
||||
kinds: [30078]
|
||||
});
|
||||
|
||||
const publicEvents = Array.from(events).filter(e =>
|
||||
e.tags.find(([k, v]) => k === "visibility" && v === "public")
|
||||
);
|
||||
```
|
||||
|
||||
To fetch your own counters:
|
||||
|
||||
```ts
|
||||
const user = await ndk.signer?.user();
|
||||
const events = await ndk.fetchEvents({
|
||||
kinds: [30078],
|
||||
authors: [user?.pubkey || ""]
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Notes
|
||||
|
||||
* The URL slug for counters is the **event ID** (NIP-19 encoded if needed)
|
||||
* Event `id` is used to lookup and display the counter
|
||||
* Lightning zaps should be handled via metadata (fetch kind:0 or NIP-05 info)
|
||||
* Updating a counter means publishing a new event with new content
|
||||
|
||||
---
|
||||
|
||||
Let me know if you want to include zaps, NIP-75 fundraising goals, or update/delete flows.
|
||||
Reference in New Issue
Block a user