@solarpunkltd/swarm-chat-js 7.3.0 → 8.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/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
- import { ChatMessageError as e, DEFAULT_NOTE_HEARTBEAT_MS as t, DEFAULT_NOTE_SLOT_MS as n, MAX_ENTRY_BYTES as r, MAX_MESSAGE_BYTES as i, MAX_NAME_CHARACTERS as a, MAX_NOTE_BYTES as o, MAX_TEXT_CHARACTERS as s, MAX_TOPIC_CHARACTERS as c, MESSAGE_VERSION as l, MessageType as u, NOTE_VERSION as d, chatMessageSchema as f, checkChatMessage as p, countCharacters as m, createChatMessage as h, encodeChatMessage as g, encodeSlotNote as _, feedEntrySchema as ee, hasValidSignature as te, historyFileSchema as ne, historyLinkSchema as v, historyRowSchema as y, newMessageId as b, noteAddress as x, noteIdentifier as S, noteIdentifierText as re, noteSlotEnd as C, noteSlotOf as w, parseChatMessage as T, parseFeedEntry as E, parseHistoryFile as D, parseSlotNote as O, signedBytes as k, slotNoteSchema as A } from "./message.js";
2
- import { Bee as j, BeeResponseError as M, Identifier as ie, PrivateKey as N, Topic as P } from "@ethersphere/bee-js";
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 ee, O as u, P as d, R as f, S as p, T as m, V as te, _ as ne, a as re, b as ie, c as h, d as g, f as _, g as v, h as y, i as ae, j as oe, k as b, l as x, m as S, n as C, o as w, p as T, r as E, s as D, t as O, u as k, v as A, w as se, x as ce, y as j, z as M } from "./message-Dbh8qrpg.js";
2
+ import { Bee as N, BeeResponseError as P, Identifier as F, PrivateKey as I, Topic as L } from "@ethersphere/bee-js";
3
3
  //#region src/events.ts
4
- var F = {
4
+ var R = {
5
5
  LOADING_INIT: "loadingInit",
6
6
  LOADING_PREVIOUS_MESSAGES: "loadingPreviousMessages",
7
7
  MESSAGE_RECEIVED: "messageReceived",
@@ -13,13 +13,13 @@ var F = {
13
13
  MESSAGE_SKIPPED: "messageSkipped",
14
14
  ERROR: "error"
15
15
  };
16
- function I(e) {
17
- return R(e, -1, e.ts);
16
+ function z(e) {
17
+ return V(e, -1, e.ts);
18
18
  }
19
- function L(e) {
20
- return R(e.msg, e.seq, e.at);
19
+ function B(e) {
20
+ return V(e.msg, e.seq, e.at);
21
21
  }
22
- function R(e, t, n) {
22
+ function V(e, t, n) {
23
23
  return {
24
24
  id: e.id,
25
25
  type: e.type,
@@ -28,13 +28,11 @@ function R(e, t, n) {
28
28
  address: e.addr,
29
29
  timestamp: n,
30
30
  ...e.target ? { targetMessageId: e.target } : {},
31
- chatTopic: e.topic,
32
- signature: e.sig,
33
31
  index: t,
34
- sentAt: e.ts
32
+ signedMessage: e
35
33
  };
36
34
  }
37
- var z = class {
35
+ var H = class {
38
36
  constructor() {
39
37
  this.listeners = /* @__PURE__ */ new Map(), this.on = (e, t) => {
40
38
  this.listeners.set(e, [...this.listeners.get(e) ?? [], t]);
@@ -51,7 +49,7 @@ var z = class {
51
49
  console.error(`a listener for ${e} threw`, t);
52
50
  }
53
51
  }
54
- }, B = 2e4, V = class {
52
+ }, U = 2e4, W = class {
55
53
  constructor(e, t) {
56
54
  this.spacingMs = e, this.now = t, this.missedAt = /* @__PURE__ */ new Map();
57
55
  }
@@ -75,68 +73,68 @@ var z = class {
75
73
  expired(e, t) {
76
74
  return e > t || t - e >= this.spacingMs;
77
75
  }
78
- }, H = class extends Error {
76
+ }, G = class extends Error {
79
77
  constructor(e) {
80
78
  super("the feed head lookup did not answer in time", e), this.name = "HeadLookupTimeoutError";
81
79
  }
82
- }, U = class extends Error {
80
+ }, K = class extends Error {
83
81
  constructor(e, t) {
84
82
  super(`feed slot ${e} was served but could not be read`, t), this.index = e, this.name = "UnreadableSlotError";
85
83
  }
86
84
  };
87
- function W(e) {
88
- return e instanceof M && (e.status === 404 || e.status === 500);
85
+ function q(e) {
86
+ return e instanceof P && (e.status === 404 || e.status === 500);
89
87
  }
90
- async function G(e, t) {
88
+ async function J(e, t) {
91
89
  try {
92
90
  return await t();
93
91
  } catch (t) {
94
- if (W(t)) return null;
95
- throw t instanceof M ? t : new U(e, { cause: t });
92
+ if (q(t)) return null;
93
+ throw t instanceof P ? t : new K(e, { cause: t });
96
94
  }
97
95
  }
98
- function K(e, t, r, i, a = n) {
99
- let o = P.fromString(r), s = (n) => e.feed.makeReader(o, t, q(n));
96
+ function le(e, t, n, r, i = C) {
97
+ let a = L.fromString(n), o = (n) => e.feed.makeReader(a, t, Y(n));
100
98
  return {
101
- readNote: (n) => G(n, async () => (await e.soc.makeReader(t, q(i.slotReadMs)).download(S(r, a, n))).payload.toUint8Array()),
102
- readSlot: (e) => G(e, async () => (await s(i.slotReadMs).downloadPayload({ index: e })).payload.toUint8Array()),
99
+ readNote: (a) => J(a, async () => (await e.soc.makeReader(t, Y(r.slotReadMs)).download(D(n, i, a))).payload.toUint8Array()),
100
+ readSlot: (e) => J(e, async () => (await o(r.slotReadMs).downloadPayload({ index: e })).payload.toUint8Array()),
103
101
  async readHead() {
104
- let n = q(i.feedReadMs);
102
+ let n = Y(r.feedReadMs);
105
103
  try {
106
- let { payload: r, feedIndex: i } = await e.feed.makeReader(o, t, n).downloadPayload();
104
+ let { payload: r, feedIndex: i } = await e.feed.makeReader(a, t, n).downloadPayload();
107
105
  return {
108
106
  index: Number(i.toBigInt()),
109
107
  payload: r.toUint8Array()
110
108
  };
111
109
  } catch (e) {
112
- if (W(e)) return null;
113
- throw n.signal?.aborted ? new H({ cause: e }) : e;
110
+ if (q(e)) return null;
111
+ throw n.signal?.aborted ? new G({ cause: e }) : e;
114
112
  }
115
113
  },
116
114
  async readFile(t) {
117
- return (await e.data.download(t, void 0, q(i.feedReadMs))).toUint8Array();
115
+ return (await e.data.download(t, void 0, Y(r.feedReadMs))).toUint8Array();
118
116
  }
119
117
  };
120
118
  }
121
- function q(e) {
119
+ function Y(e) {
122
120
  return { signal: AbortSignal.timeout(e) };
123
121
  }
124
- var ae = "0123456789abcdef".repeat(4);
125
- function J(e, t, n, r, i) {
126
- let a = new N(n), o = ie.fromString(r);
122
+ var ue = "0123456789abcdef".repeat(4);
123
+ function de(e, t, n, r, i) {
124
+ let a = new I(n), o = F.fromString(r);
127
125
  return async (n) => {
128
- await e.messaging.gsocSend(t, a, o, n, { deferred: !1 }, q(i.writeMs));
126
+ await e.messaging.gsocSend(t, a, o, n, { deferred: !1 }, Y(i.writeMs));
129
127
  };
130
128
  }
131
129
  //#endregion
132
130
  //#region src/follower.ts
133
- var Y = {
131
+ var X = {
134
132
  LIVE: "live",
135
133
  RECONNECTING: "reconnecting",
136
134
  STALLED: "stalled"
137
- }, oe = {
135
+ }, fe = {
138
136
  pollIntervalMs: 1e3,
139
- missingReadSpacingMs: B,
137
+ missingReadSpacingMs: U,
140
138
  maxSlotsPerPoll: 16,
141
139
  unservedPollsBeforeProbe: 3,
142
140
  unreadablePollsBeforeFailure: 3,
@@ -154,16 +152,16 @@ var Y = {
154
152
  stallAfterMs: 8e3,
155
153
  random: Math.random,
156
154
  now: Date.now
157
- }, X = class extends Error {
155
+ }, Z = class extends Error {
158
156
  constructor(e) {
159
157
  super(`the gateway keeps answering feed slot ${e} with something that is not a chunk`), this.index = e, this.name = "UnreadableGatewayError";
160
158
  }
161
- }, se = class {
159
+ }, pe = class {
162
160
  constructor(e, t, n, r = {}, i = null) {
163
161
  this.source = e, this.topic = t, this.events = n, this.notes = i, this.next = 0, this.ceiling = null, this.nextNoteSlot = 0, this.lastNoteFoundAt = 0, this.unservedPolls = 0, this.nextProbeAt = 0, this.unreadablePolls = 0, this.gatewayFailures = 0, this.missed = /* @__PURE__ */ new Map(), this.timer = null, this.generation = 0, this.running = !1, this.status = null, this.settings = {
164
- ...oe,
162
+ ...fe,
165
163
  ...r
166
- }, this.pacer = new V(this.settings.missingReadSpacingMs, this.settings.now);
164
+ }, this.pacer = new W(this.settings.missingReadSpacingMs, this.settings.now);
167
165
  }
168
166
  get nextIndex() {
169
167
  return this.next;
@@ -225,7 +223,7 @@ var Y = {
225
223
  try {
226
224
  t = await this.source.readSlot(e);
227
225
  } catch (e) {
228
- if (e instanceof U) return "unreadable";
226
+ if (e instanceof K) return "unreadable";
229
227
  throw e;
230
228
  }
231
229
  return t === null ? this.pacer.missed(e) : this.pacer.found(e), t;
@@ -249,7 +247,7 @@ var Y = {
249
247
  this.unreadablePolls = 0;
250
248
  continue;
251
249
  }
252
- if (this.unreadablePolls >= this.settings.unreadablePollsBeforeFailure) throw new X(n);
250
+ if (this.unreadablePolls >= this.settings.unreadablePollsBeforeFailure) throw new Z(n);
253
251
  }
254
252
  return t;
255
253
  }
@@ -305,16 +303,16 @@ var Y = {
305
303
  }
306
304
  }
307
305
  accept(e, t) {
308
- let n = E(t, e, this.topic);
306
+ let n = A(t, e, this.topic);
309
307
  n.ok ? (this.notes?.clock.observe(n.value.at, this.settings.now()), this.events.entry(n.value)) : this.events.skipped(e, n.reason, n.detail);
310
308
  }
311
309
  gatewayFailed(e) {
312
- this.gatewayFailures++, this.setStatus(Y.RECONNECTING), this.events.error(e);
310
+ this.gatewayFailures++, this.setStatus(X.RECONNECTING), this.events.error(e);
313
311
  }
314
312
  gatewayAnswered() {
315
313
  this.gatewayFailures = 0;
316
314
  let e = this.settings.now(), t = [...this.missed.values()].some((t) => e - t >= this.settings.stallAfterMs);
317
- this.setStatus(t ? Y.STALLED : Y.LIVE);
315
+ this.setStatus(t ? X.STALLED : X.LIVE);
318
316
  }
319
317
  backoffMs() {
320
318
  let { pollIntervalMs: e, backoffCapMs: t, random: n } = this.settings, r = Math.min(t, e * 2 ** this.gatewayFailures);
@@ -323,7 +321,7 @@ var Y = {
323
321
  setStatus(e) {
324
322
  e !== this.status && (this.status = e, this.events.status(e));
325
323
  }
326
- }, ce = 16, le = class {
324
+ }, me = 16, he = class {
327
325
  constructor(e, t, n, r = null) {
328
326
  this.source = e, this.topic = t, this.events = n, this.notes = r, this.older = null, this.loading = null;
329
327
  }
@@ -368,7 +366,7 @@ var Y = {
368
366
  try {
369
367
  return await this.source.readHead();
370
368
  } catch (e) {
371
- if (e instanceof H) return this.events.error(e), null;
369
+ if (e instanceof G) return this.events.error(e), null;
372
370
  throw e;
373
371
  }
374
372
  }
@@ -383,30 +381,30 @@ var Y = {
383
381
  async loadOlderOnce() {
384
382
  let e = this.older;
385
383
  if (e === null) return [];
386
- let t = await this.source.readFile(e.ref), n = D(t, this.topic, e);
384
+ let t = await this.source.readFile(e.ref), n = j(t, this.topic, e);
387
385
  if (!n.ok) throw this.older = null, Error(`history file ${e.ref} refused (${n.reason}): ${n.detail}`);
388
386
  return this.report(n.value.skipped), this.older = n.value.prev, n.value.rows;
389
387
  }
390
388
  async newestLink(e, t) {
391
389
  let n = t === void 0 ? e : e - 1;
392
390
  if (t !== void 0) {
393
- let n = E(t, e, this.topic);
391
+ let n = A(t, e, this.topic);
394
392
  if (n.ok) return n.value.history;
395
393
  }
396
- for (let t = n; t >= Math.max(0, e - ce); t--) {
394
+ for (let t = n; t >= Math.max(0, e - me); t--) {
397
395
  let e = await this.source.readSlot(t).catch((e) => {
398
- if (e instanceof U) return null;
396
+ if (e instanceof K) return null;
399
397
  throw e;
400
398
  });
401
399
  if (e === null) continue;
402
- let n = E(e, t, this.topic);
400
+ let n = A(e, t, this.topic);
403
401
  if (n.ok) return n.value.history;
404
402
  }
405
403
  return null;
406
404
  }
407
405
  async readFile(e) {
408
406
  try {
409
- let t = D(await this.source.readFile(e.ref), this.topic, e);
407
+ let t = j(await this.source.readFile(e.ref), this.topic, e);
410
408
  return t.ok ? (this.report(t.value.skipped), this.older = t.value.prev, t.value.rows) : (this.events.error(/* @__PURE__ */ Error(`history file ${e.ref} refused (${t.reason}): ${t.detail}`)), "refused");
411
409
  } catch (t) {
412
410
  return this.events.error(t), this.older = e, null;
@@ -415,18 +413,18 @@ var Y = {
415
413
  report(e) {
416
414
  e > 0 && this.events.skipped(e);
417
415
  }
418
- }, ue = {
419
- slotMs: n,
420
- heartbeatMs: t,
416
+ }, ge = {
417
+ slotMs: C,
418
+ heartbeatMs: O,
421
419
  marginMs: 1e3,
422
420
  scanBatch: 4,
423
421
  clockLimitMs: 3e5,
424
- missingReadSpacingMs: B
422
+ missingReadSpacingMs: U
425
423
  };
426
- function Z(e) {
424
+ function _e(e) {
427
425
  return typeof e.readNote == "function";
428
426
  }
429
- var de = class {
427
+ var ve = class {
430
428
  constructor(e) {
431
429
  this.limitMs = e, this.aheadAtMost = Infinity, this.trusted = !0;
432
430
  }
@@ -443,21 +441,21 @@ var de = class {
443
441
  let e = Number.isFinite(this.aheadAtMost), t = this.trusted || !e ? Math.min(0, this.aheadAtMost) : this.aheadAtMost;
444
442
  return Math.max(-this.limitMs, Math.min(this.limitMs, t));
445
443
  }
446
- }, fe = class {
444
+ }, ye = class {
447
445
  constructor(e, t, n) {
448
446
  this.source = e, this.now = n, this.counts = {
449
447
  found: 0,
450
448
  empty: 0
451
449
  }, this.settings = {
452
- ...ue,
450
+ ...ge,
453
451
  ...t
454
- }, this.clock = new de(this.settings.clockLimitMs), this.pacer = new V(this.settings.missingReadSpacingMs, n);
452
+ }, this.clock = new ve(this.settings.clockLimitMs), this.pacer = new W(this.settings.missingReadSpacingMs, n);
455
453
  }
456
454
  lastReadableSlot(e = this.now()) {
457
- return w(e - this.settings.marginMs - this.clock.ms, this.settings.slotMs) - 1;
455
+ return k(e - this.settings.marginMs - this.clock.ms, this.settings.slotMs) - 1;
458
456
  }
459
457
  readableAt(e) {
460
- return C(e, this.settings.slotMs) + this.settings.marginMs + this.clock.ms;
458
+ return x(e, this.settings.slotMs) + this.settings.marginMs + this.clock.ms;
461
459
  }
462
460
  get lookBackSlots() {
463
461
  return Math.ceil(this.settings.heartbeatMs / this.settings.slotMs) + 2;
@@ -471,10 +469,10 @@ var de = class {
471
469
  try {
472
470
  t = await this.source.readNote(e), t === null && this.pacer.missed(e);
473
471
  } catch (e) {
474
- if (!(e instanceof U)) throw e;
472
+ if (!(e instanceof K)) throw e;
475
473
  t = null;
476
474
  }
477
- let n = t === null ? null : O(t);
475
+ let n = t === null ? null : g(t);
478
476
  return n === null ? (this.counts.empty++, null) : (this.counts.found++, this.clock.observe(n.writtenAt, this.now()), n);
479
477
  }
480
478
  async scan(e, t) {
@@ -494,17 +492,17 @@ var de = class {
494
492
  maxResends: 5,
495
493
  reactionWindowMs: 1e3,
496
494
  isLive: () => !0
497
- }, pe = class {
495
+ }, be = class {
498
496
  constructor(e, t, n, r, i = Q) {
499
- this.key = e, this.name = t, this.write = n, this.events = r, this.settings = i, this.outgoing = /* @__PURE__ */ new Map(), this.reactions = /* @__PURE__ */ new Map(), this.stopped = !1;
497
+ this.key = e, this.profile = t, this.write = n, this.events = r, this.settings = i, this.outgoing = /* @__PURE__ */ new Map(), this.reactions = /* @__PURE__ */ new Map(), this.stopped = !1;
500
498
  }
501
499
  get address() {
502
500
  return this.key.publicKey().address().toHex();
503
501
  }
504
502
  send(e) {
505
- let { message: t, bytes: n } = h(this.key, {
503
+ let { message: t, bytes: n } = l(this.key, {
506
504
  ...e,
507
- name: this.name
505
+ ...this.profile
508
506
  }), r = {
509
507
  message: t,
510
508
  bytes: n,
@@ -581,22 +579,27 @@ var de = class {
581
579
  clearTimer(e) {
582
580
  e.timer &&= (clearTimeout(e.timer), null);
583
581
  }
584
- }, me = [
582
+ }, xe = [
585
583
  1e3,
586
584
  2e3,
587
585
  4e3,
588
586
  8e3
589
- ], he = 3;
587
+ ], Se = 3;
590
588
  function $(e) {
591
589
  return (e.startsWith("0x") ? e.slice(2) : e).toLowerCase();
592
590
  }
593
- var ge = class {
591
+ var Ce = class {
594
592
  constructor(e, t = {}) {
595
- this.emitter = new z(), this.seen = /* @__PURE__ */ new Set(), this.status = null, this.generation = 0, this.running = !1, this.starting = null, this.openTimer = null, this.wakeOpen = null;
593
+ this.emitter = new H(), this.seen = /* @__PURE__ */ new Set(), this.status = null, this.generation = 0, this.running = !1, this.starting = null, this.openTimer = null, this.wakeOpen = null;
596
594
  let { user: n, infra: r } = e;
597
- this.key = new N($(n.privateKey)), this.topic = r.chatTopic, this.nickname = n.nickname, this.openRetryMs = t.openRetryMs ?? me, this.senderSettings = {
595
+ this.key = new I($(n.privateKey)), this.topic = r.chatTopic, this.profile = {
596
+ name: n.nickname,
597
+ via: r.via,
598
+ ...n.binding ? { idb: n.binding } : {},
599
+ ...r.own === void 0 ? {} : { own: r.own }
600
+ }, this.openRetryMs = t.openRetryMs ?? xe, this.senderSettings = {
598
601
  ...Q,
599
- isLive: () => this.status === Y.LIVE,
602
+ isLive: () => this.status === X.LIVE,
600
603
  ...t.sender
601
604
  };
602
605
  let i = {
@@ -608,28 +611,28 @@ var ge = class {
608
611
  ...r.noteHeartbeatMs === void 0 ? {} : { heartbeatMs: r.noteHeartbeatMs },
609
612
  ...t.notes
610
613
  };
611
- this.source = t.source ?? K(new j(r.beeUrl), $(r.chatAddress), r.chatTopic, i, a.slotMs), this.write = t.write ?? J(new j(r.writeUrl ?? r.beeUrl), r.stamp ? $(r.stamp) : ae, $(r.gsocResourceId), r.gsocTopic, i);
614
+ this.source = t.source ?? le(new N(r.beeUrl), $(r.chatAddress), r.chatTopic, i, a.slotMs), this.write = t.write ?? de(new N(r.writeUrl ?? r.beeUrl), r.stamp ? $(r.stamp) : ue, $(r.gsocResourceId), r.gsocTopic, i);
612
615
  let o = t.follower?.now ?? (() => Date.now()), s = {
613
616
  pollIntervalMs: r.pollingInterval ?? 1e3,
614
617
  ...t.follower,
615
618
  now: o
616
619
  }, c = this.source;
617
- this.notes = Z(c) ? new fe(c, a, o) : null, this.follower = new se(this.source, this.topic, {
620
+ this.notes = _e(c) ? new ye(c, a, o) : null, this.follower = new pe(this.source, this.topic, {
618
621
  entry: (e) => this.show(e),
619
- skipped: (e, t, n) => this.emitter.emit(F.MESSAGE_SKIPPED, {
622
+ skipped: (e, t, n) => this.emitter.emit(R.MESSAGE_SKIPPED, {
620
623
  index: e,
621
624
  reason: t,
622
625
  detail: n
623
626
  }),
624
627
  status: (e) => this.setStatus(e),
625
- error: (e) => this.emitter.emit(F.ERROR, e)
626
- }, s, this.notes), this.history = new le(this.source, this.topic, {
627
- skipped: (e) => this.emitter.emit(F.MESSAGE_SKIPPED, {
628
+ error: (e) => this.emitter.emit(R.ERROR, e)
629
+ }, s, this.notes), this.history = new he(this.source, this.topic, {
630
+ skipped: (e) => this.emitter.emit(R.MESSAGE_SKIPPED, {
628
631
  index: -1,
629
632
  reason: "history-row",
630
633
  detail: `${e} rows of a history file`
631
634
  }),
632
- error: (e) => this.emitter.emit(F.ERROR, e)
635
+ error: (e) => this.emitter.emit(R.ERROR, e)
633
636
  }, this.notes), this.sender = this.makeSender();
634
637
  }
635
638
  getEmitter() {
@@ -657,7 +660,7 @@ var ge = class {
657
660
  if (!n) throw Error("a reaction names the message it reacts to");
658
661
  return this.sender.react(this.topic, n, e), null;
659
662
  }
660
- return I(this.sender.send({
663
+ return z(this.sender.send({
661
664
  topic: this.topic,
662
665
  type: t,
663
666
  target: n ?? "",
@@ -668,12 +671,12 @@ var ge = class {
668
671
  return this.sender.retry(typeof e == "string" ? e : e.id);
669
672
  }
670
673
  async fetchPreviousMessages() {
671
- this.emitter.emit(F.LOADING_PREVIOUS_MESSAGES, !0);
674
+ this.emitter.emit(R.LOADING_PREVIOUS_MESSAGES, !0);
672
675
  try {
673
676
  let e = this.generation, t = await this.history.loadOlder();
674
677
  return e === this.generation ? this.showRows(t) : [];
675
678
  } finally {
676
- this.emitter.emit(F.LOADING_PREVIOUS_MESSAGES, !1);
679
+ this.emitter.emit(R.LOADING_PREVIOUS_MESSAGES, !1);
677
680
  }
678
681
  }
679
682
  hasPreviousMessages() {
@@ -683,16 +686,16 @@ var ge = class {
683
686
  return [...e].sort((e, t) => e.index >= 0 && t.index >= 0 ? e.index - t.index : e.index >= 0 || t.index >= 0 ? e.index >= 0 ? -1 : 1 : e.timestamp - t.timestamp);
684
687
  }
685
688
  async open(e) {
686
- this.emitter.emit(F.LOADING_INIT, !0);
689
+ this.emitter.emit(R.LOADING_INIT, !0);
687
690
  let t = 0;
688
691
  for (; e === this.generation;) try {
689
692
  let t = await this.history.open();
690
693
  if (e !== this.generation) return;
691
- this.showRows(t.rows), this.follower.start(t.startAt, t.notes), this.emitter.emit(F.LOADING_INIT, !1);
694
+ this.showRows(t.rows), this.follower.start(t.startAt, t.notes), this.emitter.emit(R.LOADING_INIT, !1);
692
695
  return;
693
696
  } catch (n) {
694
697
  if (e !== this.generation) return;
695
- t++, this.emitter.emit(F.ERROR, n), this.setStatus(Y.RECONNECTING), t === he && this.emitter.emit(F.CRITICAL_ERROR, n), await this.waitToOpen(this.openRetryMs[Math.min(t, this.openRetryMs.length) - 1] ?? 8e3);
698
+ t++, this.emitter.emit(R.ERROR, n), this.setStatus(X.RECONNECTING), t === Se && this.emitter.emit(R.CRITICAL_ERROR, n), await this.waitToOpen(this.openRetryMs[Math.min(t, this.openRetryMs.length) - 1] ?? 8e3);
696
699
  }
697
700
  }
698
701
  waitToOpen(e) {
@@ -705,31 +708,31 @@ var ge = class {
705
708
  });
706
709
  }
707
710
  makeSender() {
708
- return new pe(this.key, this.nickname, this.write, {
709
- pending: (e) => this.emitter.emit(F.MESSAGE_REQUEST_INITIATED, I(e)),
710
- written: (e) => this.emitter.emit(F.MESSAGE_REQUEST_UPLOADED, I(e)),
711
+ return new be(this.key, this.profile, this.write, {
712
+ pending: (e) => this.emitter.emit(R.MESSAGE_REQUEST_INITIATED, z(e)),
713
+ written: (e) => this.emitter.emit(R.MESSAGE_REQUEST_UPLOADED, z(e)),
711
714
  failed: (e, t) => {
712
- this.emitter.emit(F.ERROR, t), this.emitter.emit(F.MESSAGE_REQUEST_ERROR, I(e));
715
+ this.emitter.emit(R.ERROR, t), this.emitter.emit(R.MESSAGE_REQUEST_ERROR, z(e));
713
716
  },
714
717
  confirmed: () => {}
715
718
  }, this.senderSettings);
716
719
  }
717
720
  show(e) {
718
- this.seen.has(e.seq) || (this.seen.add(e.seq), this.sender.confirm(e.msg), this.emitter.emit(F.MESSAGE_RECEIVED, L(e)));
721
+ this.seen.has(e.seq) || (this.seen.add(e.seq), this.sender.confirm(e.msg), this.emitter.emit(R.MESSAGE_RECEIVED, B(e)));
719
722
  }
720
723
  showRows(e) {
721
724
  let t = [];
722
725
  for (let n of e) {
723
726
  if (this.seen.has(n.seq)) continue;
724
727
  this.seen.add(n.seq), this.sender.confirm(n.msg);
725
- let e = L(n);
726
- t.push(e), this.emitter.emit(F.MESSAGE_RECEIVED, e);
728
+ let e = B(n);
729
+ t.push(e), this.emitter.emit(R.MESSAGE_RECEIVED, e);
727
730
  }
728
731
  return t;
729
732
  }
730
733
  setStatus(e) {
731
- e !== this.status && (this.status = e, this.emitter.emit(F.STATUS, e));
734
+ e !== this.status && (this.status = e, this.emitter.emit(R.STATUS, e));
732
735
  }
733
736
  };
734
737
  //#endregion
735
- export { z as ChatEmitter, e as ChatMessageError, t as DEFAULT_NOTE_HEARTBEAT_MS, n as DEFAULT_NOTE_SLOT_MS, F as EVENTS, Y as FeedStatus, H as HeadLookupTimeoutError, r as MAX_ENTRY_BYTES, i as MAX_MESSAGE_BYTES, a as MAX_NAME_CHARACTERS, o as MAX_NOTE_BYTES, s as MAX_TEXT_CHARACTERS, c as MAX_TOPIC_CHARACTERS, l as MESSAGE_VERSION, u as MessageType, d as NOTE_VERSION, ge as SwarmChat, X as UnreadableGatewayError, U as UnreadableSlotError, f as chatMessageSchema, p as checkChatMessage, m as countCharacters, h as createChatMessage, g as encodeChatMessage, _ as encodeSlotNote, ee as feedEntrySchema, te as hasValidSignature, ne as historyFileSchema, v as historyLinkSchema, y as historyRowSchema, b as newMessageId, x as noteAddress, S as noteIdentifier, re as noteIdentifierText, C as noteSlotEnd, w as noteSlotOf, T as parseChatMessage, E as parseFeedEntry, D as parseHistoryFile, O as parseSlotNote, k as signedBytes, A as slotNoteSchema };
738
+ export { M as CHAT_BINDING_TITLE, H as ChatEmitter, p as ChatMessageError, O as DEFAULT_NOTE_HEARTBEAT_MS, C as DEFAULT_NOTE_SLOT_MS, R as EVENTS, X as FeedStatus, G as HeadLookupTimeoutError, t as MAX_BINDING_CHARACTERS, T as MAX_ENTRY_BYTES, n as MAX_MESSAGE_BYTES, se as MAX_NAME_CHARACTERS, E as MAX_NOTE_BYTES, m as MAX_TEXT_CHARACTERS, i as MAX_TOPIC_CHARACTERS, r as MESSAGE_VERSION, u as MessageType, b as MessageVia, ae as NOTE_VERSION, ie as OWN_FEED_TOPIC_PREFIX, Ce as SwarmChat, Z as UnreadableGatewayError, K as UnreadableSlotError, te as chatBindingSchema, e as chatMessageSchema, o as checkChatBinding, oe as countCharacters, l as createChatMessage, ee as encodeChatMessage, re as encodeSlotNote, S as feedEntrySchema, d as hasValidSignature, y as historyFileSchema, v as historyLinkSchema, ne as historyRowSchema, a as newMessageId, w as noteAddress, D as noteIdentifier, h as noteIdentifierText, x as noteSlotEnd, k as noteSlotOf, ce as ownFeedTopic, s as parseChatMessage, A as parseFeedEntry, j as parseHistoryFile, g as parseSlotNote, c as signedBytes, _ as slotNoteSchema, f as verifyChatMessage };
@@ -0,0 +1,48 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * The Swarm ID chat binding: the account's statement, signed with its own key, that a chat address on one site is its
4
+ * own. The Swarm ID fork (solarpunk-id, `lib/src/utils/chat-binding.ts`) makes it, and this module reads it exactly as
5
+ * the fork's `verifyChatBinding` does, without importing the fork: the same four lines, the same clean site origin,
6
+ * the same EIP-191 personal_sign recovery with v 27 or 28 and a low s.
7
+ */
8
+ /** The first line, which also versions the binding format. */
9
+ export declare const CHAT_BINDING_TITLE = "Swarm ID chat binding v1";
10
+ /** The fork's own bound on a binding's text. */
11
+ export declare const MAX_BINDING_CHARACTERS = 512;
12
+ /**
13
+ * A binding as a message carries it. `sig` is spelled as the fork writes it, `0x` and 130 lowercase hex characters
14
+ * of r, s and v, so one binding has one spelling inside the signed bytes.
15
+ */
16
+ export declare const chatBindingSchema: z.ZodObject<{
17
+ msg: z.ZodString;
18
+ sig: z.ZodString;
19
+ }, z.core.$strict>;
20
+ export type ChatBinding = z.infer<typeof chatBindingSchema>;
21
+ /** Who a verified binding says the sender is. */
22
+ export interface ChatIdentity {
23
+ /** The Swarm ID account that signed the binding, `0x` and 40 lowercase hex characters. */
24
+ account: string;
25
+ /** The site the binding was signed for, a bare origin. */
26
+ site: string;
27
+ /** When the account says it signed, ISO 8601 UTC. */
28
+ date: string;
29
+ }
30
+ export interface BindingOptions {
31
+ /** The origin the reader runs on. When given, a binding for any other site is refused. */
32
+ origin?: string;
33
+ /** Accept a binding for `http://localhost`, `http://127.0.0.1` or `http://[::1]`, as only a development build signs. */
34
+ allowLocalHttp?: boolean;
35
+ }
36
+ export type BindingCheck = {
37
+ ok: true;
38
+ identity: ChatIdentity;
39
+ } | {
40
+ ok: false;
41
+ detail: string;
42
+ };
43
+ /**
44
+ * Reads a binding for the chat address `addr` (40 lowercase hex characters, no `0x`). Refuses every text but the four
45
+ * lines the fork writes, a binding for another chat address, one for another site than `origin` when that is given,
46
+ * and a signature nothing recovers an account from. Never throws.
47
+ */
48
+ export declare function checkChatBinding(binding: ChatBinding, addr: string, options?: BindingOptions): BindingCheck;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Whether r and s, 64 hex characters each, are in range with s in the lower half of the curve order. Every ECDSA
3
+ * signature has a second valid spelling with s replaced by n - s and v flipped, which recovers the same signer, so
4
+ * refusing the high s one leaves one valid signature per signed text. bee-js and the Swarm ID fork both sign low s.
5
+ */
6
+ export declare function isCanonicalSignature(rHex: string, sHex: string): boolean;
@@ -1,8 +1,9 @@
1
1
  import { z } from 'zod';
2
2
  /**
3
3
  * What the server writes: one feed entry per message at indices 0, 1, 2 and on, and one history file per chat that
4
- * the entries point to. The server builds these and the reader checks their shape. The reader does not check each
5
- * message's signature, because the server checked it before publishing.
4
+ * the entries point to. The server builds these and the reader checks their shape. Their `v` is MESSAGE_VERSION. The
5
+ * reader does not check each message's signature or binding, because the server checked both before publishing. A
6
+ * page that shows who sent a message verifies `msg` itself with `verifyChatMessage`, in a Web Worker.
6
7
  */
7
8
  /** A feed entry is always one chunk, so bee-js never wraps it. */
8
9
  export declare const MAX_ENTRY_BYTES = 4096;
@@ -12,11 +13,11 @@ export declare const historyLinkSchema: z.ZodObject<{
12
13
  }, z.core.$strict>;
13
14
  export type HistoryLink = z.infer<typeof historyLinkSchema>;
14
15
  export declare const feedEntrySchema: z.ZodObject<{
15
- v: z.ZodLiteral<7>;
16
+ v: z.ZodLiteral<8>;
16
17
  seq: z.ZodNumber;
17
18
  at: z.ZodNumber;
18
19
  msg: z.ZodObject<{
19
- v: z.ZodLiteral<7>;
20
+ v: z.ZodLiteral<8>;
20
21
  topic: z.ZodString;
21
22
  id: z.ZodString;
22
23
  type: z.ZodEnum<{
@@ -29,6 +30,15 @@ export declare const feedEntrySchema: z.ZodObject<{
29
30
  name: z.ZodString;
30
31
  addr: z.ZodString;
31
32
  ts: z.ZodNumber;
33
+ via: z.ZodEnum<{
34
+ gateway: "gateway";
35
+ "own-stamp": "own-stamp";
36
+ }>;
37
+ own: z.ZodBoolean;
38
+ idb: z.ZodOptional<z.ZodObject<{
39
+ msg: z.ZodString;
40
+ sig: z.ZodString;
41
+ }, z.core.$strict>>;
32
42
  sig: z.ZodString;
33
43
  }, z.core.$strict>;
34
44
  history: z.ZodNullable<z.ZodObject<{
@@ -41,7 +51,7 @@ export declare const historyRowSchema: z.ZodObject<{
41
51
  seq: z.ZodNumber;
42
52
  at: z.ZodNumber;
43
53
  msg: z.ZodObject<{
44
- v: z.ZodLiteral<7>;
54
+ v: z.ZodLiteral<8>;
45
55
  topic: z.ZodString;
46
56
  id: z.ZodString;
47
57
  type: z.ZodEnum<{
@@ -54,13 +64,22 @@ export declare const historyRowSchema: z.ZodObject<{
54
64
  name: z.ZodString;
55
65
  addr: z.ZodString;
56
66
  ts: z.ZodNumber;
67
+ via: z.ZodEnum<{
68
+ gateway: "gateway";
69
+ "own-stamp": "own-stamp";
70
+ }>;
71
+ own: z.ZodBoolean;
72
+ idb: z.ZodOptional<z.ZodObject<{
73
+ msg: z.ZodString;
74
+ sig: z.ZodString;
75
+ }, z.core.$strict>>;
57
76
  sig: z.ZodString;
58
77
  }, z.core.$strict>;
59
78
  }, z.core.$strict>;
60
79
  export type HistoryRow = z.infer<typeof historyRowSchema>;
61
80
  /** A row that fails its shape is left out and counted, so one bad row never hides the rest of the file. */
62
81
  export declare const historyFileSchema: z.ZodObject<{
63
- v: z.ZodLiteral<7>;
82
+ v: z.ZodLiteral<8>;
64
83
  topic: z.ZodString;
65
84
  fromSeq: z.ZodNumber;
66
85
  toSeq: z.ZodNumber;
@@ -1,3 +1,5 @@
1
1
  export * from './message.js';
2
+ export * from './binding.js';
3
+ export * from './ownFeed.js';
2
4
  export * from './entry.js';
3
5
  export * from './note.js';