open-secrets-sdk 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +73 -13
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -2,6 +2,15 @@
2
2
 
3
3
  A decentralized protocol for anonymous confessions, built on Nostr.
4
4
 
5
+ ## Our Philosophy
6
+
7
+ Confession websites are ephemeral. They start empty, grow briefly, and eventually die, taking years of human secrets and community with them.
8
+
9
+ **Open Secrets** was created to end this cycle. By moving the "database" of secrets to a decentralized network (Nostr), we ensure that:
10
+ - **Communities Never Die**: If your favorite confession site goes offline, the data remains. A new client can spin up and instantly restore the entire community history.
11
+ - **Global Repository**: We are building a permanent, global archive of anonymous human experiences that no single entity owns or can delete.
12
+ - **Cross-App discovery**: A secret posted on one app can be discovered and discussed on another, creating a massive, interconnected network of anonymous talk.
13
+
5
14
  ## Installation
6
15
 
7
16
  ```bash
@@ -23,13 +32,7 @@ const tags = createOpenSecretsTags({
23
32
  client: 'my-awesome-app'
24
33
  });
25
34
 
26
- // Use with nostr-tools
27
- const event = {
28
- kind: 1,
29
- content: "This is my secret...",
30
- tags: tags,
31
- created_at: Math.floor(Date.now() / 1000)
32
- };
35
+ // Use with nostr-tools to sign and publish
33
36
  ```
34
37
 
35
38
  ### Parsing metadata
@@ -39,16 +42,73 @@ import { parseOpenSecretsTags } from 'open-secrets-sdk';
39
42
 
40
43
  const metadata = parseOpenSecretsTags(event.tags);
41
44
  console.log(metadata.gender); // 'female'
42
- console.log(metadata.client); // 'my-awesome-app'
43
45
  ```
44
46
 
45
- ### Fetching posts
47
+ ## Building a Client
46
48
 
47
- ```typescript
48
- import { getOpenSecretsFilter } from 'open-secrets-sdk';
49
+ To build a barebones client, you need to query Nostr relays for events with the `#t: open-secrets` tag.
50
+
51
+ ### Simple Frontend Example (React-ish)
52
+
53
+ ```javascript
54
+ import { SimplePool } from 'nostr-tools';
55
+ import { getOpenSecretsFilter, parseOpenSecretsTags } from 'open-secrets-sdk';
56
+
57
+ const relays = ['wss://nos.lol', 'wss://relay.damus.io'];
58
+ const pool = new SimplePool();
59
+
60
+ async function fetchSecrets() {
61
+ const filter = getOpenSecretsFilter(50);
62
+ const events = await pool.querySync(relays, filter);
63
+
64
+ return events.map(event => ({
65
+ ...event,
66
+ metadata: parseOpenSecretsTags(event.tags)
67
+ }));
68
+ }
69
+ ```
70
+
71
+ ## Moderation & Safety
72
+
73
+ ### The Decentralized Reality
74
+ Because Open Secrets is decentralized, **no one can delete a post from the network once it is published.** There is no central admin who can "wipe" undesirable content.
75
+
76
+ ### Client-Side Defense (The "Gatekeeper" Role)
77
+ As a client developer, you are the editor of your own app. You have the power (and responsibility) to decide what your users see.
78
+
79
+ **Since you cannot censor the protocol, you must filter the view.**
80
+
81
+ #### 1. NSFW Handling
82
+ Always check the `isNsfw` flag on the metadata. You can choose to blur these posts or hide them entirely by default.
83
+
84
+ ```javascript
85
+ const postsToShow = allPosts.filter(p => !p.metadata.isNsfw);
86
+ ```
87
+
88
+ #### 2. Content Removals (Reporting)
89
+ Since every post uses a fresh identity, blacklisting users is impossible. However, you can maintain a local list of problematic `event.id`s (e.g., from reports) to hide specific posts that violate your app's rules.
90
+
91
+ ```javascript
92
+ const REMOVED_IDS = ['event_id_1', 'event_id_2'];
93
+ const filteredPosts = posts.filter(p => !REMOVED_IDS.includes(p.id));
94
+ ```
95
+
96
+ #### 3. Trust-Based Filtering (Client Allowlist)
97
+ If you want to be stricter, you can choose to only display posts that originated from "trusted" clients.
98
+
99
+ **Note on Trusted Clients**: Some client may use a "publish first, moderate later" approach to ensure a 100% censorship-resistant archive. This means a trusted client *will* still broadcast everything to Nostr, but will hide problematic posts in its own UI once its filters catch up. As a developer, you should always combine client trust with your own local filters.
100
+
101
+ ```javascript
102
+ const TRUSTED_CLIENTS = ['lapregunta', 'trusted-app-1'];
103
+ const verifiedPosts = posts.filter(p => TRUSTED_CLIENTS.includes(p.metadata.client));
104
+ ```
105
+
106
+ #### 3. Content Filtering
107
+ Since it's anonymous text, you can run simple keyword filters before rendering the content to the user.
49
108
 
50
- const filter = getOpenSecretsFilter(100);
51
- // Query your favorite relays...
109
+ ```javascript
110
+ const BAD_WORDS = ['...'];
111
+ const safePosts = posts.filter(p => !BAD_WORDS.some(word => p.content.includes(word)));
52
112
  ```
53
113
 
54
114
  ## Protocol Details
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-secrets-sdk",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "SDK for the Open Secrets protocol on Nostr",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",