@solarpunkltd/swarm-chat-js 8.1.0 → 9.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,16 +1,18 @@
1
1
  import { PrivateKey } from '@ethersphere/bee-js';
2
2
  import { z } from 'zod';
3
3
  import { type ChatBinding, type ChatIdentity } from './binding.js';
4
+ import { type WalletLink } from './walletLink.js';
4
5
  /**
5
- * The chat message of version 8: what a browser sends as a GSOC payload, what the server verifies before it
6
+ * The chat message of version 9: what a browser sends as a GSOC payload, what the server verifies before it
6
7
  * publishes, and what every feed entry carries back as `msg`. This module is the only place its bytes are built,
7
8
  * signed, checked and read, and the server imports it from here rather than keeping a copy. A message of any other
8
9
  * version fails the shape check.
9
10
  */
10
- export declare const MESSAGE_VERSION = 8;
11
+ export declare const MESSAGE_VERSION = 9;
11
12
  /**
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.
13
+ * Measured on the UTF-8 of the whole JSON object, on top of the per-field caps, wallet link included. Large enough for
14
+ * a 500 character text of two byte characters with a Swarm ID binding and a wallet link, at every other cap, which
15
+ * comes to 2,376 bytes.
14
16
  */
15
17
  export declare const MAX_MESSAGE_BYTES = 3072;
16
18
  export declare const MAX_TOPIC_CHARACTERS = 128;
@@ -33,8 +35,18 @@ export type MessageVia = (typeof MessageVia)[keyof typeof MessageVia];
33
35
  * once. A composer that shows a count uses this function, so it and the check agree.
34
36
  */
35
37
  export declare function countCharacters(value: string): number;
38
+ /**
39
+ * Why a name is refused: `length` is outside 1 to {@link MAX_NAME_CHARACTERS} characters, `invisible` holds a format
40
+ * or control character, `ens-like` ends in `.eth` as a reader sees it, which only a verified ENS name may show.
41
+ */
42
+ export type DisplayNameProblem = 'length' | 'invisible' | 'ens-like';
43
+ /**
44
+ * Whether `name` is one a message may carry, as the message check reads it, and why not when it is not. A composer
45
+ * calls this on the name as it will be sent, so it and the check agree.
46
+ */
47
+ export declare function displayNameProblem(name: string): DisplayNameProblem | null;
36
48
  export declare const chatMessageSchema: z.ZodObject<{
37
- v: z.ZodLiteral<8>;
49
+ v: z.ZodLiteral<9>;
38
50
  topic: z.ZodString;
39
51
  id: z.ZodString;
40
52
  type: z.ZodEnum<{
@@ -51,11 +63,15 @@ export declare const chatMessageSchema: z.ZodObject<{
51
63
  gateway: "gateway";
52
64
  "own-stamp": "own-stamp";
53
65
  }>;
54
- own: z.ZodBoolean;
55
66
  idb: z.ZodOptional<z.ZodObject<{
56
67
  msg: z.ZodString;
57
68
  sig: z.ZodString;
58
69
  }, z.core.$strict>>;
70
+ wl: z.ZodOptional<z.ZodObject<{
71
+ msg: z.ZodString;
72
+ wsig: z.ZodString;
73
+ asig: z.ZodString;
74
+ }, z.core.$strict>>;
59
75
  sig: z.ZodString;
60
76
  }, z.core.$strict>;
61
77
  export type ChatMessage = z.infer<typeof chatMessageSchema>;
@@ -102,10 +118,10 @@ export interface ChatMessageDraft {
102
118
  ts?: number;
103
119
  /** Who pays for the inbox write. Required, since nothing can tell from here. */
104
120
  via: MessageVia;
105
- /** Whether the sender also keeps a copy in its own feed, false when left out. */
106
- own?: boolean;
107
121
  /** The sender's Swarm ID chat binding, given only for a signed-in sender. */
108
122
  idb?: ChatBinding;
123
+ /** The sender's Swarm ID wallet link, given only beside `idb`, for a sender who shows an ENS name. */
124
+ wl?: WalletLink;
109
125
  }
110
126
  export interface SignedChatMessage {
111
127
  message: ChatMessage;
@@ -123,8 +139,10 @@ export declare function createChatMessage(privateKey: PrivateKey | Uint8Array |
123
139
  export declare function hasValidSignature(message: ChatMessage): boolean;
124
140
  /**
125
141
  * 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.
142
+ * binding is the fork's four lines for this `addr` and for `options.origin`, and recovers an account. When it also
143
+ * carries a wallet link, the link must be the fork's five lines for that account, signed by its wallet and by the
144
+ * account, and the identity then names the wallet. A message whose binding or link fails is refused as `binding`,
145
+ * never passed as a guest, and so is a bound message checked with no origin.
128
146
  * 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
147
  */
130
148
  export declare function verifyChatMessage(value: unknown, options: VerifyOptions): ChatMessageCheck;
@@ -1,6 +1,6 @@
1
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
2
+ * A sender may keep a copy of each message it sends in a feed of its own, owned by its chat address `addr`. The
3
+ * message says nothing about it, so whether a copy exists is read from that feed. That feed is named by `ownFeedTopic(chatTopic)`, turned into a feed topic with
4
4
  * `Topic.fromString` as the chat's own feed is named by `chatTopic`. The prefix carries a version, so a later layout of
5
5
  * the copies takes a new topic rather than mixing with this one.
6
6
  */
@@ -0,0 +1,7 @@
1
+ /**
2
+ * The address that made `sig` over `text`, `0x` and 40 lowercase hex characters, or null for a signature the fork
3
+ * would refuse or nothing recovers from. `sig` is `0x` and 130 hex characters of r, s and v, already shape-checked.
4
+ */
5
+ export declare function recoverPersonalSigner(text: string, sig: string): string | null;
6
+ /** Whether `text` is a date in the one spelling `Date.prototype.toISOString` writes. */
7
+ export declare function isCanonicalDate(text: string): boolean;
@@ -0,0 +1,45 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * The Swarm ID wallet link: the statement, signed by an account's wallet and countersigned by the account's own key,
4
+ * that the two belong to the same person, which lets a reader show the wallet's ENS name. The Swarm ID fork makes it
5
+ * while the person has "Show my ENS name on sites" on, and its canonical description is `docs/Wallet-Link.md` in the
6
+ * fork (solarpunk-id), with `verifyWalletLink` in its `lib/src/utils/wallet-link.ts`. This module reads it exactly as
7
+ * that function does, without importing the fork: the same five lines, the second of them read exactly, and both
8
+ * EIP-191 personal_sign signatures with v 27 or 28 and a low s. It looks nothing up: a reader takes the checked wallet to its own ENS lookup.
9
+ */
10
+ /** The first line, which also versions the wallet link format. */
11
+ export declare const WALLET_LINK_TITLE = "Swarm ID wallet link v1";
12
+ /** The second line, what the wallet's owner agrees to, which a wallet shows them before they sign. */
13
+ export declare const WALLET_LINK_STATEMENT = "I link this wallet to the Swarm ID account below, so sites may show my ENS name beside its messages.";
14
+ /** The fork's own bound on a wallet link's text, which is 258 characters in the format it writes. */
15
+ export declare const MAX_WALLET_LINK_CHARACTERS = 320;
16
+ /**
17
+ * A wallet link as a message carries it: the fork's `{ message, walletSignature, accountSignature }` as `msg`, `wsig`
18
+ * and `asig`. Each signature is spelled as the fork writes it, `0x` and 130 lowercase hex characters of r, s and v, so
19
+ * one link has one spelling inside the signed bytes.
20
+ */
21
+ export declare const walletLinkSchema: z.ZodObject<{
22
+ msg: z.ZodString;
23
+ wsig: z.ZodString;
24
+ asig: z.ZodString;
25
+ }, z.core.$strict>;
26
+ export type WalletLink = z.infer<typeof walletLinkSchema>;
27
+ export type WalletLinkCheck = {
28
+ ok: true;
29
+ /** The wallet both signatures were checked for, `0x` and 40 lowercase hex characters. */
30
+ wallet: string;
31
+ /** The account the link names, which is the one it was checked against. */
32
+ account: string;
33
+ /** When the account says it signed, ISO 8601 UTC. */
34
+ date: string;
35
+ } | {
36
+ ok: false;
37
+ detail: string;
38
+ };
39
+ /**
40
+ * Reads a wallet link for `account` (`0x` and 40 lowercase hex characters), the account a verified chat binding
41
+ * named. Refuses every text but the five lines the fork writes, its statement included, a wallet signature that does not recover the wallet
42
+ * the link names, an account signature that does not recover the account it names, and a link naming any other
43
+ * account. Never throws.
44
+ */
45
+ export declare function checkWalletLink(link: WalletLink, account: string): WalletLinkCheck;
@@ -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.origin!==void 0&&i!==n.origin)return{ok:!1,detail:`the binding is for ${i}, not ${n.origin}`};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(typeof t?.origin!=`string`)return{ok:!1,reason:`binding`,detail:`no origin was 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}});