spasm.js 0.1.0

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.
@@ -0,0 +1,3 @@
1
+ import { identifyPostOrEvent, convertToSpasm } from "./identifyEvent";
2
+
3
+ export { identifyPostOrEvent, convertToSpasm }
@@ -0,0 +1,283 @@
1
+ export type FiltersCategory = "defi" | "nft" | "privacy" | "any" | null;
2
+ export type PostId = string | number | null | undefined
3
+ export type PostUrl = string | null | undefined
4
+ export type PostSignature = string | null | undefined
5
+ export type PostAction = Web3MessageAction | null | undefined
6
+
7
+ export interface Post {
8
+ // web2 & web3
9
+ // Each post might have different IDs on different servers
10
+ id?: PostId // dbId in SpasmEvent
11
+
12
+ // web2 only
13
+ // guid, source, author, url, description, pubdate
14
+ // are usually taken from the RSS feed.
15
+ guid?: string | null // eventId in SpasmEvent
16
+ source?: string | null // source in SpasmEvent
17
+ author?: string | null // author in SpasmEvent
18
+ url?: PostUrl // links.http|ipfs|etc in SpasmEvent
19
+ description?: string | null // content in SpasmEvent
20
+ pubdate?: string | null // timestamp in SpasmEvent
21
+
22
+ // web3 only
23
+ target?: string | null // parentEvent in SpasmEvent
24
+ action?: PostAction // action in SpasmEvent
25
+ text?: string | null // content in SpasmEvent
26
+ signer?: string | null // author in SpasmEvent
27
+ signed_message?: string | null // originalEventString in SpasmEvent
28
+ signature?: PostSignature // signature in SpasmEvent
29
+ signed_time?: string | null // timestamp in SpasmEvent
30
+ added_time?: string | null // dbTimestamp in SpasmEvent
31
+ ipfs? : string | null // links.ipfs in SpasmEvent
32
+
33
+ // web2 & web3
34
+ tickers?: string[] | null // keywords in SpasmEvent
35
+ title?: string | null // title in SpasmEvent
36
+ category?: string | null // category in SpasmEvent
37
+ tags?: string[] | null // spasmEvent.tags ??
38
+ upvote?: number | null // spasmEvent.reactions.upvote
39
+ downvote?: number | null
40
+ bullish?: number | null
41
+ bearish?: number | null
42
+ important?: number | null
43
+ scam?: number | null
44
+ comments_count?: number | null
45
+ latest_action_added_time?: string | null
46
+
47
+ // comments
48
+ children?: Post[]
49
+ }
50
+
51
+ export type Web3MessageAction = "post" | "react" | "reply"
52
+
53
+ export type Web3MessageLicense = "MIT" | "CC0" | "CC0-1.0" | "SPDX-License-Identifier: CC0-1.0" | "SPDX-License-Identifier: MIT"
54
+
55
+ export interface Web3Message {
56
+ version: string
57
+ time?: string
58
+ action: Web3MessageAction
59
+ target?: string
60
+ title?: string
61
+ text?: string
62
+ license: Web3MessageLicense
63
+ }
64
+
65
+ export type NostrSpasmTag = SpasmVersionTag | SpasmTargetTag | SpasmActionTag | SpasmCategoryTag | SpasmTitleTag | SpasmLicenseTag
66
+
67
+ export type SpasmVersionTag = ["spasm_version", string]
68
+
69
+ export type SpasmTargetTag = ["spasm_target", string]
70
+
71
+ export type SpasmActionTag = ["spasm_action", Web3MessageAction]
72
+
73
+ export type SpasmCategoryTag = ["spasm_category", FiltersCategory]
74
+
75
+ export type SpasmTitleTag = ["spasm_title", string]
76
+
77
+ export type SpasmLicenseTag = ["license", Web3MessageLicense]
78
+
79
+ export type AnyTag = any[]
80
+
81
+ export type UnknownEvent =
82
+ DmpEvent |
83
+ DmpEventSignedClosed |
84
+ DmpEventSignedOpened |
85
+ NostrEvent |
86
+ NostrEventSignedOpened |
87
+ NostrSpasmEvent |
88
+ NostrSpasmEventSignedOpened |
89
+ SpasmEvent
90
+
91
+ export type UnknownPostOrEvent = Post | UnknownEvent
92
+
93
+ export interface NostrEvent {
94
+ id?: string
95
+ content: string
96
+ created_at: number
97
+ kind: number
98
+ pubkey: string
99
+ tags?: AnyTag[]
100
+ }
101
+
102
+ export interface NostrEventSignedOpened extends NostrEvent {
103
+ id: string
104
+ sig: string
105
+ }
106
+
107
+ // Nostr event with extra tags to be compatible with SPASM.
108
+ export interface NostrSpasmEvent {
109
+ id?: string
110
+ content: string
111
+ created_at: number
112
+ kind: number
113
+ pubkey: string
114
+ // tags: (NostrSpasmTag | AnyTag)[]
115
+ // Require at least one tag, followed by any number of tags.
116
+ tags: [(NostrSpasmTag | AnyTag), ...(NostrSpasmTag | AnyTag)[]]
117
+
118
+ // TODO: how to enforce that tags should have at least
119
+ // one element of type NostrSpasmTag?
120
+ // The solution below requires that the first element
121
+ // of tags array should be of type NostrSpasmTag,
122
+ // followed by any number of elements of type NostrSpasmTag or AnyTag.
123
+ // However, there might be other tags, so NostrSpasmTag might be not
124
+ // the first element in the tags array.
125
+ // tags: [NostrSpasmTag, ...(NostrSpasmTag | AnyTag)[]]
126
+ }
127
+
128
+ // Signed Nostr event with extra tags to be compatible with SPASM.
129
+ // 'Opened' means that the signed event is already an object
130
+ // so there is no need to convert any string to an object.
131
+ export interface NostrSpasmEventSignedOpened extends NostrSpasmEvent {
132
+ id: string
133
+ sig: string
134
+ }
135
+
136
+ export interface DmpEvent extends Web3Message {}
137
+
138
+ // 'Closed' means that the signed string has to be converted to an
139
+ // object in order to get an access to the properties of the event.
140
+ export interface DmpEventSignedClosed {
141
+ signedString: string
142
+ signature: string
143
+ signer?: string
144
+ }
145
+
146
+ // 'Opened' means that the signed event has an object with all the
147
+ // properties of the event, so there is no need to convert
148
+ // any string to an object in order to work with the event.
149
+ export interface DmpEventSignedOpened extends DmpEventSignedClosed {
150
+ signedObject: DmpEvent
151
+ }
152
+
153
+ export type SpasmVersion = "1.0.0" | string | false
154
+
155
+ export type EventBaseProtocol = "dmp" | "nostr" | "spasm" | false
156
+
157
+ export type EventBaseProtocolVersion = "dmp_v0.1.0" | string | false
158
+
159
+ export type EventPrivateKey = "ethereum" | "nostr" | false
160
+
161
+ export type EventProtocolCryptography = "schnorr" | "secp256k1" | string | false
162
+
163
+ export type SpasmAction = Web3MessageAction
164
+
165
+ export interface HashesObject {
166
+ sha1?: string
167
+ sha256?: string
168
+ infohash?: string
169
+ ipfs?: string
170
+ }
171
+
172
+ export interface LinksObject {
173
+ http?: string
174
+ ipfs?: string
175
+ torrent?: string
176
+ }
177
+
178
+ export type MimeType =
179
+ | "image/jpeg" | "image/png" | "image/gif" | "image/webp"
180
+ | "image/svg+xml"
181
+ | "audio/mpeg" | "audio/ogg" | "audio/wav"
182
+ | "video/mp4" | "video/ogg" | "video/webm"
183
+ | "text/plain" | "text/html" | "text/css" | "text/javascript"
184
+ | "application/json" | "application/xml" | "application/pdf"
185
+ | "application/octet-stream";
186
+
187
+ export interface EventMedia {
188
+ hashes?: HashesObject
189
+ links?: LinksObject
190
+ type?: MimeType
191
+ }
192
+
193
+ export interface EventReactions {
194
+ upvote?: number | null
195
+ downvote?: number | null
196
+ bullish?: number | null
197
+ bearish?: number | null
198
+ important?: number | null
199
+ scam?: number | null
200
+ comments_count?: number | null
201
+ latest_action_added_time?: string | null
202
+ }
203
+
204
+ export interface SpasmEvent {
205
+ baseProtocol?: EventBaseProtocol
206
+ baseProtocolVersion?: EventBaseProtocolVersion
207
+ hasExtraSpasmFields?: boolean
208
+ spasmVersion?: SpasmVersion
209
+ privateKey?: EventPrivateKey
210
+ cryptography?: EventProtocolCryptography
211
+ spasmId?: string | number
212
+ eventId?: string | number
213
+ dbId?: number | string
214
+ hashes?: HashesObject
215
+ rootEvent?: string
216
+ parentEvent?: string
217
+ action?: string
218
+ title?: string
219
+ content?: string
220
+ source?: string
221
+ timestamp?: number | string
222
+ dbTimestamp?: number | string
223
+ author?: string
224
+ category?: string
225
+ links?: LinksObject
226
+ keywords?: string[] | string
227
+ tags?: any[][]
228
+ media?: EventMedia
229
+ referencedEvents?: string[]
230
+ referencedAuthors?: string[]
231
+ previousEvent?: string | number
232
+ sequence?: number
233
+ license?: string
234
+ extra?: any
235
+ metadata?: any
236
+ language?: string
237
+ originalEventObject?: DmpEvent | NostrSpasmEventSignedOpened
238
+ originalEventString?: string
239
+ reactions?: EventReactions
240
+ comments?: any
241
+ signature?: string
242
+ }
243
+
244
+ export interface SpasmEventSignedOpened extends SpasmEvent {
245
+ signature: string
246
+ }
247
+
248
+ export interface StandardizedEvent {
249
+ signedString?: string
250
+ signature?: string
251
+ signer?: string
252
+ target?: string
253
+ action?: string
254
+ title?: string
255
+ text?: string
256
+ signedDate?: string
257
+ }
258
+
259
+ export interface SpasmSource {
260
+ name?: string
261
+ uiUrl?: string
262
+ apiUrl?: string
263
+ query?: string
264
+ showSource?: boolean
265
+ }
266
+
267
+ export class IgnoreWhitelistFor {
268
+ action: {
269
+ post: boolean
270
+ reply: boolean
271
+ react: boolean
272
+ moderate: boolean
273
+ }
274
+
275
+ constructor() {
276
+ this.action = {
277
+ post: false,
278
+ reply: false,
279
+ react: false,
280
+ moderate: false
281
+ }
282
+ }
283
+ }
@@ -0,0 +1,33 @@
1
+ import { bech32 } from "bech32";
2
+
3
+ export const isObjectWithValues = (val: any): boolean => {
4
+ if (!val) return false
5
+ if (Array.isArray(val)) return false
6
+ if (typeof(val) !== "object") return false
7
+ if (Object.keys(val).length === 0) return false
8
+
9
+ return true
10
+ }
11
+
12
+ // Nostr
13
+ export const convertHexToBech32 = (hexKey, prefix?) => {
14
+ try {
15
+ // Convert private or public key from HEX to bech32
16
+ let bytes = new Uint8Array(hexKey.length / 2);
17
+
18
+ for(let i = 0; i < hexKey.length; i+=2) {
19
+ bytes[i/2] = parseInt(hexKey.substr(i, 2), 16);
20
+ }
21
+
22
+ const words = bech32.toWords(bytes);
23
+
24
+ prefix = prefix ?? 'npub'
25
+
26
+ const bech32Key = bech32.encode(prefix, words);
27
+
28
+ return bech32Key
29
+ } catch (error) {
30
+ console.error(error)
31
+ return ''
32
+ }
33
+ }