@solarpunkltd/swarm-chat-js 7.3.0 → 8.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.
- package/README.md +107 -20
- package/dist/chat.d.ts +9 -2
- package/dist/events.d.ts +9 -5
- package/dist/index.cjs +1 -1
- package/dist/index.js +102 -99
- package/dist/message/binding.d.ts +48 -0
- package/dist/message/canonicalSignature.d.ts +6 -0
- package/dist/message/entry.d.ts +25 -6
- package/dist/message/index.d.ts +2 -0
- package/dist/message/message.d.ts +60 -14
- package/dist/message/ownFeed.d.ts +9 -0
- package/dist/message-Bmwh3SCs.cjs +3 -0
- package/dist/message-Dbh8qrpg.js +455 -0
- package/dist/message.cjs +1 -1
- package/dist/message.js +2 -308
- package/dist/sender.d.ts +11 -4
- package/package.json +13 -10
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
import { PrivateKey } from '@ethersphere/bee-js';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
+
import { type ChatBinding, type ChatIdentity } from './binding.js';
|
|
3
4
|
/**
|
|
4
|
-
* The chat message of version
|
|
5
|
+
* The chat message of version 8: what a browser sends as a GSOC payload, what the server verifies before it
|
|
5
6
|
* publishes, and what every feed entry carries back as `msg`. This module is the only place its bytes are built,
|
|
6
|
-
* signed, checked and read, and the server imports it from here rather than keeping a copy.
|
|
7
|
+
* signed, checked and read, and the server imports it from here rather than keeping a copy. A message of any other
|
|
8
|
+
* version fails the shape check.
|
|
7
9
|
*/
|
|
8
|
-
export declare const MESSAGE_VERSION =
|
|
9
|
-
/**
|
|
10
|
-
|
|
10
|
+
export declare const MESSAGE_VERSION = 8;
|
|
11
|
+
/**
|
|
12
|
+
* Measured on the UTF-8 of the whole JSON object, on top of the per-field caps. Large enough for a 500 character text
|
|
13
|
+
* of two byte characters with a Swarm ID binding, at every other cap.
|
|
14
|
+
*/
|
|
15
|
+
export declare const MAX_MESSAGE_BYTES = 3072;
|
|
11
16
|
export declare const MAX_TOPIC_CHARACTERS = 128;
|
|
12
17
|
export declare const MAX_TEXT_CHARACTERS = 500;
|
|
13
18
|
export declare const MAX_NAME_CHARACTERS = 20;
|
|
@@ -17,13 +22,19 @@ export declare const MessageType: {
|
|
|
17
22
|
readonly REACTION: 'reaction';
|
|
18
23
|
};
|
|
19
24
|
export type MessageType = (typeof MessageType)[keyof typeof MessageType];
|
|
25
|
+
/** Who paid for the inbox write: the gateway's stamp, or the sender's own. */
|
|
26
|
+
export declare const MessageVia: {
|
|
27
|
+
readonly GATEWAY: 'gateway';
|
|
28
|
+
readonly OWN_STAMP: 'own-stamp';
|
|
29
|
+
};
|
|
30
|
+
export type MessageVia = (typeof MessageVia)[keyof typeof MessageVia];
|
|
20
31
|
/**
|
|
21
32
|
* Characters are counted as Unicode code points, never as UTF-16 units, so an emoji outside the basic plane counts
|
|
22
33
|
* once. A composer that shows a count uses this function, so it and the check agree.
|
|
23
34
|
*/
|
|
24
35
|
export declare function countCharacters(value: string): number;
|
|
25
36
|
export declare const chatMessageSchema: z.ZodObject<{
|
|
26
|
-
v: z.ZodLiteral<
|
|
37
|
+
v: z.ZodLiteral<8>;
|
|
27
38
|
topic: z.ZodString;
|
|
28
39
|
id: z.ZodString;
|
|
29
40
|
type: z.ZodEnum<{
|
|
@@ -36,19 +47,39 @@ export declare const chatMessageSchema: z.ZodObject<{
|
|
|
36
47
|
name: z.ZodString;
|
|
37
48
|
addr: z.ZodString;
|
|
38
49
|
ts: z.ZodNumber;
|
|
50
|
+
via: z.ZodEnum<{
|
|
51
|
+
gateway: "gateway";
|
|
52
|
+
"own-stamp": "own-stamp";
|
|
53
|
+
}>;
|
|
54
|
+
own: z.ZodBoolean;
|
|
55
|
+
idb: z.ZodOptional<z.ZodObject<{
|
|
56
|
+
msg: z.ZodString;
|
|
57
|
+
sig: z.ZodString;
|
|
58
|
+
}, z.core.$strict>>;
|
|
39
59
|
sig: z.ZodString;
|
|
40
60
|
}, z.core.$strict>;
|
|
41
61
|
export type ChatMessage = z.infer<typeof chatMessageSchema>;
|
|
42
62
|
export type UnsignedChatMessage = Omit<ChatMessage, 'sig'>;
|
|
43
|
-
export type ChatMessageRefusal = 'too-large' | 'not-utf8' | 'not-json' | 'shape' | 'signature';
|
|
63
|
+
export type ChatMessageRefusal = 'too-large' | 'not-utf8' | 'not-json' | 'shape' | 'signature' | 'binding';
|
|
64
|
+
/** `identity` is null for a guest, a message with no binding. */
|
|
44
65
|
export type ChatMessageCheck = {
|
|
45
66
|
ok: true;
|
|
46
67
|
message: ChatMessage;
|
|
68
|
+
identity: ChatIdentity | null;
|
|
47
69
|
} | {
|
|
48
70
|
ok: false;
|
|
49
71
|
reason: ChatMessageRefusal;
|
|
50
72
|
detail: string;
|
|
51
73
|
};
|
|
74
|
+
/**
|
|
75
|
+
* `origin` is the site the chat runs on, a bare origin such as `https://example.com`, and is required: a binding for
|
|
76
|
+
* any other site is refused, so a binding signed for one site never passes in another site's chat.
|
|
77
|
+
*/
|
|
78
|
+
export interface VerifyOptions {
|
|
79
|
+
origin: string;
|
|
80
|
+
/** Accept a binding for `http://localhost`, `http://127.0.0.1` or `http://[::1]`, as only a development build signs. */
|
|
81
|
+
allowLocalHttp?: boolean;
|
|
82
|
+
}
|
|
52
83
|
export declare class ChatMessageError extends Error {
|
|
53
84
|
readonly reason: ChatMessageRefusal;
|
|
54
85
|
constructor(reason: ChatMessageRefusal, detail: string);
|
|
@@ -69,6 +100,12 @@ export interface ChatMessageDraft {
|
|
|
69
100
|
id?: string;
|
|
70
101
|
/** The sender's clock in milliseconds, `Date.now()` when left out. */
|
|
71
102
|
ts?: number;
|
|
103
|
+
/** Who pays for the inbox write. Required, since nothing can tell from here. */
|
|
104
|
+
via: MessageVia;
|
|
105
|
+
/** Whether the sender also keeps a copy in its own feed, false when left out. */
|
|
106
|
+
own?: boolean;
|
|
107
|
+
/** The sender's Swarm ID chat binding, given only for a signed-in sender. */
|
|
108
|
+
idb?: ChatBinding;
|
|
72
109
|
}
|
|
73
110
|
export interface SignedChatMessage {
|
|
74
111
|
message: ChatMessage;
|
|
@@ -76,15 +113,24 @@ export interface SignedChatMessage {
|
|
|
76
113
|
}
|
|
77
114
|
/**
|
|
78
115
|
* Builds and signs a message, and throws a ChatMessageError before signing anything that the server would refuse:
|
|
79
|
-
* a field outside its cap,
|
|
116
|
+
* a field outside its cap, a payload over MAX_MESSAGE_BYTES, or a binding that is not for this key.
|
|
80
117
|
*/
|
|
81
118
|
export declare function createChatMessage(privateKey: PrivateKey | Uint8Array | string, draft: ChatMessageDraft): SignedChatMessage;
|
|
82
|
-
/**
|
|
119
|
+
/**
|
|
120
|
+
* Whether `sig` was made over this message's signed bytes by the key behind `addr`, in its one canonical spelling: v 27
|
|
121
|
+
* or 28 and a low s, as bee-js signs. bee-js would also recover the signer from the high s twin, or from any other v.
|
|
122
|
+
*/
|
|
83
123
|
export declare function hasValidSignature(message: ChatMessage): boolean;
|
|
84
|
-
/** Checks a message that arrived as an object, its shape and its signature. */
|
|
85
|
-
export declare function checkChatMessage(value: unknown): ChatMessageCheck;
|
|
86
124
|
/**
|
|
87
|
-
*
|
|
88
|
-
*
|
|
125
|
+
* Verifies a message that arrived as an object: its shape, its signature, and, when it carries a binding, that the
|
|
126
|
+
* binding is the fork's four lines for this `addr` and for `options.origin`, and recovers an account. A message whose
|
|
127
|
+
* binding fails is refused as `binding`, never passed as a guest, and so is a bound message checked with no origin.
|
|
128
|
+
* Never throws, and touches no DOM and no Node API, so a page runs it in a Web Worker as the server runs it.
|
|
129
|
+
*/
|
|
130
|
+
export declare function verifyChatMessage(value: unknown, options: VerifyOptions): ChatMessageCheck;
|
|
131
|
+
/**
|
|
132
|
+
* Verifies a message as it arrived on the wire: the byte cap on the raw payload, then UTF-8, JSON, and everything
|
|
133
|
+
* `verifyChatMessage` checks. Never throws, since the server calls it on whatever anybody writes to the chat's GSOC
|
|
134
|
+
* address.
|
|
89
135
|
*/
|
|
90
|
-
export declare function parseChatMessage(payload: Uint8Array): ChatMessageCheck;
|
|
136
|
+
export declare function parseChatMessage(payload: Uint8Array, options: VerifyOptions): ChatMessageCheck;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A sender may keep a copy of each message it sends in a feed of its own, owned by its chat address `addr`, and says
|
|
3
|
+
* so with `own: true`. That feed is named by `ownFeedTopic(chatTopic)`, turned into a feed topic with
|
|
4
|
+
* `Topic.fromString` as the chat's own feed is named by `chatTopic`. The prefix carries a version, so a later layout of
|
|
5
|
+
* the copies takes a new topic rather than mixing with this one.
|
|
6
|
+
*/
|
|
7
|
+
export declare const OWN_FEED_TOPIC_PREFIX = "swarm-chat-own-feed-v1:";
|
|
8
|
+
/** The topic string of the feed where the sender keeps its copies of the messages it sent to chat `chatTopic`. */
|
|
9
|
+
export declare function ownFeedTopic(chatTopic: string): string;
|
|
@@ -0,0 +1,3 @@
|
|
|
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=`Swarm ID chat binding v1`,s=512,c=`Site: `,l=`Chat address: `,ee=`Date: `,te=`
|
|
2
|
+
`,u=4,d=`Ethereum Signed Message:
|
|
3
|
+
`,ne=new Set([27,28]),f=/^0x[0-9a-f]{40}$/,p=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/,m=/^[a-z0-9-]+(\.[a-z0-9-]+)*$/,re=new Set([`localhost`,`127.0.0.1`,`[::1]`]),h=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`)}),g=new TextEncoder;function ie(e,t){let n;try{n=new URL(e)}catch{return!1}let r=n.protocol===`https:`,i=t&&n.protocol===`http:`&&re.has(n.hostname);return!r&&!i||!i&&!m.test(n.hostname)?!1:n.host!==``&&n.username===``&&n.password===``&&n.origin===e}function _(e){if(!p.test(e))return!1;let t=Date.parse(e);return!Number.isNaN(t)&&new Date(t).toISOString()===e}function v(e,t){return e.startsWith(t)?e.slice(t.length):null}function ae(e){let t=g.encode(e),n=g.encode(`${d}${t.length}`),r=new Uint8Array(n.length+t.length);return r.set(n),r.set(t,n.length),r}function oe(e){return Array.from(e,e=>e.toString(16).padStart(2,`0`)).join(``)}function y(e,t){let r=t.slice(2,66),i=t.slice(66,130),o=parseInt(t.slice(130),16);if(!ne.has(o)||!a(r,i))return null;try{let t=(0,n.recoverPublicKey)(ae(e),BigInt(`0x${r}`),BigInt(`0x${i}`),BigInt(o));return`0x${oe((0,n.publicKeyToAddress)(t))}`}catch{return null}}function b(e,t,n={}){if(!h.safeParse(e).success)return{ok:!1,detail:`not a binding of a text and a 65 byte signature`};let r=e.msg.split(te);if(r.length!==u||r[0]!==`Swarm ID chat binding v1`)return{ok:!1,detail:`not the ${u} lines of a ${o}`};let i=v(r[1],c),a=v(r[2],l),s=v(r[3],ee);if(i===null||!ie(i,n.allowLocalHttp===!0))return{ok:!1,detail:`the binding does not name a clean site origin`};if(a===null||!f.test(a))return{ok:!1,detail:`the binding does not name a chat address as 0x and 40 lowercase hex characters`};if(s===null||!_(s))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.origin!==void 0&&i!==n.origin)return{ok:!1,detail:`the binding is for ${i}, not ${n.origin}`};let d=y(e.msg,e.sig);return d===null?{ok:!1,detail:`the binding signature recovers no account`}:{ok:!0,identity:{account:d,site:i,date:s}}}var x=8,S=3072,se=128,ce=500,C=20,w={TEXT:`text`,THREAD:`thread`,REACTION:`reaction`},T={GATEWAY:`gateway`,OWN_STAMP:`own-stamp`};function E(e){let t=0;for(let n of e)t++;return t}function D(e){return t.z.string().regex(RegExp(`^[0-9a-f]{${e}}$`),`expected ${e} lowercase hex characters`)}function O(e,n){return t.z.string().refine(t=>{let r=E(t);return r>=e&&r<=n},`expected ${e} to ${n} characters`)}var k=D(32),A=t.z.strictObject({v:t.z.literal(8),topic:O(1,128),id:k,type:t.z.enum([w.TEXT,w.THREAD,w.REACTION]),target:t.z.union([t.z.literal(``),k]),text:O(1,500),name:O(1,20),addr:D(40),ts:t.z.number().int().nonnegative().max(2**53-1),via:t.z.enum([T.GATEWAY,T.OWN_STAMP]),own:t.z.boolean(),idb:h.optional(),sig:D(130)}).refine(e=>e.type===w.TEXT==(e.target===``),{message:`a text message has no target, a thread reply or a reaction names one`,path:[`target`]}),j=class extends Error{constructor(e,t){super(`chat message refused (${e}): ${t}`),this.reason=e,this.name=`ChatMessageError`}},M=new TextEncoder,le=`1b`,ue=`1c`,de=new TextDecoder(`utf-8`,{fatal:!0});function N(e){return M.encode(JSON.stringify([e.v,e.topic,e.id,e.type,e.target,e.text,e.name,e.addr,e.ts,e.via,e.own,e.idb?.msg??``,e.idb?.sig??``]))}function P(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,own:e.own,...e.idb?{idb:{msg:e.idb.msg,sig:e.idb.sig}}:{},sig:e.sig};return M.encode(JSON.stringify(t))}function F(){let e=crypto.getRandomValues(new Uint8Array(16));return Array.from(e,e=>e.toString(16).padStart(2,`0`)).join(``)}function I(e){return e.issues.map(e=>`${e.path.join(`.`)||`message`}: ${e.message}`).join(`, `)}function L(t,n){let r=t instanceof e.PrivateKey?t:new e.PrivateKey(t),i={v:8,topic:n.topic,id:n.id??F(),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,own:n.own??!1,...n.idb?{idb:n.idb}:{}},a={...i,sig:`0`.repeat(130)},o=A.safeParse(a);if(!o.success)throw new j(`shape`,I(o.error));let s=P(a).byteLength;if(s>3072)throw new j(`too-large`,`${s} bytes, the cap is ${S}`);if(i.idb){let e=b(i.idb,i.addr,{allowLocalHttp:!0});if(!e.ok)throw new j(`binding`,e.detail)}let c={...i,sig:r.sign(N(i)).toHex()};return{message:c,bytes:P(c)}}function R(t){let n=t.sig.slice(128);if(n!==le&&n!==ue||!a(t.sig.slice(0,64),t.sig.slice(64,128)))return!1;try{return new e.Signature(t.sig).recoverPublicKey(N(t)).address().toHex()===t.addr}catch{return!1}}function z(e,t){let n=A.safeParse(e);if(!n.success)return{ok:!1,reason:`shape`,detail:I(n.error)};let r=n.data;if(!R(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(typeof t?.origin!=`string`)return{ok:!1,reason:`binding`,detail:`no origin was given to check the binding against`};let i=b(r.idb,r.addr,t);return i.ok?{ok:!0,message:r,identity:i.identity}:{ok:!1,reason:`binding`,detail:i.detail}}function B(e,t){if(e.byteLength>3072)return{ok:!1,reason:`too-large`,detail:`${e.byteLength} bytes, the cap is ${S}`};let n;try{n=de.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 z(r,t)}var V=`swarm-chat-own-feed-v1:`;function H(e){return`${V}${e}`}var fe=4096,pe=t.z.string().regex(/^[0-9a-f]{64}([0-9a-f]{64})?$/,`expected a 64 or 128 hex character reference`),U=t.z.number().int().nonnegative().max(2**53-1),W=t.z.strictObject({ref:pe,toSeq:U}),G=t.z.strictObject({v:t.z.literal(8),seq:U,at:U,msg:A,history:W.nullable()}),K=t.z.strictObject({seq:U,at:U,msg:A}),q=t.z.strictObject({v:t.z.literal(8),topic:t.z.string().min(1),fromSeq:U,toSeq:U,messages:t.z.array(t.z.unknown()),prev:W.nullable()}).refine(e=>e.fromSeq<=e.toSeq,{message:`fromSeq is after toSeq`,path:[`fromSeq`]}),me=new TextDecoder(`utf-8`,{fatal:!0});function J(e){let t;try{t=me.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 Y(e){return e.issues.map(e=>`${e.path.join(`.`)||`value`}: ${e.message}`).join(`, `)}function he(e,t,n){let r=J(e);if(!r.ok)return r;let i=G.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:Y(i.error)}}function ge(e,t,n){let r=J(e);if(!r.ok)return r;let i=q.safeParse(r.value);if(!i.success)return{ok:!1,reason:`shape`,detail:Y(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=K.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 _e=1,ve=2e3,ye=3e4,be=256,X=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 Z(e){if(!Number.isInteger(e)||e<=0)throw RangeError(`a note slot is a positive whole number of milliseconds, not ${e}`)}function xe(e,t){return Z(t),Math.floor(e/t)}function Se(e,t){return Z(t),(e+1)*t}function Q(e,t,n){return`${e}/note/${t}/${n}`}function $(t,n,r){return e.Identifier.fromString(Q(t,n,r))}function Ce(t,n,r,i){let a=$(t,n,r);return new e.Reference(e.Bytes.keccak256(e.Bytes.concat(a.toUint8Array(),new e.EthAddress(i).toUint8Array())))}var we=new TextEncoder,Te=new TextDecoder(`utf-8`,{fatal:!0});function Ee(e){let t={v:1,newest:e.newest,writtenAt:e.writtenAt};return we.encode(JSON.stringify(t))}function De(e){if(e.length>256)return null;try{let t=X.safeParse(JSON.parse(Te.decode(e)));return t.success?t.data:null}catch{return null}}Object.defineProperty(exports,"A",{enumerable:!0,get:function(){return A}}),Object.defineProperty(exports,"B",{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,"C",{enumerable:!0,get:function(){return S}}),Object.defineProperty(exports,"D",{enumerable:!0,get:function(){return x}}),Object.defineProperty(exports,"E",{enumerable:!0,get:function(){return se}}),Object.defineProperty(exports,"F",{enumerable:!0,get:function(){return F}}),Object.defineProperty(exports,"H",{enumerable:!0,get:function(){return b}}),Object.defineProperty(exports,"I",{enumerable:!0,get:function(){return B}}),Object.defineProperty(exports,"L",{enumerable:!0,get:function(){return N}}),Object.defineProperty(exports,"M",{enumerable:!0,get:function(){return L}}),Object.defineProperty(exports,"N",{enumerable:!0,get:function(){return P}}),Object.defineProperty(exports,"O",{enumerable:!0,get:function(){return w}}),Object.defineProperty(exports,"P",{enumerable:!0,get:function(){return R}}),Object.defineProperty(exports,"R",{enumerable:!0,get:function(){return z}}),Object.defineProperty(exports,"S",{enumerable:!0,get:function(){return j}}),Object.defineProperty(exports,"T",{enumerable:!0,get:function(){return ce}}),Object.defineProperty(exports,"V",{enumerable:!0,get:function(){return h}}),Object.defineProperty(exports,"_",{enumerable:!0,get:function(){return K}}),Object.defineProperty(exports,"a",{enumerable:!0,get:function(){return Ee}}),Object.defineProperty(exports,"b",{enumerable:!0,get:function(){return V}}),Object.defineProperty(exports,"c",{enumerable:!0,get:function(){return Q}}),Object.defineProperty(exports,"d",{enumerable:!0,get:function(){return De}}),Object.defineProperty(exports,"f",{enumerable:!0,get:function(){return X}}),Object.defineProperty(exports,"g",{enumerable:!0,get:function(){return W}}),Object.defineProperty(exports,"h",{enumerable:!0,get:function(){return q}}),Object.defineProperty(exports,"i",{enumerable:!0,get:function(){return _e}}),Object.defineProperty(exports,"j",{enumerable:!0,get:function(){return E}}),Object.defineProperty(exports,"k",{enumerable:!0,get:function(){return T}}),Object.defineProperty(exports,"l",{enumerable:!0,get:function(){return Se}}),Object.defineProperty(exports,"m",{enumerable:!0,get:function(){return G}}),Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return ve}}),Object.defineProperty(exports,"o",{enumerable:!0,get:function(){return Ce}}),Object.defineProperty(exports,"p",{enumerable:!0,get:function(){return fe}}),Object.defineProperty(exports,"r",{enumerable:!0,get:function(){return be}}),Object.defineProperty(exports,"s",{enumerable:!0,get:function(){return $}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return ye}}),Object.defineProperty(exports,"u",{enumerable:!0,get:function(){return xe}}),Object.defineProperty(exports,"v",{enumerable:!0,get:function(){return he}}),Object.defineProperty(exports,"w",{enumerable:!0,get:function(){return C}}),Object.defineProperty(exports,"x",{enumerable:!0,get:function(){return H}}),Object.defineProperty(exports,"y",{enumerable:!0,get:function(){return ge}}),Object.defineProperty(exports,"z",{enumerable:!0,get:function(){return o}});
|
|
@@ -0,0 +1,455 @@
|
|
|
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 };
|
package/dist/message.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});
|
|
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;
|