@solarpunkltd/swarm-chat-js 8.1.0 → 9.0.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.
@@ -1,455 +0,0 @@
1
- import { Bytes as e, EthAddress as t, Identifier as n, PrivateKey as r, Reference as i, Signature as a } from "@ethersphere/bee-js";
2
- import { z as o } from "zod";
3
- import { publicKeyToAddress as s, recoverPublicKey as c } from "@ethersphere/core-sdk/crypto";
4
- //#region src/message/canonicalSignature.ts
5
- var l = 115792089237316195423570985008687907852837564279074904382605163141518161494337n, ee = l / 2n;
6
- function u(e, t) {
7
- let n = BigInt(`0x${e}`), r = BigInt(`0x${t}`);
8
- return n > 0n && n < l && r > 0n && r <= ee;
9
- }
10
- //#endregion
11
- //#region src/message/binding.ts
12
- var d = "Swarm ID chat binding v1", te = 512, ne = "Site: ", re = "Chat address: ", ie = "Date: ", ae = "\n", f = 4, oe = "Ethereum Signed Message:\n", p = /* @__PURE__ */ new Set([27, 28]), m = /^0x[0-9a-f]{40}$/, se = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/, ce = /^[a-z0-9-]+(\.[a-z0-9-]+)*$/, le = /* @__PURE__ */ new Set([
13
- "localhost",
14
- "127.0.0.1",
15
- "[::1]"
16
- ]), h = o.strictObject({
17
- msg: o.string().max(512),
18
- sig: o.string().regex(/^0x[0-9a-f]{130}$/, "expected 0x and 130 lowercase hex characters")
19
- }), g = new TextEncoder();
20
- function ue(e, t) {
21
- let n;
22
- try {
23
- n = new URL(e);
24
- } catch {
25
- return !1;
26
- }
27
- let r = n.protocol === "https:", i = t && n.protocol === "http:" && le.has(n.hostname);
28
- return !r && !i || !i && !ce.test(n.hostname) ? !1 : n.host !== "" && n.username === "" && n.password === "" && n.origin === e;
29
- }
30
- function _(e) {
31
- if (!se.test(e)) return !1;
32
- let t = Date.parse(e);
33
- return !Number.isNaN(t) && new Date(t).toISOString() === e;
34
- }
35
- function v(e, t) {
36
- return e.startsWith(t) ? e.slice(t.length) : null;
37
- }
38
- function de(e) {
39
- let t = g.encode(e), n = g.encode(`${oe}${t.length}`), r = new Uint8Array(n.length + t.length);
40
- return r.set(n), r.set(t, n.length), r;
41
- }
42
- function fe(e) {
43
- return Array.from(e, (e) => e.toString(16).padStart(2, "0")).join("");
44
- }
45
- function y(e, t) {
46
- let n = t.slice(2, 66), r = t.slice(66, 130), i = parseInt(t.slice(130), 16);
47
- if (!p.has(i) || !u(n, r)) return null;
48
- try {
49
- let t = c(de(e), BigInt(`0x${n}`), BigInt(`0x${r}`), BigInt(i));
50
- return `0x${fe(s(t))}`;
51
- } catch {
52
- return null;
53
- }
54
- }
55
- function b(e, t, n = {}) {
56
- if (!h.safeParse(e).success) return {
57
- ok: !1,
58
- detail: "not a binding of a text and a 65 byte signature"
59
- };
60
- let r = e.msg.split(ae);
61
- if (r.length !== f || r[0] !== "Swarm ID chat binding v1") return {
62
- ok: !1,
63
- detail: `not the ${f} lines of a ${d}`
64
- };
65
- let i = v(r[1], ne), a = v(r[2], re), o = v(r[3], ie);
66
- if (i === null || !ue(i, n.allowLocalHttp === !0)) return {
67
- ok: !1,
68
- detail: "the binding does not name a clean site origin"
69
- };
70
- if (a === null || !m.test(a)) return {
71
- ok: !1,
72
- detail: "the binding does not name a chat address as 0x and 40 lowercase hex characters"
73
- };
74
- if (o === null || !_(o)) return {
75
- ok: !1,
76
- detail: "the binding date is not ISO 8601 UTC with milliseconds"
77
- };
78
- if (a !== `0x${t}`) return {
79
- ok: !1,
80
- detail: "the binding is for another chat address than addr"
81
- };
82
- if (n.origin !== void 0 && i !== n.origin) return {
83
- ok: !1,
84
- detail: `the binding is for ${i}, not ${n.origin}`
85
- };
86
- let s = y(e.msg, e.sig);
87
- return s === null ? {
88
- ok: !1,
89
- detail: "the binding signature recovers no account"
90
- } : {
91
- ok: !0,
92
- identity: {
93
- account: s,
94
- site: i,
95
- date: o
96
- }
97
- };
98
- }
99
- //#endregion
100
- //#region src/message/message.ts
101
- var x = 8, S = 3072, pe = 128, me = 500, he = 20, C = {
102
- TEXT: "text",
103
- THREAD: "thread",
104
- REACTION: "reaction"
105
- }, w = {
106
- GATEWAY: "gateway",
107
- OWN_STAMP: "own-stamp"
108
- };
109
- function T(e) {
110
- let t = 0;
111
- for (let n of e) t++;
112
- return t;
113
- }
114
- function E(e) {
115
- return o.string().regex(RegExp(`^[0-9a-f]{${e}}$`), `expected ${e} lowercase hex characters`);
116
- }
117
- function D(e, t) {
118
- return o.string().refine((n) => {
119
- let r = T(n);
120
- return r >= e && r <= t;
121
- }, `expected ${e} to ${t} characters`);
122
- }
123
- var O = E(32), k = o.strictObject({
124
- v: o.literal(8),
125
- topic: D(1, 128),
126
- id: O,
127
- type: o.enum([
128
- C.TEXT,
129
- C.THREAD,
130
- C.REACTION
131
- ]),
132
- target: o.union([o.literal(""), O]),
133
- text: D(1, 500),
134
- name: D(1, 20),
135
- addr: E(40),
136
- ts: o.number().int().nonnegative().max(2 ** 53 - 1),
137
- via: o.enum([w.GATEWAY, w.OWN_STAMP]),
138
- own: o.boolean(),
139
- idb: h.optional(),
140
- sig: E(130)
141
- }).refine((e) => e.type === C.TEXT == (e.target === ""), {
142
- message: "a text message has no target, a thread reply or a reaction names one",
143
- path: ["target"]
144
- }), A = class extends Error {
145
- constructor(e, t) {
146
- super(`chat message refused (${e}): ${t}`), this.reason = e, this.name = "ChatMessageError";
147
- }
148
- }, j = new TextEncoder(), M = "1b", N = "1c", P = new TextDecoder("utf-8", { fatal: !0 });
149
- function F(e) {
150
- return j.encode(JSON.stringify([
151
- e.v,
152
- e.topic,
153
- e.id,
154
- e.type,
155
- e.target,
156
- e.text,
157
- e.name,
158
- e.addr,
159
- e.ts,
160
- e.via,
161
- e.own,
162
- e.idb?.msg ?? "",
163
- e.idb?.sig ?? ""
164
- ]));
165
- }
166
- function I(e) {
167
- let t = {
168
- v: e.v,
169
- topic: e.topic,
170
- id: e.id,
171
- type: e.type,
172
- target: e.target,
173
- text: e.text,
174
- name: e.name,
175
- addr: e.addr,
176
- ts: e.ts,
177
- via: e.via,
178
- own: e.own,
179
- ...e.idb ? { idb: {
180
- msg: e.idb.msg,
181
- sig: e.idb.sig
182
- } } : {},
183
- sig: e.sig
184
- };
185
- return j.encode(JSON.stringify(t));
186
- }
187
- function L() {
188
- let e = crypto.getRandomValues(/* @__PURE__ */ new Uint8Array(16));
189
- return Array.from(e, (e) => e.toString(16).padStart(2, "0")).join("");
190
- }
191
- function R(e) {
192
- return e.issues.map((e) => `${e.path.join(".") || "message"}: ${e.message}`).join(", ");
193
- }
194
- function ge(e, t) {
195
- let n = e instanceof r ? e : new r(e), i = {
196
- v: 8,
197
- topic: t.topic,
198
- id: t.id ?? L(),
199
- type: t.type,
200
- target: t.target ?? "",
201
- text: t.text,
202
- name: t.name,
203
- addr: n.publicKey().address().toHex(),
204
- ts: t.ts ?? Date.now(),
205
- via: t.via,
206
- own: t.own ?? !1,
207
- ...t.idb ? { idb: t.idb } : {}
208
- }, a = {
209
- ...i,
210
- sig: "0".repeat(130)
211
- }, o = k.safeParse(a);
212
- if (!o.success) throw new A("shape", R(o.error));
213
- let s = I(a).byteLength;
214
- if (s > 3072) throw new A("too-large", `${s} bytes, the cap is ${S}`);
215
- if (i.idb) {
216
- let e = b(i.idb, i.addr, { allowLocalHttp: !0 });
217
- if (!e.ok) throw new A("binding", e.detail);
218
- }
219
- let c = {
220
- ...i,
221
- sig: n.sign(F(i)).toHex()
222
- };
223
- return {
224
- message: c,
225
- bytes: I(c)
226
- };
227
- }
228
- function z(e) {
229
- let t = e.sig.slice(128);
230
- if (t !== M && t !== N || !u(e.sig.slice(0, 64), e.sig.slice(64, 128))) return !1;
231
- try {
232
- return new a(e.sig).recoverPublicKey(F(e)).address().toHex() === e.addr;
233
- } catch {
234
- return !1;
235
- }
236
- }
237
- function B(e, t) {
238
- let n = k.safeParse(e);
239
- if (!n.success) return {
240
- ok: !1,
241
- reason: "shape",
242
- detail: R(n.error)
243
- };
244
- let r = n.data;
245
- if (!z(r)) return {
246
- ok: !1,
247
- reason: "signature",
248
- detail: "the signature was not made by addr over these fields"
249
- };
250
- if (!r.idb) return {
251
- ok: !0,
252
- message: r,
253
- identity: null
254
- };
255
- if (typeof t?.origin != "string") return {
256
- ok: !1,
257
- reason: "binding",
258
- detail: "no origin was given to check the binding against"
259
- };
260
- let i = b(r.idb, r.addr, t);
261
- return i.ok ? {
262
- ok: !0,
263
- message: r,
264
- identity: i.identity
265
- } : {
266
- ok: !1,
267
- reason: "binding",
268
- detail: i.detail
269
- };
270
- }
271
- function _e(e, t) {
272
- if (e.byteLength > 3072) return {
273
- ok: !1,
274
- reason: "too-large",
275
- detail: `${e.byteLength} bytes, the cap is ${S}`
276
- };
277
- let n;
278
- try {
279
- n = P.decode(e);
280
- } catch {
281
- return {
282
- ok: !1,
283
- reason: "not-utf8",
284
- detail: "the payload is not valid UTF-8"
285
- };
286
- }
287
- let r;
288
- try {
289
- r = JSON.parse(n);
290
- } catch {
291
- return {
292
- ok: !1,
293
- reason: "not-json",
294
- detail: "the payload is not JSON"
295
- };
296
- }
297
- return B(r, t);
298
- }
299
- //#endregion
300
- //#region src/message/ownFeed.ts
301
- var V = "swarm-chat-own-feed-v1:";
302
- function ve(e) {
303
- return `${V}${e}`;
304
- }
305
- //#endregion
306
- //#region src/message/entry.ts
307
- var ye = 4096, be = o.string().regex(/^[0-9a-f]{64}([0-9a-f]{64})?$/, "expected a 64 or 128 hex character reference"), H = o.number().int().nonnegative().max(2 ** 53 - 1), U = o.strictObject({
308
- ref: be,
309
- toSeq: H
310
- }), W = o.strictObject({
311
- v: o.literal(8),
312
- seq: H,
313
- at: H,
314
- msg: k,
315
- history: U.nullable()
316
- }), G = o.strictObject({
317
- seq: H,
318
- at: H,
319
- msg: k
320
- }), K = o.strictObject({
321
- v: o.literal(8),
322
- topic: o.string().min(1),
323
- fromSeq: H,
324
- toSeq: H,
325
- messages: o.array(o.unknown()),
326
- prev: U.nullable()
327
- }).refine((e) => e.fromSeq <= e.toSeq, {
328
- message: "fromSeq is after toSeq",
329
- path: ["fromSeq"]
330
- }), xe = new TextDecoder("utf-8", { fatal: !0 });
331
- function q(e) {
332
- let t;
333
- try {
334
- t = xe.decode(e);
335
- } catch {
336
- return {
337
- ok: !1,
338
- reason: "not-utf8",
339
- detail: "the payload is not valid UTF-8"
340
- };
341
- }
342
- try {
343
- return {
344
- ok: !0,
345
- value: JSON.parse(t)
346
- };
347
- } catch {
348
- return {
349
- ok: !1,
350
- reason: "not-json",
351
- detail: "the payload is not JSON"
352
- };
353
- }
354
- }
355
- function J(e) {
356
- return e.issues.map((e) => `${e.path.join(".") || "value"}: ${e.message}`).join(", ");
357
- }
358
- function Se(e, t, n) {
359
- let r = q(e);
360
- if (!r.ok) return r;
361
- let i = W.safeParse(r.value);
362
- return i.success ? i.data.seq === t ? i.data.msg.topic === n ? {
363
- ok: !0,
364
- value: i.data
365
- } : {
366
- ok: !1,
367
- reason: "mismatch",
368
- detail: "the message belongs to another chat"
369
- } : {
370
- ok: !1,
371
- reason: "mismatch",
372
- detail: `seq ${i.data.seq} at index ${t}`
373
- } : {
374
- ok: !1,
375
- reason: "shape",
376
- detail: J(i.error)
377
- };
378
- }
379
- function Ce(e, t, n) {
380
- let r = q(e);
381
- if (!r.ok) return r;
382
- let i = K.safeParse(r.value);
383
- if (!i.success) return {
384
- ok: !1,
385
- reason: "shape",
386
- detail: J(i.error)
387
- };
388
- if (i.data.topic !== t || i.data.toSeq !== n.toSeq) return {
389
- ok: !1,
390
- reason: "mismatch",
391
- detail: "the file is not the one its link names"
392
- };
393
- let { fromSeq: a, toSeq: o, prev: s } = i.data, c = [], l = 0;
394
- for (let e of i.data.messages) {
395
- let n = G.safeParse(e);
396
- n.success && n.data.seq >= a && n.data.seq <= o && n.data.msg.topic === t ? c.push(n.data) : l++;
397
- }
398
- return {
399
- ok: !0,
400
- value: {
401
- topic: t,
402
- fromSeq: a,
403
- toSeq: o,
404
- rows: c,
405
- prev: s,
406
- skipped: l
407
- }
408
- };
409
- }
410
- //#endregion
411
- //#region src/message/note.ts
412
- var we = 1, Y = 2e3, Te = 3e4, Ee = 256, X = o.strictObject({
413
- v: o.literal(1),
414
- newest: o.number().int().min(-1).max(2 ** 53 - 1),
415
- writtenAt: o.number().int().nonnegative().max(2 ** 53 - 1)
416
- });
417
- function Z(e) {
418
- if (!Number.isInteger(e) || e <= 0) throw RangeError(`a note slot is a positive whole number of milliseconds, not ${e}`);
419
- }
420
- function De(e, t) {
421
- return Z(t), Math.floor(e / t);
422
- }
423
- function Oe(e, t) {
424
- return Z(t), (e + 1) * t;
425
- }
426
- function Q(e, t, n) {
427
- return `${e}/note/${t}/${n}`;
428
- }
429
- function $(e, t, r) {
430
- return n.fromString(Q(e, t, r));
431
- }
432
- function ke(n, r, a, o) {
433
- let s = $(n, r, a);
434
- return new i(e.keccak256(e.concat(s.toUint8Array(), new t(o).toUint8Array())));
435
- }
436
- var Ae = new TextEncoder(), je = new TextDecoder("utf-8", { fatal: !0 });
437
- function Me(e) {
438
- let t = {
439
- v: 1,
440
- newest: e.newest,
441
- writtenAt: e.writtenAt
442
- };
443
- return Ae.encode(JSON.stringify(t));
444
- }
445
- function Ne(e) {
446
- if (e.length > 256) return null;
447
- try {
448
- let t = X.safeParse(JSON.parse(je.decode(e)));
449
- return t.success ? t.data : null;
450
- } catch {
451
- return null;
452
- }
453
- }
454
- //#endregion
455
- export { k as A, te as B, S as C, x as D, pe as E, L as F, b as H, _e as I, F as L, ge as M, I as N, C as O, z as P, B as R, A as S, me as T, h as V, G as _, Me as a, V as b, Q as c, Ne as d, X as f, U as g, K as h, we as i, T as j, w as k, Oe as l, W as m, Y as n, ke as o, ye as p, Ee as r, $ as s, Te as t, De as u, Se as v, he as w, ve as x, Ce as y, d as z };