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.
- package/LICENSE.md +21 -0
- package/lib.commonjs/README.md +20 -0
- package/lib.commonjs/identifyEvent.js +812 -0
- package/lib.commonjs/identifyEvent.js.map +1 -0
- package/lib.commonjs/index.js +7 -0
- package/lib.commonjs/index.js.map +1 -0
- package/lib.commonjs/interfaces.js +16 -0
- package/lib.commonjs/interfaces.js.map +1 -0
- package/lib.commonjs/package.json +4 -0
- package/lib.commonjs/utils.js +36 -0
- package/lib.commonjs/utils.js.map +1 -0
- package/lib.esm/README.md +20 -0
- package/lib.esm/identifyEvent.js +778 -0
- package/lib.esm/identifyEvent.js.map +1 -0
- package/lib.esm/index.js +3 -0
- package/lib.esm/index.js.map +1 -0
- package/lib.esm/interfaces.js +12 -0
- package/lib.esm/interfaces.js.map +1 -0
- package/lib.esm/package.json +4 -0
- package/lib.esm/utils.js +31 -0
- package/lib.esm/utils.js.map +1 -0
- package/package.json +49 -0
- package/src.ts/identifyEvent.ts +1103 -0
- package/src.ts/index.ts +3 -0
- package/src.ts/interfaces.ts +283 -0
- package/src.ts/utils.ts +33 -0
package/src.ts/index.ts
ADDED
|
@@ -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
|
+
}
|
package/src.ts/utils.ts
ADDED
|
@@ -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
|
+
}
|