@solarpunkltd/swarm-chat-js 8.1.0 → 10.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.
@@ -0,0 +1,551 @@
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
+ // src/message/canonicalSignature.ts
5
+ var l = 115792089237316195423570985008687907852837564279074904382605163141518161494337n, ee = l / 2n;
6
+ function te(e, t) {
7
+ let n = BigInt(`0x${e}`), r = BigInt(`0x${t}`);
8
+ return n > 0n && n < l && r > 0n && r <= ee;
9
+ }
10
+ // src/message/personalSign.ts
11
+ var ne = "Ethereum Signed Message:\n", re = /* @__PURE__ */ new Set([27, 28]), ie = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/, u = new TextEncoder();
12
+ function ae(e) {
13
+ let t = u.encode(e), n = u.encode(`${ne}${t.length}`), r = new Uint8Array(n.length + t.length);
14
+ return r.set(n), r.set(t, n.length), r;
15
+ }
16
+ function oe(e) {
17
+ return Array.from(e, (e) => e.toString(16).padStart(2, "0")).join("");
18
+ }
19
+ function d(e, t) {
20
+ let n = t.slice(2, 66), r = t.slice(66, 130), i = parseInt(t.slice(130), 16);
21
+ if (!re.has(i) || !te(n, r)) return null;
22
+ try {
23
+ let t = c(ae(e), BigInt(`0x${n}`), BigInt(`0x${r}`), BigInt(i));
24
+ return `0x${oe(s(t))}`;
25
+ } catch {
26
+ return null;
27
+ }
28
+ }
29
+ function f(e) {
30
+ if (!ie.test(e)) return !1;
31
+ let t = Date.parse(e);
32
+ return !Number.isNaN(t) && new Date(t).toISOString() === e;
33
+ }
34
+ // src/message/binding.ts
35
+ var p = "Swarm ID chat binding v1", se = 512, ce = "Site: ", le = "Chat address: ", ue = "Date: ", de = "\n", fe = 4, pe = /^0x[0-9a-f]{40}$/, me = /^[a-z0-9-]+(\.[a-z0-9-]+)*$/, he = /* @__PURE__ */ new Set([
36
+ "localhost",
37
+ "127.0.0.1",
38
+ "[::1]"
39
+ ]), m = o.strictObject({
40
+ msg: o.string().max(512),
41
+ sig: o.string().regex(/^0x[0-9a-f]{130}$/, "expected 0x and 130 lowercase hex characters")
42
+ });
43
+ function ge(e, t) {
44
+ let n;
45
+ try {
46
+ n = new URL(e);
47
+ } catch {
48
+ return !1;
49
+ }
50
+ let r = n.protocol === "https:", i = t && n.protocol === "http:" && he.has(n.hostname);
51
+ return !r && !i || !i && !me.test(n.hostname) ? !1 : n.host !== "" && n.username === "" && n.password === "" && n.origin === e;
52
+ }
53
+ function h(e, t) {
54
+ return e.startsWith(t) ? e.slice(t.length) : null;
55
+ }
56
+ function g(e, t, n = {}) {
57
+ if (!m.safeParse(e).success) return {
58
+ ok: !1,
59
+ detail: "not a binding of a text and a 65 byte signature"
60
+ };
61
+ let r = e.msg.split(de);
62
+ if (r.length !== fe || r[0] !== "Swarm ID chat binding v1") return {
63
+ ok: !1,
64
+ detail: `not the ${fe} lines of a ${p}`
65
+ };
66
+ let i = h(r[1], ce), a = h(r[2], le), o = h(r[3], ue);
67
+ if (i === null || !ge(i, n.allowLocalHttp === !0)) return {
68
+ ok: !1,
69
+ detail: "the binding does not name a clean site origin"
70
+ };
71
+ if (a === null || !pe.test(a)) return {
72
+ ok: !1,
73
+ detail: "the binding does not name a chat address as 0x and 40 lowercase hex characters"
74
+ };
75
+ if (o === null || !f(o)) return {
76
+ ok: !1,
77
+ detail: "the binding date is not ISO 8601 UTC with milliseconds"
78
+ };
79
+ if (a !== `0x${t}`) return {
80
+ ok: !1,
81
+ detail: "the binding is for another chat address than addr"
82
+ };
83
+ if (n.origins !== void 0 && !Array.isArray(n.origins)) return {
84
+ ok: !1,
85
+ detail: "origins is not a list of sites"
86
+ };
87
+ if (n.origins !== void 0 && !n.origins.includes(i)) return {
88
+ ok: !1,
89
+ detail: `the binding is for ${i}, not for ${n.origins.join(" or ") || "any site"}`
90
+ };
91
+ let s = d(e.msg, e.sig);
92
+ return s === null ? {
93
+ ok: !1,
94
+ detail: "the binding signature recovers no account"
95
+ } : {
96
+ ok: !0,
97
+ identity: {
98
+ account: s,
99
+ site: i,
100
+ date: o
101
+ }
102
+ };
103
+ }
104
+ // src/message/walletLink.ts
105
+ var _ = "Swarm ID wallet link v1", _e = "I link this wallet to the Swarm ID account below, so sites may show my ENS name beside its messages.", ve = 320, ye = "Account: ", be = "Wallet: ", xe = "Date: ", Se = "\n", v = 5, y = /^0x[0-9a-f]{40}$/, b = o.string().regex(/^0x[0-9a-f]{130}$/, "expected 0x and 130 lowercase hex characters"), x = o.strictObject({
106
+ msg: o.string().max(320),
107
+ wsig: b,
108
+ asig: b
109
+ });
110
+ function S(e, t) {
111
+ return e.startsWith(t) ? e.slice(t.length) : null;
112
+ }
113
+ function C(e, t) {
114
+ if (!x.safeParse(e).success) return {
115
+ ok: !1,
116
+ detail: "not a wallet link of a text and two 65 byte signatures"
117
+ };
118
+ let n = e.msg.split(Se);
119
+ if (n.length !== v || n[0] !== "Swarm ID wallet link v1") return {
120
+ ok: !1,
121
+ detail: `not the ${v} lines of a ${_}`
122
+ };
123
+ if (n[1] !== "I link this wallet to the Swarm ID account below, so sites may show my ENS name beside its messages.") return {
124
+ ok: !1,
125
+ detail: `the wallet link's second line is not the ${_} statement`
126
+ };
127
+ let r = S(n[2], ye), i = S(n[3], be), a = S(n[4], xe);
128
+ return r === null || !y.test(r) ? {
129
+ ok: !1,
130
+ detail: "the wallet link does not name an account as 0x and 40 lowercase hex characters"
131
+ } : i === null || !y.test(i) ? {
132
+ ok: !1,
133
+ detail: "the wallet link does not name a wallet as 0x and 40 lowercase hex characters"
134
+ } : a === null || !f(a) ? {
135
+ ok: !1,
136
+ detail: "the wallet link date is not ISO 8601 UTC with milliseconds"
137
+ } : r === t ? d(e.msg, e.wsig) === i ? d(e.msg, e.asig) === r ? {
138
+ ok: !0,
139
+ wallet: i,
140
+ account: r,
141
+ date: a
142
+ } : {
143
+ ok: !1,
144
+ detail: "the account signature does not recover the account the link names"
145
+ } : {
146
+ ok: !1,
147
+ detail: "the wallet signature does not recover the wallet the link names"
148
+ } : {
149
+ ok: !1,
150
+ detail: `the wallet link is for ${r}, not the binding's account ${t}`
151
+ };
152
+ }
153
+ // src/message/message.ts
154
+ var Ce = 9, w = 3072, we = 128, Te = 500, Ee = 20, T = {
155
+ TEXT: "text",
156
+ THREAD: "thread",
157
+ REACTION: "reaction"
158
+ }, E = {
159
+ GATEWAY: "gateway",
160
+ OWN_STAMP: "own-stamp"
161
+ };
162
+ function D(e) {
163
+ let t = 0;
164
+ for (let n of e) t++;
165
+ return t;
166
+ }
167
+ function O(e) {
168
+ return o.string().regex(RegExp(`^[0-9a-f]{${e}}$`), `expected ${e} lowercase hex characters`);
169
+ }
170
+ function k(e, t) {
171
+ return o.string().refine((n) => {
172
+ let r = D(n);
173
+ return r >= e && r <= t;
174
+ }, `expected ${e} to ${t} characters`);
175
+ }
176
+ var A = /(?![\u200c\u200d])[\p{Cf}\p{Cc}\u2800\u115f\u1160\u3164\uffa0]|\u034f|\u17b4|\u17b5/u, De = /[\p{Default_Ignorable_Code_Point}\p{Mn}\p{Me}\u2800]/gu, j = Object.fromEntries([
177
+ ...[..."℮ꬲеҽ⋿ΕЕⴹᎬꗋꓰ𑢦𑢮𐊆𝾁"].map((e) => [e, "e"]),
178
+ ...[..."⊤⟙🝨𝍳ΤⲦТтߠᎢꔋㄒꓔ𖼊𑢼𐊗𐊱𐌕丅"].map((e) => [e, "t"]),
179
+ ...[..."һҺႹհᏂΗⲎНнᎻᕼꓧ𐋏"].map((e) => [e, "h"])
180
+ ]), Oe = RegExp(`[${Object.keys(j).join("")}]`, "gu"), ke = /[\u3002\u0660\u06f0\u0701\u0702\ua4f8\ua60e\uabec\u{10a50}\u{1d16d}\u{1ecae}]/gu, Ae = /[\p{Z}.]+$/u, M = ".eth";
181
+ function je(e) {
182
+ return e.normalize("NFKD").replace(ke, ".").replace(De, "").replace(Oe, (e) => j[e] ?? e).toLowerCase().trim().replace(Ae, "");
183
+ }
184
+ function N(e) {
185
+ return je(e).endsWith(M);
186
+ }
187
+ function Me(e, t) {
188
+ return k(e, t).refine((e) => !A.test(e), "expected no format or control characters").refine((e) => !N(e), `expected a name not ending in ${M}, which ENS names keep`);
189
+ }
190
+ function Ne(e) {
191
+ let t = D(e);
192
+ return t < 1 || t > 20 ? "length" : A.test(e) ? "invisible" : N(e) ? "ens-like" : null;
193
+ }
194
+ var P = O(32), F = o.strictObject({
195
+ v: o.literal(9),
196
+ topic: k(1, 128),
197
+ id: P,
198
+ type: o.enum([
199
+ T.TEXT,
200
+ T.THREAD,
201
+ T.REACTION
202
+ ]),
203
+ target: o.union([o.literal(""), P]),
204
+ text: k(1, 500),
205
+ name: Me(1, 20),
206
+ addr: O(40),
207
+ ts: o.number().int().nonnegative().max(2 ** 53 - 1),
208
+ via: o.enum([E.GATEWAY, E.OWN_STAMP]),
209
+ idb: m.optional(),
210
+ wl: x.optional(),
211
+ sig: O(130)
212
+ }).refine((e) => e.type === T.TEXT == (e.target === ""), {
213
+ message: "a text message has no target, a thread reply or a reaction names one",
214
+ path: ["target"]
215
+ }).refine((e) => e.wl === void 0 || e.idb !== void 0, {
216
+ message: "a wallet link is carried only beside a chat binding, whose account it names",
217
+ path: ["wl"]
218
+ }), I = class extends Error {
219
+ constructor(e, t) {
220
+ super(`chat message refused (${e}): ${t}`), this.reason = e, this.name = "ChatMessageError";
221
+ }
222
+ }, L = new TextEncoder(), Pe = "1b", Fe = "1c", Ie = new TextDecoder("utf-8", { fatal: !0 });
223
+ function R(e) {
224
+ return L.encode(JSON.stringify([
225
+ e.v,
226
+ e.topic,
227
+ e.id,
228
+ e.type,
229
+ e.target,
230
+ e.text,
231
+ e.name,
232
+ e.addr,
233
+ e.ts,
234
+ e.via,
235
+ e.idb?.msg ?? "",
236
+ e.idb?.sig ?? "",
237
+ ...e.wl ? [
238
+ e.wl.msg,
239
+ e.wl.wsig,
240
+ e.wl.asig
241
+ ] : []
242
+ ]));
243
+ }
244
+ function z(e) {
245
+ let t = {
246
+ v: e.v,
247
+ topic: e.topic,
248
+ id: e.id,
249
+ type: e.type,
250
+ target: e.target,
251
+ text: e.text,
252
+ name: e.name,
253
+ addr: e.addr,
254
+ ts: e.ts,
255
+ via: e.via,
256
+ ...e.idb ? { idb: {
257
+ msg: e.idb.msg,
258
+ sig: e.idb.sig
259
+ } } : {},
260
+ ...e.wl ? { wl: {
261
+ msg: e.wl.msg,
262
+ wsig: e.wl.wsig,
263
+ asig: e.wl.asig
264
+ } } : {},
265
+ sig: e.sig
266
+ };
267
+ return L.encode(JSON.stringify(t));
268
+ }
269
+ function B() {
270
+ let e = crypto.getRandomValues(/* @__PURE__ */ new Uint8Array(16));
271
+ return Array.from(e, (e) => e.toString(16).padStart(2, "0")).join("");
272
+ }
273
+ function V(e) {
274
+ return e.issues.map((e) => `${e.path.join(".") || "message"}: ${e.message}`).join(", ");
275
+ }
276
+ function Le(e, t) {
277
+ let n = e instanceof r ? e : new r(e), i = {
278
+ v: 9,
279
+ topic: t.topic,
280
+ id: t.id ?? B(),
281
+ type: t.type,
282
+ target: t.target ?? "",
283
+ text: t.text,
284
+ name: t.name,
285
+ addr: n.publicKey().address().toHex(),
286
+ ts: t.ts ?? Date.now(),
287
+ via: t.via,
288
+ ...t.idb ? { idb: t.idb } : {},
289
+ ...t.wl ? { wl: t.wl } : {}
290
+ }, a = {
291
+ ...i,
292
+ sig: "0".repeat(130)
293
+ }, o = F.safeParse(a);
294
+ if (!o.success) throw new I("shape", V(o.error));
295
+ let s = z(a).byteLength;
296
+ if (s > 3072) throw new I("too-large", `${s} bytes, the cap is ${w}`);
297
+ if (i.idb) {
298
+ let e = g(i.idb, i.addr, { allowLocalHttp: !0 });
299
+ if (!e.ok) throw new I("binding", e.detail);
300
+ if (i.wl) {
301
+ let t = C(i.wl, e.identity.account);
302
+ if (!t.ok) throw new I("binding", `wallet link: ${t.detail}`);
303
+ }
304
+ }
305
+ let c = {
306
+ ...i,
307
+ sig: n.sign(R(i)).toHex()
308
+ };
309
+ return {
310
+ message: c,
311
+ bytes: z(c)
312
+ };
313
+ }
314
+ function H(e) {
315
+ let t = e.sig.slice(128);
316
+ if (t !== Pe && t !== Fe || !te(e.sig.slice(0, 64), e.sig.slice(64, 128))) return !1;
317
+ try {
318
+ return new a(e.sig).recoverPublicKey(R(e)).address().toHex() === e.addr;
319
+ } catch {
320
+ return !1;
321
+ }
322
+ }
323
+ function U(e, t) {
324
+ let n = F.safeParse(e);
325
+ if (!n.success) return {
326
+ ok: !1,
327
+ reason: "shape",
328
+ detail: V(n.error)
329
+ };
330
+ let r = n.data;
331
+ if (!H(r)) return {
332
+ ok: !1,
333
+ reason: "signature",
334
+ detail: "the signature was not made by addr over these fields"
335
+ };
336
+ if (!r.idb) return {
337
+ ok: !0,
338
+ message: r,
339
+ identity: null
340
+ };
341
+ if (!Array.isArray(t?.origins)) return {
342
+ ok: !1,
343
+ reason: "binding",
344
+ detail: "no origins were given to check the binding against"
345
+ };
346
+ let i = g(r.idb, r.addr, t);
347
+ if (!i.ok) return {
348
+ ok: !1,
349
+ reason: "binding",
350
+ detail: i.detail
351
+ };
352
+ if (!r.wl) return {
353
+ ok: !0,
354
+ message: r,
355
+ identity: i.identity
356
+ };
357
+ let a = C(r.wl, i.identity.account);
358
+ return a.ok ? {
359
+ ok: !0,
360
+ message: r,
361
+ identity: {
362
+ ...i.identity,
363
+ wallet: a.wallet
364
+ }
365
+ } : {
366
+ ok: !1,
367
+ reason: "binding",
368
+ detail: `wallet link: ${a.detail}`
369
+ };
370
+ }
371
+ function Re(e, t) {
372
+ if (e.byteLength > 3072) return {
373
+ ok: !1,
374
+ reason: "too-large",
375
+ detail: `${e.byteLength} bytes, the cap is ${w}`
376
+ };
377
+ let n;
378
+ try {
379
+ n = Ie.decode(e);
380
+ } catch {
381
+ return {
382
+ ok: !1,
383
+ reason: "not-utf8",
384
+ detail: "the payload is not valid UTF-8"
385
+ };
386
+ }
387
+ let r;
388
+ try {
389
+ r = JSON.parse(n);
390
+ } catch {
391
+ return {
392
+ ok: !1,
393
+ reason: "not-json",
394
+ detail: "the payload is not JSON"
395
+ };
396
+ }
397
+ return U(r, t);
398
+ }
399
+ // src/message/ownFeed.ts
400
+ var W = "swarm-chat-own-feed-v1:";
401
+ function ze(e) {
402
+ return `${W}${e}`;
403
+ }
404
+ // src/message/entry.ts
405
+ var Be = 4096, Ve = o.string().regex(/^[0-9a-f]{64}([0-9a-f]{64})?$/, "expected a 64 or 128 hex character reference"), G = o.number().int().nonnegative().max(2 ** 53 - 1), K = o.strictObject({
406
+ ref: Ve,
407
+ toSeq: G
408
+ }), q = o.strictObject({
409
+ v: o.literal(9),
410
+ seq: G,
411
+ at: G,
412
+ msg: F,
413
+ history: K.nullable()
414
+ }), J = o.strictObject({
415
+ seq: G,
416
+ at: G,
417
+ msg: F
418
+ }), Y = o.strictObject({
419
+ v: o.literal(9),
420
+ topic: o.string().min(1),
421
+ fromSeq: G,
422
+ toSeq: G,
423
+ messages: o.array(o.unknown()),
424
+ prev: K.nullable()
425
+ }).refine((e) => e.fromSeq <= e.toSeq, {
426
+ message: "fromSeq is after toSeq",
427
+ path: ["fromSeq"]
428
+ }), He = new TextDecoder("utf-8", { fatal: !0 });
429
+ function X(e) {
430
+ let t;
431
+ try {
432
+ t = He.decode(e);
433
+ } catch {
434
+ return {
435
+ ok: !1,
436
+ reason: "not-utf8",
437
+ detail: "the payload is not valid UTF-8"
438
+ };
439
+ }
440
+ try {
441
+ return {
442
+ ok: !0,
443
+ value: JSON.parse(t)
444
+ };
445
+ } catch {
446
+ return {
447
+ ok: !1,
448
+ reason: "not-json",
449
+ detail: "the payload is not JSON"
450
+ };
451
+ }
452
+ }
453
+ function Z(e) {
454
+ return e.issues.map((e) => `${e.path.join(".") || "value"}: ${e.message}`).join(", ");
455
+ }
456
+ function Ue(e, t, n) {
457
+ let r = X(e);
458
+ if (!r.ok) return r;
459
+ let i = q.safeParse(r.value);
460
+ return i.success ? i.data.seq === t ? i.data.msg.topic === n ? {
461
+ ok: !0,
462
+ value: i.data
463
+ } : {
464
+ ok: !1,
465
+ reason: "mismatch",
466
+ detail: "the message belongs to another chat"
467
+ } : {
468
+ ok: !1,
469
+ reason: "mismatch",
470
+ detail: `seq ${i.data.seq} at index ${t}`
471
+ } : {
472
+ ok: !1,
473
+ reason: "shape",
474
+ detail: Z(i.error)
475
+ };
476
+ }
477
+ function We(e, t, n) {
478
+ let r = X(e);
479
+ if (!r.ok) return r;
480
+ let i = Y.safeParse(r.value);
481
+ if (!i.success) return {
482
+ ok: !1,
483
+ reason: "shape",
484
+ detail: Z(i.error)
485
+ };
486
+ if (i.data.topic !== t || i.data.toSeq !== n.toSeq) return {
487
+ ok: !1,
488
+ reason: "mismatch",
489
+ detail: "the file is not the one its link names"
490
+ };
491
+ let { fromSeq: a, toSeq: o, prev: s } = i.data, c = [], l = 0;
492
+ for (let e of i.data.messages) {
493
+ let n = J.safeParse(e);
494
+ n.success && n.data.seq >= a && n.data.seq <= o && n.data.msg.topic === t ? c.push(n.data) : l++;
495
+ }
496
+ return {
497
+ ok: !0,
498
+ value: {
499
+ topic: t,
500
+ fromSeq: a,
501
+ toSeq: o,
502
+ rows: c,
503
+ prev: s,
504
+ skipped: l
505
+ }
506
+ };
507
+ }
508
+ // src/message/note.ts
509
+ var Ge = 1, Ke = 2e3, qe = 3e4, Je = 256, Ye = o.strictObject({
510
+ v: o.literal(1),
511
+ newest: o.number().int().min(-1).max(2 ** 53 - 1),
512
+ writtenAt: o.number().int().nonnegative().max(2 ** 53 - 1)
513
+ });
514
+ function Q(e) {
515
+ if (!Number.isInteger(e) || e <= 0) throw RangeError(`a note slot is a positive whole number of milliseconds, not ${e}`);
516
+ }
517
+ function Xe(e, t) {
518
+ return Q(t), Math.floor(e / t);
519
+ }
520
+ function Ze(e, t) {
521
+ return Q(t), (e + 1) * t;
522
+ }
523
+ function Qe(e, t, n) {
524
+ return `${e}/note/${t}/${n}`;
525
+ }
526
+ function $(e, t, r) {
527
+ return n.fromString(Qe(e, t, r));
528
+ }
529
+ function $e(n, r, a, o) {
530
+ let s = $(n, r, a);
531
+ return new i(e.keccak256(e.concat(s.toUint8Array(), new t(o).toUint8Array())));
532
+ }
533
+ var et = new TextEncoder(), tt = new TextDecoder("utf-8", { fatal: !0 });
534
+ function nt(e) {
535
+ let t = {
536
+ v: 1,
537
+ newest: e.newest,
538
+ writtenAt: e.writtenAt
539
+ };
540
+ return et.encode(JSON.stringify(t));
541
+ }
542
+ function rt(e) {
543
+ if (e.length > 256) return null;
544
+ try {
545
+ let t = Ye.safeParse(JSON.parse(tt.decode(e)));
546
+ return t.success ? t.data : null;
547
+ } catch {
548
+ return null;
549
+ }
550
+ }
551
+ export { F as A, ve as B, w as C, Ce as D, we as E, H as F, p as G, _ as H, B as I, g as J, se as K, Re as L, Le as M, Ne as N, T as O, z as P, R, I as S, Te as T, C as U, _e as V, x as W, J as _, nt as a, W as b, Qe as c, rt as d, Ye as f, K as g, Y as h, Ge as i, D as j, E as k, Ze as l, q as m, Ke as n, $e as o, Be as p, m as q, Je as r, $ as s, qe as t, Xe as u, Ue as v, Ee as w, ze as x, We as y, U as z };
@@ -0,0 +1,4 @@
1
+ let e=require("@ethersphere/bee-js"),t=require("zod"),n=require("@ethersphere/core-sdk/crypto");var r=115792089237316195423570985008687907852837564279074904382605163141518161494337n,i=r/2n;function a(e,t){let n=BigInt(`0x${e}`),a=BigInt(`0x${t}`);return n>0n&&n<r&&a>0n&&a<=i}var o=`Ethereum Signed Message:
2
+ `,s=new Set([27,28]),c=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/,l=new TextEncoder;function ee(e){let t=l.encode(e),n=l.encode(`${o}${t.length}`),r=new Uint8Array(n.length+t.length);return r.set(n),r.set(t,n.length),r}function te(e){return Array.from(e,e=>e.toString(16).padStart(2,`0`)).join(``)}function u(e,t){let r=t.slice(2,66),i=t.slice(66,130),o=parseInt(t.slice(130),16);if(!s.has(o)||!a(r,i))return null;try{let t=(0,n.recoverPublicKey)(ee(e),BigInt(`0x${r}`),BigInt(`0x${i}`),BigInt(o));return`0x${te((0,n.publicKeyToAddress)(t))}`}catch{return null}}function d(e){if(!c.test(e))return!1;let t=Date.parse(e);return!Number.isNaN(t)&&new Date(t).toISOString()===e}var f=`Swarm ID chat binding v1`,ne=512,re=`Site: `,ie=`Chat address: `,ae=`Date: `,oe=`
3
+ `,p=4,se=/^0x[0-9a-f]{40}$/,ce=/^[a-z0-9-]+(\.[a-z0-9-]+)*$/,le=new Set([`localhost`,`127.0.0.1`,`[::1]`]),m=t.z.strictObject({msg:t.z.string().max(512),sig:t.z.string().regex(/^0x[0-9a-f]{130}$/,`expected 0x and 130 lowercase hex characters`)});function ue(e,t){let n;try{n=new URL(e)}catch{return!1}let r=n.protocol===`https:`,i=t&&n.protocol===`http:`&&le.has(n.hostname);return!r&&!i||!i&&!ce.test(n.hostname)?!1:n.host!==``&&n.username===``&&n.password===``&&n.origin===e}function h(e,t){return e.startsWith(t)?e.slice(t.length):null}function g(e,t,n={}){if(!m.safeParse(e).success)return{ok:!1,detail:`not a binding of a text and a 65 byte signature`};let r=e.msg.split(oe);if(r.length!==p||r[0]!==`Swarm ID chat binding v1`)return{ok:!1,detail:`not the ${p} lines of a ${f}`};let i=h(r[1],re),a=h(r[2],ie),o=h(r[3],ae);if(i===null||!ue(i,n.allowLocalHttp===!0))return{ok:!1,detail:`the binding does not name a clean site origin`};if(a===null||!se.test(a))return{ok:!1,detail:`the binding does not name a chat address as 0x and 40 lowercase hex characters`};if(o===null||!d(o))return{ok:!1,detail:`the binding date is not ISO 8601 UTC with milliseconds`};if(a!==`0x${t}`)return{ok:!1,detail:`the binding is for another chat address than addr`};if(n.origins!==void 0&&!Array.isArray(n.origins))return{ok:!1,detail:`origins is not a list of sites`};if(n.origins!==void 0&&!n.origins.includes(i))return{ok:!1,detail:`the binding is for ${i}, not for ${n.origins.join(` or `)||`any site`}`};let s=u(e.msg,e.sig);return s===null?{ok:!1,detail:`the binding signature recovers no account`}:{ok:!0,identity:{account:s,site:i,date:o}}}var _=`Swarm ID wallet link v1`,de=`I link this wallet to the Swarm ID account below, so sites may show my ENS name beside its messages.`,fe=320,pe=`Account: `,me=`Wallet: `,he=`Date: `,ge=`
4
+ `,v=5,y=/^0x[0-9a-f]{40}$/,b=t.z.string().regex(/^0x[0-9a-f]{130}$/,`expected 0x and 130 lowercase hex characters`),x=t.z.strictObject({msg:t.z.string().max(320),wsig:b,asig:b});function S(e,t){return e.startsWith(t)?e.slice(t.length):null}function C(e,t){if(!x.safeParse(e).success)return{ok:!1,detail:`not a wallet link of a text and two 65 byte signatures`};let n=e.msg.split(ge);if(n.length!==v||n[0]!==`Swarm ID wallet link v1`)return{ok:!1,detail:`not the ${v} lines of a ${_}`};if(n[1]!==`I link this wallet to the Swarm ID account below, so sites may show my ENS name beside its messages.`)return{ok:!1,detail:`the wallet link's second line is not the ${_} statement`};let r=S(n[2],pe),i=S(n[3],me),a=S(n[4],he);return r===null||!y.test(r)?{ok:!1,detail:`the wallet link does not name an account as 0x and 40 lowercase hex characters`}:i===null||!y.test(i)?{ok:!1,detail:`the wallet link does not name a wallet as 0x and 40 lowercase hex characters`}:a===null||!d(a)?{ok:!1,detail:`the wallet link date is not ISO 8601 UTC with milliseconds`}:r===t?u(e.msg,e.wsig)===i?u(e.msg,e.asig)===r?{ok:!0,wallet:i,account:r,date:a}:{ok:!1,detail:`the account signature does not recover the account the link names`}:{ok:!1,detail:`the wallet signature does not recover the wallet the link names`}:{ok:!1,detail:`the wallet link is for ${r}, not the binding's account ${t}`}}var _e=9,w=3072,ve=128,ye=500,be=20,T={TEXT:`text`,THREAD:`thread`,REACTION:`reaction`},E={GATEWAY:`gateway`,OWN_STAMP:`own-stamp`};function D(e){let t=0;for(let n of e)t++;return t}function O(e){return t.z.string().regex(RegExp(`^[0-9a-f]{${e}}$`),`expected ${e} lowercase hex characters`)}function k(e,n){return t.z.string().refine(t=>{let r=D(t);return r>=e&&r<=n},`expected ${e} to ${n} characters`)}var A=/(?![\u200c\u200d])[\p{Cf}\p{Cc}\u2800\u115f\u1160\u3164\uffa0]|\u034f|\u17b4|\u17b5/u,xe=/[\p{Default_Ignorable_Code_Point}\p{Mn}\p{Me}\u2800]/gu,j=Object.fromEntries([...[...`℮ꬲеҽ⋿ΕЕⴹᎬꗋꓰ𑢦𑢮𐊆𝾁`].map(e=>[e,`e`]),...[...`⊤⟙🝨𝍳ΤⲦТтߠᎢꔋㄒꓔ𖼊𑢼𐊗𐊱𐌕丅`].map(e=>[e,`t`]),...[...`һҺႹհᏂΗⲎНнᎻᕼꓧ𐋏`].map(e=>[e,`h`])]),Se=RegExp(`[${Object.keys(j).join(``)}]`,`gu`),Ce=/[\u3002\u0660\u06f0\u0701\u0702\ua4f8\ua60e\uabec\u{10a50}\u{1d16d}\u{1ecae}]/gu,we=/[\p{Z}.]+$/u,M=`.eth`;function Te(e){return e.normalize(`NFKD`).replace(Ce,`.`).replace(xe,``).replace(Se,e=>j[e]??e).toLowerCase().trim().replace(we,``)}function N(e){return Te(e).endsWith(M)}function Ee(e,t){return k(e,t).refine(e=>!A.test(e),`expected no format or control characters`).refine(e=>!N(e),`expected a name not ending in ${M}, which ENS names keep`)}function De(e){let t=D(e);return t<1||t>20?`length`:A.test(e)?`invisible`:N(e)?`ens-like`:null}var P=O(32),F=t.z.strictObject({v:t.z.literal(9),topic:k(1,128),id:P,type:t.z.enum([T.TEXT,T.THREAD,T.REACTION]),target:t.z.union([t.z.literal(``),P]),text:k(1,500),name:Ee(1,20),addr:O(40),ts:t.z.number().int().nonnegative().max(2**53-1),via:t.z.enum([E.GATEWAY,E.OWN_STAMP]),idb:m.optional(),wl:x.optional(),sig:O(130)}).refine(e=>e.type===T.TEXT==(e.target===``),{message:`a text message has no target, a thread reply or a reaction names one`,path:[`target`]}).refine(e=>e.wl===void 0||e.idb!==void 0,{message:`a wallet link is carried only beside a chat binding, whose account it names`,path:[`wl`]}),I=class extends Error{constructor(e,t){super(`chat message refused (${e}): ${t}`),this.reason=e,this.name=`ChatMessageError`}},L=new TextEncoder,Oe=`1b`,ke=`1c`,Ae=new TextDecoder(`utf-8`,{fatal:!0});function R(e){return L.encode(JSON.stringify([e.v,e.topic,e.id,e.type,e.target,e.text,e.name,e.addr,e.ts,e.via,e.idb?.msg??``,e.idb?.sig??``,...e.wl?[e.wl.msg,e.wl.wsig,e.wl.asig]:[]]))}function z(e){let t={v:e.v,topic:e.topic,id:e.id,type:e.type,target:e.target,text:e.text,name:e.name,addr:e.addr,ts:e.ts,via:e.via,...e.idb?{idb:{msg:e.idb.msg,sig:e.idb.sig}}:{},...e.wl?{wl:{msg:e.wl.msg,wsig:e.wl.wsig,asig:e.wl.asig}}:{},sig:e.sig};return L.encode(JSON.stringify(t))}function B(){let e=crypto.getRandomValues(new Uint8Array(16));return Array.from(e,e=>e.toString(16).padStart(2,`0`)).join(``)}function V(e){return e.issues.map(e=>`${e.path.join(`.`)||`message`}: ${e.message}`).join(`, `)}function je(t,n){let r=t instanceof e.PrivateKey?t:new e.PrivateKey(t),i={v:9,topic:n.topic,id:n.id??B(),type:n.type,target:n.target??``,text:n.text,name:n.name,addr:r.publicKey().address().toHex(),ts:n.ts??Date.now(),via:n.via,...n.idb?{idb:n.idb}:{},...n.wl?{wl:n.wl}:{}},a={...i,sig:`0`.repeat(130)},o=F.safeParse(a);if(!o.success)throw new I(`shape`,V(o.error));let s=z(a).byteLength;if(s>3072)throw new I(`too-large`,`${s} bytes, the cap is ${w}`);if(i.idb){let e=g(i.idb,i.addr,{allowLocalHttp:!0});if(!e.ok)throw new I(`binding`,e.detail);if(i.wl){let t=C(i.wl,e.identity.account);if(!t.ok)throw new I(`binding`,`wallet link: ${t.detail}`)}}let c={...i,sig:r.sign(R(i)).toHex()};return{message:c,bytes:z(c)}}function H(t){let n=t.sig.slice(128);if(n!==Oe&&n!==ke||!a(t.sig.slice(0,64),t.sig.slice(64,128)))return!1;try{return new e.Signature(t.sig).recoverPublicKey(R(t)).address().toHex()===t.addr}catch{return!1}}function U(e,t){let n=F.safeParse(e);if(!n.success)return{ok:!1,reason:`shape`,detail:V(n.error)};let r=n.data;if(!H(r))return{ok:!1,reason:`signature`,detail:`the signature was not made by addr over these fields`};if(!r.idb)return{ok:!0,message:r,identity:null};if(!Array.isArray(t?.origins))return{ok:!1,reason:`binding`,detail:`no origins were given to check the binding against`};let i=g(r.idb,r.addr,t);if(!i.ok)return{ok:!1,reason:`binding`,detail:i.detail};if(!r.wl)return{ok:!0,message:r,identity:i.identity};let a=C(r.wl,i.identity.account);return a.ok?{ok:!0,message:r,identity:{...i.identity,wallet:a.wallet}}:{ok:!1,reason:`binding`,detail:`wallet link: ${a.detail}`}}function Me(e,t){if(e.byteLength>3072)return{ok:!1,reason:`too-large`,detail:`${e.byteLength} bytes, the cap is ${w}`};let n;try{n=Ae.decode(e)}catch{return{ok:!1,reason:`not-utf8`,detail:`the payload is not valid UTF-8`}}let r;try{r=JSON.parse(n)}catch{return{ok:!1,reason:`not-json`,detail:`the payload is not JSON`}}return U(r,t)}var W=`swarm-chat-own-feed-v1:`;function Ne(e){return`${W}${e}`}var Pe=4096,Fe=t.z.string().regex(/^[0-9a-f]{64}([0-9a-f]{64})?$/,`expected a 64 or 128 hex character reference`),G=t.z.number().int().nonnegative().max(2**53-1),K=t.z.strictObject({ref:Fe,toSeq:G}),q=t.z.strictObject({v:t.z.literal(9),seq:G,at:G,msg:F,history:K.nullable()}),J=t.z.strictObject({seq:G,at:G,msg:F}),Y=t.z.strictObject({v:t.z.literal(9),topic:t.z.string().min(1),fromSeq:G,toSeq:G,messages:t.z.array(t.z.unknown()),prev:K.nullable()}).refine(e=>e.fromSeq<=e.toSeq,{message:`fromSeq is after toSeq`,path:[`fromSeq`]}),Ie=new TextDecoder(`utf-8`,{fatal:!0});function X(e){let t;try{t=Ie.decode(e)}catch{return{ok:!1,reason:`not-utf8`,detail:`the payload is not valid UTF-8`}}try{return{ok:!0,value:JSON.parse(t)}}catch{return{ok:!1,reason:`not-json`,detail:`the payload is not JSON`}}}function Z(e){return e.issues.map(e=>`${e.path.join(`.`)||`value`}: ${e.message}`).join(`, `)}function Le(e,t,n){let r=X(e);if(!r.ok)return r;let i=q.safeParse(r.value);return i.success?i.data.seq===t?i.data.msg.topic===n?{ok:!0,value:i.data}:{ok:!1,reason:`mismatch`,detail:`the message belongs to another chat`}:{ok:!1,reason:`mismatch`,detail:`seq ${i.data.seq} at index ${t}`}:{ok:!1,reason:`shape`,detail:Z(i.error)}}function Re(e,t,n){let r=X(e);if(!r.ok)return r;let i=Y.safeParse(r.value);if(!i.success)return{ok:!1,reason:`shape`,detail:Z(i.error)};if(i.data.topic!==t||i.data.toSeq!==n.toSeq)return{ok:!1,reason:`mismatch`,detail:`the file is not the one its link names`};let{fromSeq:a,toSeq:o,prev:s}=i.data,c=[],l=0;for(let e of i.data.messages){let n=J.safeParse(e);n.success&&n.data.seq>=a&&n.data.seq<=o&&n.data.msg.topic===t?c.push(n.data):l++}return{ok:!0,value:{topic:t,fromSeq:a,toSeq:o,rows:c,prev:s,skipped:l}}}var ze=1,Be=2e3,Ve=3e4,He=256,Q=t.z.strictObject({v:t.z.literal(1),newest:t.z.number().int().min(-1).max(2**53-1),writtenAt:t.z.number().int().nonnegative().max(2**53-1)});function $(e){if(!Number.isInteger(e)||e<=0)throw RangeError(`a note slot is a positive whole number of milliseconds, not ${e}`)}function Ue(e,t){return $(t),Math.floor(e/t)}function We(e,t){return $(t),(e+1)*t}function Ge(e,t,n){return`${e}/note/${t}/${n}`}function Ke(t,n,r){return e.Identifier.fromString(Ge(t,n,r))}function qe(t,n,r,i){let a=Ke(t,n,r);return new e.Reference(e.Bytes.keccak256(e.Bytes.concat(a.toUint8Array(),new e.EthAddress(i).toUint8Array())))}var Je=new TextEncoder,Ye=new TextDecoder(`utf-8`,{fatal:!0});function Xe(e){let t={v:1,newest:e.newest,writtenAt:e.writtenAt};return Je.encode(JSON.stringify(t))}function Ze(e){if(e.length>256)return null;try{let t=Q.safeParse(JSON.parse(Ye.decode(e)));return t.success?t.data:null}catch{return null}}Object.defineProperty(exports,"A",{enumerable:!0,get:function(){return F}}),Object.defineProperty(exports,"B",{enumerable:!0,get:function(){return fe}}),Object.defineProperty(exports,"C",{enumerable:!0,get:function(){return w}}),Object.defineProperty(exports,"D",{enumerable:!0,get:function(){return _e}}),Object.defineProperty(exports,"E",{enumerable:!0,get:function(){return ve}}),Object.defineProperty(exports,"F",{enumerable:!0,get:function(){return H}}),Object.defineProperty(exports,"G",{enumerable:!0,get:function(){return f}}),Object.defineProperty(exports,"H",{enumerable:!0,get:function(){return _}}),Object.defineProperty(exports,"I",{enumerable:!0,get:function(){return B}}),Object.defineProperty(exports,"J",{enumerable:!0,get:function(){return g}}),Object.defineProperty(exports,"K",{enumerable:!0,get:function(){return ne}}),Object.defineProperty(exports,"L",{enumerable:!0,get:function(){return Me}}),Object.defineProperty(exports,"M",{enumerable:!0,get:function(){return je}}),Object.defineProperty(exports,"N",{enumerable:!0,get:function(){return De}}),Object.defineProperty(exports,"O",{enumerable:!0,get:function(){return T}}),Object.defineProperty(exports,"P",{enumerable:!0,get:function(){return z}}),Object.defineProperty(exports,"R",{enumerable:!0,get:function(){return R}}),Object.defineProperty(exports,"S",{enumerable:!0,get:function(){return I}}),Object.defineProperty(exports,"T",{enumerable:!0,get:function(){return ye}}),Object.defineProperty(exports,"U",{enumerable:!0,get:function(){return C}}),Object.defineProperty(exports,"V",{enumerable:!0,get:function(){return de}}),Object.defineProperty(exports,"W",{enumerable:!0,get:function(){return x}}),Object.defineProperty(exports,"_",{enumerable:!0,get:function(){return J}}),Object.defineProperty(exports,"a",{enumerable:!0,get:function(){return Xe}}),Object.defineProperty(exports,"b",{enumerable:!0,get:function(){return W}}),Object.defineProperty(exports,"c",{enumerable:!0,get:function(){return Ge}}),Object.defineProperty(exports,"d",{enumerable:!0,get:function(){return Ze}}),Object.defineProperty(exports,"f",{enumerable:!0,get:function(){return Q}}),Object.defineProperty(exports,"g",{enumerable:!0,get:function(){return K}}),Object.defineProperty(exports,"h",{enumerable:!0,get:function(){return Y}}),Object.defineProperty(exports,"i",{enumerable:!0,get:function(){return ze}}),Object.defineProperty(exports,"j",{enumerable:!0,get:function(){return D}}),Object.defineProperty(exports,"k",{enumerable:!0,get:function(){return E}}),Object.defineProperty(exports,"l",{enumerable:!0,get:function(){return We}}),Object.defineProperty(exports,"m",{enumerable:!0,get:function(){return q}}),Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return Be}}),Object.defineProperty(exports,"o",{enumerable:!0,get:function(){return qe}}),Object.defineProperty(exports,"p",{enumerable:!0,get:function(){return Pe}}),Object.defineProperty(exports,"q",{enumerable:!0,get:function(){return m}}),Object.defineProperty(exports,"r",{enumerable:!0,get:function(){return He}}),Object.defineProperty(exports,"s",{enumerable:!0,get:function(){return Ke}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return Ve}}),Object.defineProperty(exports,"u",{enumerable:!0,get:function(){return Ue}}),Object.defineProperty(exports,"v",{enumerable:!0,get:function(){return Le}}),Object.defineProperty(exports,"w",{enumerable:!0,get:function(){return be}}),Object.defineProperty(exports,"x",{enumerable:!0,get:function(){return Ne}}),Object.defineProperty(exports,"y",{enumerable:!0,get:function(){return Re}}),Object.defineProperty(exports,"z",{enumerable:!0,get:function(){return U}});
package/dist/message.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./message-Bmwh3SCs.cjs");exports.CHAT_BINDING_TITLE=e.z,exports.ChatMessageError=e.S,exports.DEFAULT_NOTE_HEARTBEAT_MS=e.t,exports.DEFAULT_NOTE_SLOT_MS=e.n,exports.MAX_BINDING_CHARACTERS=e.B,exports.MAX_ENTRY_BYTES=e.p,exports.MAX_MESSAGE_BYTES=e.C,exports.MAX_NAME_CHARACTERS=e.w,exports.MAX_NOTE_BYTES=e.r,exports.MAX_TEXT_CHARACTERS=e.T,exports.MAX_TOPIC_CHARACTERS=e.E,exports.MESSAGE_VERSION=e.D,exports.MessageType=e.O,exports.MessageVia=e.k,exports.NOTE_VERSION=e.i,exports.OWN_FEED_TOPIC_PREFIX=e.b,exports.chatBindingSchema=e.V,exports.chatMessageSchema=e.A,exports.checkChatBinding=e.H,exports.countCharacters=e.j,exports.createChatMessage=e.M,exports.encodeChatMessage=e.N,exports.encodeSlotNote=e.a,exports.feedEntrySchema=e.m,exports.hasValidSignature=e.P,exports.historyFileSchema=e.h,exports.historyLinkSchema=e.g,exports.historyRowSchema=e._,exports.newMessageId=e.F,exports.noteAddress=e.o,exports.noteIdentifier=e.s,exports.noteIdentifierText=e.c,exports.noteSlotEnd=e.l,exports.noteSlotOf=e.u,exports.ownFeedTopic=e.x,exports.parseChatMessage=e.I,exports.parseFeedEntry=e.v,exports.parseHistoryFile=e.y,exports.parseSlotNote=e.d,exports.signedBytes=e.L,exports.slotNoteSchema=e.f,exports.verifyChatMessage=e.R;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./message-BjeTRy2F.cjs");exports.CHAT_BINDING_TITLE=e.G,exports.ChatMessageError=e.S,exports.DEFAULT_NOTE_HEARTBEAT_MS=e.t,exports.DEFAULT_NOTE_SLOT_MS=e.n,exports.MAX_BINDING_CHARACTERS=e.K,exports.MAX_ENTRY_BYTES=e.p,exports.MAX_MESSAGE_BYTES=e.C,exports.MAX_NAME_CHARACTERS=e.w,exports.MAX_NOTE_BYTES=e.r,exports.MAX_TEXT_CHARACTERS=e.T,exports.MAX_TOPIC_CHARACTERS=e.E,exports.MAX_WALLET_LINK_CHARACTERS=e.B,exports.MESSAGE_VERSION=e.D,exports.MessageType=e.O,exports.MessageVia=e.k,exports.NOTE_VERSION=e.i,exports.OWN_FEED_TOPIC_PREFIX=e.b,exports.WALLET_LINK_STATEMENT=e.V,exports.WALLET_LINK_TITLE=e.H,exports.chatBindingSchema=e.q,exports.chatMessageSchema=e.A,exports.checkChatBinding=e.J,exports.checkWalletLink=e.U,exports.countCharacters=e.j,exports.createChatMessage=e.M,exports.displayNameProblem=e.N,exports.encodeChatMessage=e.P,exports.encodeSlotNote=e.a,exports.feedEntrySchema=e.m,exports.hasValidSignature=e.F,exports.historyFileSchema=e.h,exports.historyLinkSchema=e.g,exports.historyRowSchema=e._,exports.newMessageId=e.I,exports.noteAddress=e.o,exports.noteIdentifier=e.s,exports.noteIdentifierText=e.c,exports.noteSlotEnd=e.l,exports.noteSlotOf=e.u,exports.ownFeedTopic=e.x,exports.parseChatMessage=e.L,exports.parseFeedEntry=e.v,exports.parseHistoryFile=e.y,exports.parseSlotNote=e.d,exports.signedBytes=e.R,exports.slotNoteSchema=e.f,exports.verifyChatMessage=e.z,exports.walletLinkSchema=e.W;
package/dist/message.js CHANGED
@@ -1,2 +1 @@
1
- import { A as e, B as t, C as n, D as r, E as i, F as a, H as o, I as s, L as c, M as l, N as u, O as d, P as f, R as p, S as m, T as h, V as g, _, a as v, b as y, c as b, d as x, f as S, g as C, h as w, i as T, j as E, k as D, l as O, m as k, n as A, o as j, p as M, r as N, s as P, t as F, u as I, v as L, w as R, x as z, y as B, z as V } from "./message-Dbh8qrpg.js";
2
- export { V as CHAT_BINDING_TITLE, m as ChatMessageError, F as DEFAULT_NOTE_HEARTBEAT_MS, A as DEFAULT_NOTE_SLOT_MS, t as MAX_BINDING_CHARACTERS, M as MAX_ENTRY_BYTES, n as MAX_MESSAGE_BYTES, R as MAX_NAME_CHARACTERS, N as MAX_NOTE_BYTES, h as MAX_TEXT_CHARACTERS, i as MAX_TOPIC_CHARACTERS, r as MESSAGE_VERSION, d as MessageType, D as MessageVia, T as NOTE_VERSION, y as OWN_FEED_TOPIC_PREFIX, g as chatBindingSchema, e as chatMessageSchema, o as checkChatBinding, E as countCharacters, l as createChatMessage, u as encodeChatMessage, v as encodeSlotNote, k as feedEntrySchema, f as hasValidSignature, w as historyFileSchema, C as historyLinkSchema, _ as historyRowSchema, a as newMessageId, j as noteAddress, P as noteIdentifier, b as noteIdentifierText, O as noteSlotEnd, I as noteSlotOf, z as ownFeedTopic, s as parseChatMessage, L as parseFeedEntry, B as parseHistoryFile, x as parseSlotNote, c as signedBytes, S as slotNoteSchema, p as verifyChatMessage };
1
+ export { G as CHAT_BINDING_TITLE, S as ChatMessageError, t as DEFAULT_NOTE_HEARTBEAT_MS, n as DEFAULT_NOTE_SLOT_MS, K as MAX_BINDING_CHARACTERS, p as MAX_ENTRY_BYTES, C as MAX_MESSAGE_BYTES, w as MAX_NAME_CHARACTERS, r as MAX_NOTE_BYTES, T as MAX_TEXT_CHARACTERS, E as MAX_TOPIC_CHARACTERS, B as MAX_WALLET_LINK_CHARACTERS, D as MESSAGE_VERSION, O as MessageType, k as MessageVia, i as NOTE_VERSION, b as OWN_FEED_TOPIC_PREFIX, V as WALLET_LINK_STATEMENT, H as WALLET_LINK_TITLE, q as chatBindingSchema, A as chatMessageSchema, J as checkChatBinding, U as checkWalletLink, j as countCharacters, M as createChatMessage, N as displayNameProblem, P as encodeChatMessage, a as encodeSlotNote, m as feedEntrySchema, F as hasValidSignature, h as historyFileSchema, g as historyLinkSchema, _ as historyRowSchema, I as newMessageId, o as noteAddress, s as noteIdentifier, c as noteIdentifierText, l as noteSlotEnd, u as noteSlotOf, x as ownFeedTopic, L as parseChatMessage, v as parseFeedEntry, y as parseHistoryFile, d as parseSlotNote, R as signedBytes, f as slotNoteSchema, z as verifyChatMessage, W as walletLinkSchema } from "./message-BUFAxjtN.js";
package/dist/pacer.d.ts CHANGED
@@ -5,7 +5,7 @@
5
5
  * chunk for a minute (`ethersphere/bee`, `pkg/retrieval/retrieval.go`, `errSkip` and `skiplistDur = time.Minute`).
6
6
  * Once no peer is left it answers 500 at once, because "no peer left" is not `storage.ErrNotFound`
7
7
  * (`pkg/api/chunk.go`). A chunk written while its address is on that list stays unreadable on that node for up to a
8
- * minute. Measured on swarm-dev on 2026-10-12: an address read every second for 20 s and then written was readable
8
+ * minute. Measured on a test node on 2026-10-12: an address read every second for 20 s and then written was readable
9
9
  * after 33 to 36 s, one nobody had asked for at once. About four reads of a missing address exhaust the list, so one
10
10
  * read every twenty seconds stays under it.
11
11
  */
package/dist/sender.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { PrivateKey } from '@ethersphere/bee-js';
2
- import { type ChatBinding, type ChatMessage, type ChatMessageDraft, type MessageVia } from './message/index.js';
2
+ import { type ChatBinding, type ChatMessage, type ChatMessageDraft, type MessageVia, type WalletLink } from './message/index.js';
3
3
  /** Writes one payload to the chat's GSOC address. Rejects when the write did not reach the node. */
4
4
  export type GsocWrite = (payload: Uint8Array) => Promise<void>;
5
5
  export interface SenderSettings {
@@ -26,18 +26,15 @@ export interface SenderEvents {
26
26
  /** Read back from the chat feed. */
27
27
  confirmed(message: ChatMessage): void;
28
28
  }
29
- export type SendDraft = Omit<ChatMessageDraft, 'name' | 'ts' | 'id' | 'via' | 'own' | 'idb'>;
29
+ export type SendDraft = Omit<ChatMessageDraft, 'name' | 'ts' | 'id' | 'via' | 'idb' | 'wl'>;
30
30
  /** What every message this sender signs says about who sent it and how. */
31
31
  export interface SenderProfile {
32
32
  name: string;
33
33
  via: MessageVia;
34
34
  /** The sender's Swarm ID chat binding, for a signed-in sender only. */
35
35
  idb?: ChatBinding;
36
- /**
37
- * Whether the sender keeps a copy of every message in its own feed, false when left out. The library writes no copy:
38
- * the `GsocWrite` that keeps one stores it from the payload it is handed, before or after the inbox write.
39
- */
40
- own?: boolean;
36
+ /** The sender's Swarm ID wallet link, beside `idb`, for a sender who shows an ENS name. */
37
+ wl?: WalletLink;
41
38
  }
42
39
  /**
43
40
  * Sends signed messages as GSOC writes and keeps each one pending until the chat feed shows it. A pending message is
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solarpunkltd/swarm-chat-js",
3
- "version": "8.1.0",
3
+ "version": "10.0.0",
4
4
  "description": "JS library for chatting on Swarm",
5
5
  "keywords": [
6
6
  "chat",
@@ -11,7 +11,7 @@
11
11
  "url": "https://github.com/Solar-Punk-Ltd/swarm-chat-js/issues"
12
12
  },
13
13
  "license": "Apache-2.0",
14
- "author": "levente.kiss@solarpunk.buzz",
14
+ "author": "Solar Punk Ltd",
15
15
  "repository": {
16
16
  "type": "git",
17
17
  "url": "git+https://github.com/Solar-Punk-Ltd/swarm-chat-js"
@@ -56,7 +56,7 @@
56
56
  "oxlint": "1.83.0",
57
57
  "oxlint-tsgolint": "7.0.2001",
58
58
  "typescript": "7.0.2",
59
- "vite": "8.3.0",
59
+ "vite": "8.3.3",
60
60
  "vitest": "5.0.1"
61
61
  },
62
62
  "peerDependencies": {