@calimero-network/mero-js 22.8.0 → 22.9.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,3 +1,3 @@
1
- function ft(n){let e=n.filter(Boolean);if(e.length===0)return;let t=AbortSignal;if(typeof t.any=="function")try{return t.any(e)}catch{}let r=new AbortController,o=i=>{r.abort(i.target.reason);for(let a of e)a.removeEventListener("abort",o)};for(let i of e){if(i.aborted)return AbortSignal.abort(i.reason);i.addEventListener("abort",o,{once:!0})}return r.signal}function yt(n){if(typeof AbortSignal.timeout=="function")return AbortSignal.timeout(n);let e=new AbortController;return setTimeout(()=>{e.abort(new DOMException("Timeout","TimeoutError"))},n),e.signal}var oo=new Set(["token_reuse","token_revoked"]);function io(n){if(n)try{let e=JSON.parse(n),t=e?.error;if(typeof t=="string"&&t.trim()!=="")return t;let r=t?.message;if(typeof r=="string"&&r.trim()!=="")return r;let o=e?.detail;if(typeof o=="string"&&o.trim()!=="")return o}catch{}}var C=class extends Error{constructor(t,r,o,i,a){let s=io(a)??(t===0&&a?.trim()?a.trim():void 0);super(s?`HTTP ${t} ${r}: ${s}`:`HTTP ${t} ${r}`);this.status=t;this.statusText=r;this.url=o;this.headers=i;this.bodyText=a;this.name="HTTPError";this.explanation=s}toJSON(){return{status:this.status,statusText:this.statusText,url:this.url,headers:ln(this.headers),bodyText:this.bodyText}}},L=class extends C{constructor(t,r,o,i,a,s){super(r,o,i,a,s);this.reason=t;this.name="AuthRevokedError";this.message=`Authentication revoked (${t}): HTTP ${r} ${o}`}};function ln(n){let e={};return n.forEach((t,r)=>{e[r]=t}),e}function so(n){try{return new URL(n).pathname}catch{let e=n.indexOf("?");return e===-1?n:n.slice(0,e)}}var ye=class{constructor(e){this.transport=e;this.refreshTokenPromise=null;this.onTokenRefreshPromise=null}async get(e,t){return this.request(e,{...t,method:"GET"})}async post(e,t,r){return this.request(e,{...r,method:"POST",body:t?JSON.stringify(t):void 0,headers:{"Content-Type":"application/json",...r?.headers}})}async put(e,t,r){return this.request(e,{...r,method:"PUT",body:t?JSON.stringify(t):void 0,headers:{"Content-Type":"application/json",...r?.headers}})}async delete(e,t){return this.request(e,{...t,method:"DELETE"})}async patch(e,t,r){return this.request(e,{...r,method:"PATCH",body:t?JSON.stringify(t):void 0,headers:{"Content-Type":"application/json",...r?.headers}})}async head(e,t){let r=await this.makeRequest(e,{...t,method:"HEAD",parse:"response"});return{headers:ln(r.headers),status:r.status}}async request(e,t){return this.makeRequest(e,t)}async makeRequest(e,t,r=0,o){let a=this.buildUrl(e),s=o??Date.now(),c=this.createAbortSignal(t),u=await this.buildHeaders(t?.headers),d;u instanceof Headers?(d={},u.forEach((y,T)=>{d[T]=y})):d=u;let l=t?.method||"GET";if(this.transport.authorizeRequest){let y=t?.body;if(y!==void 0&&typeof y!="string"&&!(y instanceof Uint8Array))throw new Error("this transport authorizes each request against its body, so the body must be a string or Uint8Array \u2014 a stream cannot be signed, because the signature would have to read bytes the request then cannot send.");Object.assign(d,await this.transport.authorizeRequest({method:l,path:new URL(a).pathname,body:y}))}let p={method:l,headers:d},b=t?.body instanceof ReadableStream||typeof t?.body=="object"&&t?.body!==null&&"getReader"in t.body&&!(t.body instanceof Blob);(t?.body!==void 0&&!b||t?.body!==void 0&&b&&r===0)&&(p.body=t.body);let w;if(r>0&&o!==void 0){let y=t?.timeoutMs||this.transport.timeoutMs;if(y){let T=Date.now()-s,v=Math.max(0,y-T);w=this.createAbortSignal({...t,timeoutMs:v})}else w=this.createAbortSignal(t)}else w=c;if(w&&(p.signal=w),this.transport.credentials!==void 0&&(p.credentials=this.transport.credentials),t?.mode!==void 0&&(p.mode=t.mode),t?.cache!==void 0&&(p.cache=t.cache),t?.redirect!==void 0&&(p.redirect=t.redirect),t?.referrer!==void 0&&(p.referrer=t.referrer),t?.referrerPolicy!==void 0&&(p.referrerPolicy=t.referrerPolicy),t?.integrity!==void 0&&(p.integrity=t.integrity),t?.keepalive!==void 0&&(p.keepalive=t.keepalive),this.transport.getProof){let y=await this.transport.getProof({method:p.method??"GET",path:so(a),body:p.body});y&&(d["X-Calimero-Proof"]=y)}try{let y=await this.transport.fetch(a,p);if(!y.ok){let T=await this.getBodyText(y),v=new C(y.status,y.statusText,a,y.headers,T),R=y.headers.get("x-auth-error");if((y.status===401||y.status===403)&&R&&oo.has(R)){if(this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,this.transport.onAuthRevoked)try{await this.transport.onAuthRevoked()}catch{}throw new L(R,y.status,y.statusText,a,y.headers,T)}let q=t?.signal?.aborted===!0;if(y.status===401&&this.transport.refreshToken&&R==="token_expired"&&r<1&&!b&&!q)try{let U=this.refreshTokenPromise;U||(U=this.transport.refreshToken(),this.refreshTokenPromise=U);let I=await U;if(!I||I.trim()==="")throw this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,new Error("Refresh token returned empty token");if(!this.transport.onTokenRefresh)throw this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,new Error("onTokenRefresh callback is required when refreshToken is provided. The callback must update the token storage so getAuthToken() returns the new token.");let N=this.onTokenRefreshPromise;N||(N=this.transport.onTokenRefresh(I),this.onTokenRefreshPromise=N),await N,this.refreshTokenPromise=null,this.onTokenRefreshPromise=null;let W=t?.timeoutMs||this.transport.timeoutMs;if(W&&o!==void 0){let z=Date.now()-s;if(W-z<=0)throw v}return this.makeRequest(e,t,r+1,s)}catch(U){throw this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,U instanceof Error&&U.message.includes("onTokenRefresh")?U:v}throw v}return this.parseResponse(y,t?.parse)}catch(y){throw y instanceof C||y instanceof Error&&y.message.includes("onTokenRefresh")?y:new C(0,"Network Error",a,new Headers,y instanceof Error?y.message:"Unknown error")}}buildUrl(e){if(e.startsWith("http://")||e.startsWith("https://"))return e;let t=this.transport.baseUrl;return e.startsWith("/")?`${t.endsWith("/")?t.slice(0,-1):t}${e}`:`${t.endsWith("/")?t:`${t}/`}${e}`}createAbortSignal(e){let t=[];this.transport.defaultAbortSignal&&t.push(this.transport.defaultAbortSignal),e?.signal&&t.push(e.signal);let r=e?.timeoutMs||this.transport.timeoutMs;return r&&t.push(yt(r)),t.length>0?ft(t):void 0}async buildHeaders(e){let t={...this.transport.defaultHeaders};if(this.transport.getAuthToken)try{let r=await this.transport.getAuthToken();r&&r.trim()!==""&&(t.Authorization=`Bearer ${r}`)}catch{}return e&&(e instanceof Headers?e.forEach((r,o)=>{t[o]=r}):Array.isArray(e)?e.forEach(([r,o])=>{t[r]=o}):Object.assign(t,e)),t}async parseResponse(e,t){switch(t){case"text":return await e.text();case"blob":return await e.blob();case"arrayBuffer":return await e.arrayBuffer();case"response":return e;default:{let r=await e.text();if(!r)return null;try{return JSON.parse(r)}catch{throw new Error(`Expected a JSON response (status ${e.status}) but body was not JSON: ${r.slice(0,200)}`)}}}}async getBodyText(e){try{let t=await e.text();return t.length>65536?t.slice(0,65536)+"...":t}catch{return""}}};function be(n){return new ye(n)}function re(n){let e={fetch:(t,r)=>n.fetch?n.fetch(t,r):globalThis.fetch(t,r),baseUrl:n.baseUrl,getAuthToken:n.getAuthToken,getProof:n.getProof,onTokenRefresh:n.onTokenRefresh,refreshToken:n.refreshToken,onAuthRevoked:n.onAuthRevoked,defaultHeaders:n.defaultHeaders,timeoutMs:n.timeoutMs,credentials:n.credentials,defaultAbortSignal:n.defaultAbortSignal};return be(e)}function Ue(n){let e=n.fetch??globalThis.fetch;if(!e)throw new Error("No fetch implementation available. Please provide a fetch implementation (e.g., undici.fetch) or use Node.js 18+ which has native fetch support.");let r={fetch:e===globalThis.fetch?(o,i)=>globalThis.fetch(o,i):(o,i)=>e(o,i),baseUrl:n.baseUrl,getAuthToken:n.getAuthToken,getProof:n.getProof,onTokenRefresh:n.onTokenRefresh,refreshToken:n.refreshToken,onAuthRevoked:n.onAuthRevoked,defaultHeaders:n.defaultHeaders,timeoutMs:n.timeoutMs,credentials:n.credentials,defaultAbortSignal:n.defaultAbortSignal};return be(r)}function bt(n){return typeof window<"u"?re(n):Ue(n)}function ao(n,e){if(e<=0)return!1;let r=n?.name;if(r==="TimeoutError")return!0;if(r==="AbortError")return!1;let o=n;if("status"in o&&typeof o.status=="number"){let i=o.status;return i>=500||i===429}return r==="TypeError"}function co(n){let t=250*Math.pow(2,n-1),r=(Math.random()-.5)*.4*t;return Math.max(0,t+r)}async function Ne(n,e={}){let{attempts:t=3}=e,r;for(let o=1;o<=t;o++)try{return await n(o)}catch(i){if(r=i,!ao(r,t-o))throw r;let a=co(o),u=r.headers?.get?.("Retry-After");if(u){let d=parseInt(u,10);if(!isNaN(d))a=Math.max(a,d*1e3);else{let l=new Date(u);if(!isNaN(l.getTime())){let p=Math.max(0,l.getTime()-Date.now());a=Math.max(a,Math.min(p,6e4))}}}await new Promise(d=>setTimeout(d,a))}throw r||new Error("Retry failed without error")}function lo(n,e={}){return async(...t)=>Ne(()=>n(...t),e)}var Q=class{constructor(e){this.httpClient=e}async getHealth(){let e=await this.httpClient.get("/auth/health");if(!e.data)throw new Error("Health response data is null");return e.data}async getIdentity(){let e=await this.httpClient.get("/admin/identity");if(!e.data)throw new Error("Identity response data is null");return e.data}async getProviders(){let e=await this.httpClient.get("/auth/providers");if(!e.data)throw new Error("Providers response data is null");return e.data}async getLoginPage(){return this.httpClient.get("/auth/login",{parse:"text"})}async generateTokens(e){return this.httpClient.post("/auth/token",e)}async refreshToken(e){return this.httpClient.post("/auth/refresh",e)}async generateMockTokens(e){return this.httpClient.post("/auth/mock-token",e)}async validateToken(e){try{let t=await this.validateTokenGet(e);return{valid:t.status===200,headers:t.headers,status:t.status}}catch{return{valid:!1,headers:{},status:401}}}async validateTokenGet(e){let t=await this.httpClient.head("/auth/validate",{headers:{Authorization:`Bearer ${e}`}});return{status:t.status,headers:t.headers}}async revokeTokens(e){let t=await this.httpClient.post("/admin/revoke",e);if(!t.data)throw new Error("Revoke tokens response data is null");return t.data}async listRootKeys(){let e=await this.httpClient.get("/admin/keys");if(!e.data)throw new Error("Root keys response data is null");return e.data}async createRootKey(e){let t=await this.httpClient.post("/admin/keys",e);if(!t.data)throw new Error("Create root key response data is null");return t.data}async deleteRootKey(e){return this.httpClient.delete(`/admin/keys/${e}`)}async listClientKeys(){let e=await this.httpClient.get("/admin/keys/clients");if(!e.data)throw new Error("Client keys response data is null");return e.data}async generateClientKey(e){return this.httpClient.post("/admin/client-key",e)}async deleteClientKey(e,t){return this.httpClient.delete(`/admin/keys/${e}/clients/${t}`)}async getKeyPermissions(e){return this.httpClient.get(`/admin/keys/${e}/permissions`)}async updateKeyPermissions(e,t){return this.httpClient.put(`/admin/keys/${e}/permissions`,{add:t.add,remove:t.remove})}};var we=class{async get(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async post(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async put(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async delete(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async patch(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async head(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async request(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}};function oa(n){let e=new we;return new Q(e)}function ia(n){let e=new we;return new Q(e)}function sa(n){let e=new we;return new Q(e)}function un(n,e){return new Q(n)}var P={CAN_CREATE_CONTEXT:1,CAN_INVITE_MEMBERS:2,CAN_JOIN_OPEN_SUBGROUPS:4,MANAGE_MEMBERS:8,MANAGE_APPLICATION:16,CAN_CREATE_SUBGROUP:32,CAN_DELETE_SUBGROUP:64,CAN_MANAGE_VISIBILITY:128,CAN_MANAGE_METADATA:256,CAN_AUTHOR_ON_BEHALF:512},ca={NONE:0,JOIN_ONLY:P.CAN_JOIN_OPEN_SUBGROUPS,CONTRIBUTOR:P.CAN_CREATE_CONTEXT|P.CAN_INVITE_MEMBERS|P.CAN_JOIN_OPEN_SUBGROUPS,COLLABORATOR:P.CAN_CREATE_CONTEXT|P.CAN_INVITE_MEMBERS|P.CAN_JOIN_OPEN_SUBGROUPS|P.CAN_CREATE_SUBGROUP|P.CAN_DELETE_SUBGROUP|P.CAN_MANAGE_VISIBILITY};function la(...n){let e=0;for(let t of n)if(typeof t=="number")e|=t;else if(Object.prototype.hasOwnProperty.call(P,t))e|=P[t];else throw new Error(`unknown capability: ${String(t)}`);return e>>>0}function ua(n){return Object.keys(P).filter(e=>oe(n,P[e]))}function oe(n,e){let t=e>>>0;return(n&t)>>>0===t}function wt(n,e){return(n|e)>>>0}function da(n,e){return(n&~e)>>>0}var uo={invalid:!1,unauthorized:!0,forbidden:!1,"not-found":!0,conflict:!1,gone:!1,"too-large":!1,"rate-limited":!0,unavailable:!0,server:!0,unreachable:!0,unknown:!0};function po(n){switch(n){case 0:return"unreachable";case 400:return"invalid";case 401:return"unauthorized";case 403:return"forbidden";case 404:return"not-found";case 409:return"conflict";case 410:return"gone";case 413:return"too-large";case 429:return"rate-limited";case 503:case 504:return"unavailable"}return n>=500&&n<600?"server":n>=400&&n<500?"invalid":"unknown"}function go(n){if(!n||typeof n!="object")return;let e=n;for(let t of[e.status,e.response?.status,e.statusCode])if(typeof t=="number"&&Number.isFinite(t))return t}function At(n,e="Request failed"){if(typeof n=="string")return n.trim()||e;if(!n||typeof n!="object")return e;let t=n;for(let r of[t.explanation,t.response?.data?.error,t.response?.data?.message,t.data?.message,t.error,t.message])if(typeof r=="string"&&r.trim())return r;return e}function xt(n){let e=go(n),t;return e!==void 0?t=po(e):n instanceof TypeError?t="unreachable":t="unknown",{kind:t,status:e,retryable:uo[t],message:At(n)}}function mo(n){return n.status!=="failed"||!n.retryable}function ha(n){return!mo(n)}function ho(n){let e=n.toLowerCase();return e.includes("invitation has expired")||e.includes("invitation expired")||/\binvitation for group .+? expired at \d+/.test(e)?"expired":e.includes("malformed")||e.includes("does not match namespace_id")||e.includes("invalid invitation")||/\binvitation for group .+? is invalid:/.test(e)?"invalid":null}function fo(n,e){let{kind:t,status:r}=xt(n),o=ho(e);return r===401?{reason:"signed-out",retryable:!0}:r===400?{reason:o??"invalid",retryable:!1}:r===410?{reason:"expired",retryable:!1}:r===403?{reason:"refused",retryable:!1}:r===409?{reason:o??"refused",retryable:!1}:t==="unavailable"?{reason:"no-one-online",retryable:!0}:t==="unreachable"?{reason:"node-unreachable",retryable:!0}:o?{reason:o,retryable:!1}:{reason:"unknown",retryable:!0}}async function dn(n,e){let{namespaceId:t,invitation:r,teamName:o}=n,i=null;try{await e.join(t,r)}catch(d){i=d}let a=null;try{a=(await e.memberships()).includes(t)}catch{a=null}if(i===null)return{status:"joined",namespaceId:t,teamName:o};if(a===!0)return{status:"already-member",namespaceId:t,teamName:o};let s=At(i,"Could not join. Check the invitation."),{reason:c,retryable:u}=fo(i,s);return{status:"failed",namespaceId:t,message:s,reason:c,retryable:u}}var Me=class extends Error{constructor(t,r){super(`this node does not serve warrant-nonce discovery (404 on ${t}); it predates the route, so a client must fall back to its own nonce counter`);this.path=t;this.cause=r;this.name="WarrantNonceRouteUnavailableError"}};function Rt(n,e,t){let r=e[t];if(r==null)return;let o=new RegExp(`"${t}"\\s*:\\s*(\\d+)`).exec(n);if(o)return BigInt(o[1]);if(typeof r=="string"&&/^\d+$/.test(r))return BigInt(r);throw new Error(`warrant-nonce response field \`${t}\` is not a u64: ${JSON.stringify(r)}`)}function pn(n){let t=JSON.parse(n)?.data;if(!t||typeof t!="object")throw new Error(`warrant-nonce response had no \`data\`: ${n.slice(0,200)}`);let r={contextId:String(t.contextId??""),authorDeviceKey:String(t.authorDeviceKey??""),seen:t.seen===!0,highWaterNonce:Rt(n,t,"highWaterNonce"),windowWidth:Rt(n,t,"windowWidth")??0n},o=Rt(n,t,"nextNonce");return o===void 0?{...r,kind:"exhausted",seen:!0,highWaterNonce:r.highWaterNonce??0xffffffffffffffffn}:{...r,kind:"open",nextNonce:o}}function m(n){return n?.data}function yo(n,e){let[t,r]=gn(n),[o,i]=gn(e),a=t.split("."),s=o.split("."),c=Math.max(a.length,s.length);for(let p=0;p<c;p++){let b=mn(a[p]??"0",s[p]??"0");if(b!==0)return b}if(r===void 0&&i===void 0)return 0;if(r===void 0)return 1;if(i===void 0)return-1;let u=r.split("."),d=i.split("."),l=Math.max(u.length,d.length);for(let p=0;p<l;p++){if(p>=u.length)return-1;if(p>=d.length)return 1;let b=mn(u[p],d[p]);if(b!==0)return b}return 0}function gn(n){let e=n.split("+",1)[0],t=e.indexOf("-");return t===-1?[e,void 0]:[e.slice(0,t),e.slice(t+1)]}function mn(n,e){let t=/^\d+$/.test(n),r=/^\d+$/.test(e);if(t&&r){let o=Number(n)-Number(e);return o<0?-1:o>0?1:0}return t?-1:r?1:n<e?-1:n>e?1:0}async function bo(n,e,t){return Ne(async()=>{let r=await fetch(n,{signal:AbortSignal.timeout(1e4)});if(!r.ok){let o=new Error(`registry ${e} fetch failed (${r.status}) for ${t}`);throw o.status=r.status,o}return r},{attempts:3})}var Y=class{constructor(e){this.httpClient=e}async healthCheck(){return m(await this.httpClient.get("/admin-api/health"))}async readinessCheck(){return m(await this.httpClient.get("/admin-api/ready"))}async isAuthed(){return this.httpClient.get("/admin-api/is-authed")}async installApplication(e){return m(await this.httpClient.post("/admin-api/install-application",e))}async getRegistryVersions(e,t){let r=new URL("/api/v2/bundles",new URL(e).origin);r.searchParams.set("package",t);let i=await(await bo(r.toString(),"versions",t)).json();return(Array.isArray(i)?i:[]).map(a=>a.appVersion).filter(a=>typeof a=="string").sort((a,s)=>yo(s,a))}async installDevApplication(e){return m(await this.httpClient.post("/admin-api/install-dev-application",e))}async uninstallApplication(e){return m(await this.httpClient.delete(`/admin-api/applications/${e}`))}async listApplications(){return m(await this.httpClient.get("/admin-api/applications"))}async getApplication(e){return m(await this.httpClient.get(`/admin-api/applications/${e}`))}async listApplicationVersions(e){return m(await this.httpClient.get(`/admin-api/applications/${e}/versions`))}async getApplicationAbi(e,t){let r=t?`?service_name=${encodeURIComponent(t)}`:"";return m(await this.httpClient.get(`/admin-api/applications/${e}/abi${r}`))}async listPackages(){let e=await this.httpClient.get("/admin-api/packages");return e?.data??e}async listPackageVersions(e){let t=await this.httpClient.get(`/admin-api/packages/${encodeURIComponent(e)}/versions`);return t?.data??t}async getLatestPackageVersion(e){return this.httpClient.get(`/admin-api/packages/${encodeURIComponent(e)}/latest`)}async createContext(e){let t={...e,initializationParams:e.initializationParams??[]};return m(await this.httpClient.post("/admin-api/contexts",t))}async deleteContext(e){return m(await this.httpClient.delete(`/admin-api/contexts/${e}`))}async getContexts(){return m(await this.httpClient.get("/admin-api/contexts"))}async getContext(e){return m(await this.httpClient.get(`/admin-api/contexts/${e}`))}async getContextsForApplication(e){return m(await this.httpClient.get(`/admin-api/contexts/for-application/${e}`))}async generateContextIdentity(){return m(await this.httpClient.post("/admin-api/identity/context",{}))}async getContextIdentities(e){return m(await this.httpClient.get(`/admin-api/contexts/${e}/identities`))}async getContextIdentitiesOwned(e){return m(await this.httpClient.get(`/admin-api/contexts/${e}/identities-owned`))}async joinContext(e){return m(await this.httpClient.post(`/admin-api/contexts/${e}/join`,{}))}async getContextGroup(e){return m(await this.httpClient.get(`/admin-api/contexts/${e}/group`))}async getContextStorage(e){return m(await this.httpClient.get(`/admin-api/contexts/${e}/storage`))}async syncContext(e){let t=e?`/admin-api/contexts/sync/${e}`:"/admin-api/contexts/sync";await this.httpClient.post(t,{})}async resyncContext(e,t={}){return await this.httpClient.post(`/admin-api/contexts/${e}/resync`,t)??{contextId:e,resyncStarted:!0}}async inviteSpecializedNode(e){return m(await this.httpClient.post("/admin-api/contexts/invite-specialized-node",e))}async updateContextApplication(e,t){await this.httpClient.post(`/admin-api/contexts/${e}/application`,t)}async getContextsWithExecutorsForApplication(e){let t=await this.httpClient.get(`/admin-api/contexts/with-executors/for-application/${e}`);return Array.isArray(t)?t:t?.contexts??t?.data??[]}async uploadBlob(e){let t=new URLSearchParams;e.hash&&t.set("hash",e.hash),e.contextId&&t.set("context_id",e.contextId);let r=t.toString(),o=r?`/admin-api/blobs?${r}`:"/admin-api/blobs",i=m(await this.httpClient.request(o,{method:"PUT",body:e.data,headers:{"Content-Type":"application/octet-stream"}}));return{blobId:i.blob_id,size:i.size}}async deleteBlob(e){let t=await this.httpClient.delete(`/admin-api/blobs/${e}`);return{blobId:t.blob_id,deleted:t.deleted}}async listBlobs(){return{blobs:m(await this.httpClient.get("/admin-api/blobs")).blobs.map(t=>({blobId:t.blob_id,size:t.size}))}}blobPath(e,t){if(!t?.contextId)return`/admin-api/blobs/${e}`;let r=new URLSearchParams({context_id:t.contextId});return`/admin-api/blobs/${e}?${r.toString()}`}async getBlob(e,t){return this.httpClient.get(this.blobPath(e,t),{parse:"arrayBuffer"})}async getBlobInfo(e,t){let{headers:r}=await this.httpClient.head(this.blobPath(e,t)),o=Number(r["content-length"]);return{blobId:r["x-blob-id"]??e,size:Number.isFinite(o)?o:0,hash:r["x-blob-hash"],mimeType:r["x-blob-mime-type"],source:r["x-blob-source"]}}async createContextAlias(e){return m(await this.httpClient.post("/admin-api/alias/create/context",{alias:e.alias,contextId:e.contextId}))}async createApplicationAlias(e){return m(await this.httpClient.post("/admin-api/alias/create/application",{alias:e.alias,applicationId:e.applicationId}))}async lookupContextAlias(e){return m(await this.httpClient.post(`/admin-api/alias/lookup/context/${encodeURIComponent(e)}`,{}))}async lookupApplicationAlias(e){return m(await this.httpClient.post(`/admin-api/alias/lookup/application/${encodeURIComponent(e)}`,{}))}async deleteContextAlias(e){return m(await this.httpClient.post(`/admin-api/alias/delete/context/${encodeURIComponent(e)}`,{}))}async deleteApplicationAlias(e){return m(await this.httpClient.post(`/admin-api/alias/delete/application/${encodeURIComponent(e)}`,{}))}async listContextAliases(){return m(await this.httpClient.get("/admin-api/alias/list/context"))}async listApplicationAliases(){return m(await this.httpClient.get("/admin-api/alias/list/application"))}async createDeviceAlias(e){return m(await this.httpClient.post("/admin-api/alias/create/device",{alias:e.alias,deviceId:e.deviceId}))}async lookupDeviceAlias(e){return m(await this.httpClient.post(`/admin-api/alias/lookup/device/${encodeURIComponent(e)}`,{}))}async deleteDeviceAlias(e){return m(await this.httpClient.post(`/admin-api/alias/delete/device/${encodeURIComponent(e)}`,{}))}async listDeviceAliases(){return m(await this.httpClient.get("/admin-api/alias/list/device"))}async listNamespaces(){return m(await this.httpClient.get("/admin-api/namespaces"))}async getNamespace(e){return m(await this.httpClient.get(`/admin-api/namespaces/${e}`))}async getNodeIdentity(){return m(await this.httpClient.get("/admin-api/identity"))}async getNamespaceIdentity(e){let t=await this.getNodeIdentity();return{namespaceId:e,publicKey:t.publicKey,account:t.accountId}}async performIntent(e,t){return m(await this.httpClient.post(`/admin-api/contexts/${e}/intents`,t))}async queryContext(e,t){return m(await this.httpClient.post(`/admin-api/contexts/${e}/query`,t))}async getIntentRelay(e){return m(await this.httpClient.get(`/admin-api/contexts/${e}/intents`))}async listNamespacesForApplication(e){return m(await this.httpClient.get(`/admin-api/namespaces/for-application/${e}`))}async createNamespace(e){return m(await this.httpClient.post("/admin-api/namespaces",e))}async deleteNamespace(e){return m(await this.httpClient.request(`/admin-api/namespaces/${e}`,{method:"DELETE",body:"{}",headers:{"Content-Type":"application/json"}}))}async createNamespaceInvitation(e,t){return m(await this.httpClient.post(`/admin-api/namespaces/${e}/invite`,t??{}))}async admitJoin(e,t){return m(await this.httpClient.post(`/admin-api/namespaces/${e}/admit`,t,{timeoutMs:65e3}))}async joinNamespace(e,t){let r=m(await this.httpClient.post(`/admin-api/namespaces/${e}/join`,t,{timeoutMs:65e3}));return r&&r.namespaceId===void 0&&r.groupId!==void 0?{...r,namespaceId:r.groupId}:r}async redeemInvitation(e,t,r={}){let{groupName:o,teamName:i}=r;return dn({namespaceId:e,invitation:t,teamName:i},{join:async()=>{await this.joinNamespace(e,o===void 0?{invitation:t}:{invitation:t,groupName:o})},memberships:async()=>(await this.listNamespaces()??[]).map(a=>a.namespaceId)})}async createGroupInNamespace(e,t){return m(await this.httpClient.post(`/admin-api/namespaces/${e}/groups`,t??{}))}async listNamespaceGroups(e){return m(await this.httpClient.get(`/admin-api/namespaces/${e}/groups`))}async initAccountPairing(e){return m(await this.httpClient.post("/admin-api/account/pair-init",e))}async completeAccountPairing(e){return m(await this.httpClient.post("/admin-api/account/pair-complete",e))}async relinkAccountDevice(e,t){return m(await this.httpClient.post(`/admin-api/account/devices/${e}/relink`,t??{}))}async rescopeAccountDevice(e,t){return m(await this.httpClient.put(`/admin-api/account/devices/${encodeURIComponent(e)}/scope`,t))}async signWithAccountRoot(e){return m(await this.httpClient.post("/admin-api/account/sign-with-root",e))}async labelAccountDevice(e,t){return m(await this.httpClient.put(`/admin-api/account/devices/${encodeURIComponent(e)}/label`,t))}async listAccountDevices(){return(await this.httpClient.get("/admin-api/account/devices")).devices}async listAccountApplications(){return(await this.httpClient.get("/admin-api/account/applications")).applications}async revokeAccountDevice(e,t){return m(await this.httpClient.post(`/admin-api/namespaces/${e}/account/revoke`,t))}async getGroupInfo(e){return m(await this.httpClient.get(`/admin-api/groups/${e}`))}async getDefaultCapabilities(e){return(await this.getGroupInfo(e)).defaultCapabilities}async getSubgroupVisibility(e){return(await this.getGroupInfo(e)).subgroupVisibility}async deleteGroup(e){return m(await this.httpClient.request(`/admin-api/groups/${e}`,{method:"DELETE",body:"{}",headers:{"Content-Type":"application/json"}}))}async listGroupMembers(e){let t=await this.httpClient.get(`/admin-api/groups/${e}/members`);if(!Array.isArray(t?.members)){let r=String(e).replace(/[\r\n\t\s]/g,"").slice(0,64);throw new Error(`Invalid listGroupMembers response for group ${r}: missing or non-array \`members\` field`)}return t}async listGroupMemberDevices(e,t){let r=new URLSearchParams;t?.offset!==void 0&&r.set("offset",String(t.offset)),t?.limit!==void 0&&r.set("limit",String(t.limit));let o=r.toString(),i=`/admin-api/groups/${encodeURIComponent(e)}/member-devices`;return(await this.httpClient.get(o?`${i}?${o}`:i)).members}async getWarrantNonce(e,t){let r=`/admin-api/contexts/${encodeURIComponent(e)}/warrant-nonce/${encodeURIComponent(t)}`,o;try{o=await this.httpClient.get(r,{parse:"text"})}catch(i){throw i instanceof C&&i.status===404?new Me(r,i):i}return pn(o)}async getWarrantNonceAsAuthor(e,t){let r=`/admin-api/contexts/${encodeURIComponent(e)}/warrant-nonce`,o;try{o=await this.httpClient.post(r,{authorProof:t},{parse:"text"})}catch(i){throw i instanceof C&&i.status===404?new Me(r,i):i}return pn(o)}async listMemberDevices(e,t={}){let r=new URLSearchParams;t.offset!==void 0&&r.set("offset",String(t.offset)),t.limit!==void 0&&r.set("limit",String(t.limit));let o=r.toString(),i=`/admin-api/groups/${e}/member-devices${o?`?${o}`:""}`;return this.httpClient.get(i)}async sealToAccount(e,t,r){return m(await this.httpClient.post(`/admin-api/groups/${e}/accounts/${t}/seal`,r))}async listGroupContexts(e){return m(await this.httpClient.get(`/admin-api/groups/${e}/contexts`))}async addGroupMembers(e,t){await this.httpClient.post(`/admin-api/groups/${e}/members`,t)}async removeGroupMembers(e,t){await this.httpClient.post(`/admin-api/groups/${e}/members/remove`,t)}async updateMemberRole(e,t,r){await this.httpClient.put(`/admin-api/groups/${e}/members/${t}/role`,r)}async getMemberCapabilities(e,t){return m(await this.httpClient.get(`/admin-api/groups/${e}/members/${t}/capabilities`))}async setMemberCapabilities(e,t,r){await this.httpClient.put(`/admin-api/groups/${e}/members/${t}/capabilities`,r)}async setDefaultCapabilities(e,t){await this.httpClient.put(`/admin-api/groups/${e}/settings/default-capabilities`,t)}async openToDelegatedExecution(e){let t=await this.getDefaultCapabilities(e);if(oe(t,P.CAN_AUTHOR_ON_BEHALF))return{changed:!1,defaultCapabilities:t};let r=wt(t,P.CAN_AUTHOR_ON_BEHALF);return await this.setDefaultCapabilities(e,{defaultCapabilities:r}),{changed:!0,defaultCapabilities:r}}async grantAuthorship(e,t){let{capabilities:r}=await this.getMemberCapabilities(e,t);if(oe(r,P.CAN_AUTHOR_ON_BEHALF))return{changed:!1,capabilities:r};let o=wt(r,P.CAN_AUTHOR_ON_BEHALF);return await this.setMemberCapabilities(e,t,{capabilities:o}),{changed:!0,capabilities:o}}async setSubgroupVisibility(e,t){await this.httpClient.put(`/admin-api/groups/${e}/settings/subgroup-visibility`,t)}async setTeeAdmissionPolicy(e,t){await this.httpClient.put(`/admin-api/groups/${e}/settings/tee-admission-policy`,t)}async getTeeAdmissionPolicy(e){let t=await this.httpClient.get(`/admin-api/groups/${e}/settings/tee-admission-policy`);return t.data??t}async setTeeAuthoringPolicy(e,t){await this.httpClient.put(`/admin-api/groups/${e}/settings/tee-authoring-policy`,t)}async disableTeeAuthoringPolicy(e){await this.httpClient.delete(`/admin-api/groups/${e}/settings/tee-authoring-policy`)}async setGroupMetadata(e,t){await this.httpClient.put(`/admin-api/groups/${e}/metadata`,t)}async getGroupMetadata(e){return(await this.httpClient.get(`/admin-api/groups/${e}/metadata`))?.data??null}async setMemberMetadata(e,t,r){await this.httpClient.put(`/admin-api/groups/${e}/members/${t}/metadata`,r)}async getMemberMetadata(e,t){return(await this.httpClient.get(`/admin-api/groups/${e}/members/${t}/metadata`))?.data??null}async setContextMetadata(e,t,r){await this.httpClient.put(`/admin-api/groups/${e}/contexts/${t}/metadata`,r)}async getContextMetadata(e,t){return(await this.httpClient.get(`/admin-api/groups/${e}/contexts/${t}/metadata`))?.data??null}async syncGroup(e){return m(await this.httpClient.post(`/admin-api/groups/${e}/sync`,{}))}async upgradeGroup(e,t){return m(await this.httpClient.post(`/admin-api/groups/${e}/upgrade`,t))}async getGroupUpgradeStatus(e){return m(await this.httpClient.get(`/admin-api/groups/${e}/upgrade/status`))}async getMigrationStatus(e){let t=encodeURIComponent(e);return this.httpClient.get(`/admin-api/groups/${t}/migration-status`)}async getCascadeStatus(e){let t=encodeURIComponent(e);return m(await this.httpClient.get(`/admin-api/groups/${t}/cascade-status`))}async retryGroupUpgrade(e){return m(await this.httpClient.post(`/admin-api/groups/${e}/upgrade/retry`,{}))}async reparentGroup(e,t){let r=await this.httpClient.post(`/admin-api/groups/${e}/reparent`,t);return r?.data??r}async listSubgroups(e){let t=await this.httpClient.get(`/admin-api/groups/${e}/subgroups`);return t.subgroups??t.data??[]}async detachContextFromGroup(e,t){await this.httpClient.post(`/admin-api/groups/${e}/contexts/${t}/remove`,{})}async createGroupInvitation(e,t){return m(await this.httpClient.post(`/admin-api/groups/${e}/invite`,t??{}))}async joinGroup(e){return m(await this.httpClient.post("/admin-api/groups/join",e))}async joinSubgroupInheritance(e){return m(await this.httpClient.post(`/admin-api/groups/${e}/join-via-inheritance`,{}))}async getTeeInfo(){return m(await this.httpClient.get("/admin-api/tee/info"))}async teeAttest(e){return m(await this.httpClient.post("/admin-api/tee/attest",e))}async teeVerifyQuote(e){return m(await this.httpClient.post("/admin-api/tee/verify-quote",e))}async getPeersCount(){return this.httpClient.get("/admin-api/peers")}async getNetworkStatus(){return this.httpClient.get("/admin-api/network/status")}async getUsage(){return this.httpClient.get("/admin-api/usage")}async createGroup(e){return m(await this.httpClient.post("/admin-api/groups",e))}async leaveGroup(e){await this.httpClient.post(`/admin-api/groups/${e}/leave`,{})}async leaveContext(e){await this.httpClient.post(`/admin-api/contexts/${e}/leave`,{})}async leaveNamespace(e){await this.httpClient.post(`/admin-api/namespaces/${e}/leave`,{})}async issueOwnershipProof(e,t){return this.httpClient.post(`/admin-api/groups/${e}/issue-ownership-proof`,t)}async issueNamespaceOwnershipProof(e,t){return this.httpClient.post(`/admin-api/groups/${e}/issue-namespace-ownership-proof`,t)}async setMemberAutoFollow(e,t,r){await this.httpClient.put(`/admin-api/groups/${e}/members/${t}/auto-follow`,r)}async abortMigration(e){return this.httpClient.post(`/admin-api/groups/${e}/migration/abort`,{})}};function Ra(n){return Array.from(new TextEncoder().encode(n),e=>e.toString(16).padStart(2,"0")).join("")}function Ea(n){return new Y(re(n))}function Ta(n){return new Y(Ue(n))}function hn(n){return new Y(bt(n))}function _e(n,e){return new Y(n)}function vt(n){try{let e=n.indexOf("#");if(e===-1)return null;let t=n.substring(e+1),r=new URLSearchParams(t),o=r.get("access_token");return o?{accessToken:o,refreshToken:r.get("refresh_token")??"",applicationId:r.get("application_id")??"",contextId:r.get("context_id")??"",contextIdentity:r.get("context_identity")??"",nodeUrl:r.get("node_url")??""}:null}catch{return null}}function Ct(n,e){let t=new URLSearchParams;return t.set("callback-url",e.callbackUrl),e.permissions&&e.permissions.length>0&&t.set("permissions",e.permissions.join(",")),t.set("mode",e.mode),e.packageName&&(t.set("package-name",e.packageName),e.packageVersion&&t.set("package-version",e.packageVersion),e.registryUrl&&t.set("registry-url",e.registryUrl)),`${n.replace(/\/+$/,"")}/auth/login?${t.toString()}`}var fn=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,112,4,34,4,32]);function x(n){let e=new Uint8Array(4);return new DataView(e.buffer).setUint32(0,n,!0),e}function h(n){return Array.from(n,e=>e.toString(16).padStart(2,"0")).join("")}function g(n,e,t){let r=n.trim();if(!/^[0-9a-fA-F]*$/.test(r)||r.length!==t*2)throw new Error(`${e} must be ${t*2} hex characters, got ${r.length}`);let o=new Uint8Array(t);for(let i=0;i<t;i+=1)o[i]=Number.parseInt(r.slice(i*2,i*2+2),16);return o}function ie(n,e){let t=n.trim();if(!/^[0-9a-fA-F]*$/.test(t)||t.length%2!==0)throw new Error(`${e} must be an even number of hex characters`);let r=new Uint8Array(t.length/2);for(let o=0;o<r.length;o+=1)r[o]=Number.parseInt(t.slice(o*2,o*2+2),16);return r}function A(n){let e=new Uint8Array(8);return new DataView(e.buffer).setBigUint64(0,BigInt(n),!0),e}function f(...n){let e=new Uint8Array(n.reduce((r,o)=>r+o.length,0)),t=0;for(let r of n)e.set(r,t),t+=r.length;return e}async function k(n,e){let t=[A(n.length),n];for(let r of e)t.push(A(r.length),r);return new Uint8Array(await crypto.subtle.digest("SHA-256",f(...t)))}async function se(n){let e=g(n,"deviceSecret",32),t=f(fn,e);try{return await crypto.subtle.importKey("pkcs8",t,{name:"Ed25519"},!1,["sign"])}catch(r){let o=r instanceof Error?`: ${r.message}`:"";throw new Error("this runtime has no WebCrypto Ed25519, so a warrant cannot be signed here. Node 18.4+, Safari 17+, Firefox 129+ and Chrome 137+ have it; otherwise mint the warrant with `merod account warrant`"+o)}}async function yn(n,e,t){let r=await crypto.subtle.importKey("raw",g(n,"publicKey",32),{name:"Ed25519"},!1,["verify"]);return crypto.subtle.verify({name:"Ed25519"},r,e,t)}async function ae(n){let e=g(n,"deviceSecret",32),t=f(fn,e),r=await crypto.subtle.importKey("pkcs8",t,{name:"Ed25519"},!0,["sign"]),i=(await crypto.subtle.exportKey("jwk",r)).x;return Uint8Array.from(atob(i.replace(/-/g,"+").replace(/_/g,"/")),a=>a.charCodeAt(0))}var wo=new TextEncoder().encode("calimero.auth.request.v1"),Ao=new TextEncoder().encode("calimero.auth.request.body.v1");function bn(n){let e=new TextEncoder().encode(n);return f(x(e.length),e)}async function kt(n=new Uint8Array(0)){let e=typeof n=="string"?new TextEncoder().encode(n):n;return k(Ao,[e])}async function Oe(n){let e=await se(n.signerSecret),t=await kt(n.body),r=A(n.issuedAt),o=A(n.expiresAt),i=new TextEncoder,a=await k(wo,[i.encode(n.method),i.encode(n.path),t,r,o]),s=new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},e,a));return h(f(bn(n.method),bn(n.path),t,r,o,s))}function Ge(n){let e=ie(n.credential,"credential"),t=ie(n.request,"request signature"),r=n.session===void 0?new Uint8Array([0]):f(new Uint8Array([1]),ie(n.session,"session statement"));return h(f(e,r,t))}function xo(n){if(n==null)return new Uint8Array(0);if(typeof n=="string"||n instanceof Uint8Array)return n;if(n instanceof ArrayBuffer)return new Uint8Array(n);if(ArrayBuffer.isView(n))return new Uint8Array(n.buffer,n.byteOffset,n.byteLength);throw new Error(`a request-carried proof cannot commit to a ${n?.constructor?.name??typeof n} body: pass a string or bytes, or use a session for this call`)}function He(n){let e=n.ttlSeconds??120,t=n.now??(()=>Math.floor(Date.now()/1e3));return async r=>{let o=t();return Ge({credential:n.credential,session:n.session,request:await Oe({method:r.method,path:r.path,body:xo(r.body),issuedAt:o,expiresAt:o+e,signerSecret:n.signerSecret})})}}var $e=class extends Error{constructor(e,t,r,o){super(t),this.name="RpcError",this.code=e,this.data=r,this.type=o}};async function St(n,e,t){let r=await n.post("/jsonrpc",{jsonrpc:"2.0",id:1,method:e,params:t});if(r.error){let o=r.error;throw new $e(o.code??-1,o.message??o.type??"RPC error",o.data,o.type)}return r.result}var Ae=class{constructor(e){this.kind="node";this.canSubscribe=!0;this.httpClient=e.httpClient}async execute(e){let t=await St(this.httpClient,"execute",{contextId:e.contextId,method:e.method,argsJson:e.argsJson??{}});return t&&"output"in t?t.output:t}async executeWithMetadata(e){return{returns:await this.execute(e),transport:"node"}}async migrateMyEntries(e){return this.execute({contextId:e,method:"migrate_my_entries"})}async countMyPending(e){return this.execute({contextId:e,method:"count_my_pending"})}};var Ro=new Set(["MigrationStarted","MigrationProgress","CascadeProgress","MigrationCompleted"]);function wn(n){return n.type!==void 0&&Ro.has(n.type)}var vo=new Set(["token_reuse","token_revoked"]),Co=new Set([401,403]);function An(n){let e=n.headers.get("x-auth-error");return!e||!Co.has(n.status)?null:vo.has(e)?e:null}var M=class{constructor(e){this.sessionId=null;this.abortController=null;this.reconnectTimer=null;this.subscribedContextIds=new Set;this.subscribedGroupIds=new Set;this.closed=!1;this.listeners={connect:[],event:[],error:[]};if(this.baseUrl=e.baseUrl.replace(/\/+$/,""),e.authorize)this.authorize=e.authorize;else if(e.getAuthToken){let t=e.getAuthToken;this.authorize=async()=>({Authorization:`Bearer ${await t()}`})}else throw new Error("SseClient needs either `getAuthToken` or `authorize`");this.reconnectDelayMs=e.reconnectDelayMs??3e3,this.fetchImpl=(t,r)=>e.fetch?e.fetch(t,r):globalThis.fetch(t,r)}on(e,t){let r=e;if(r in this.listeners){let o=this.listeners[r];o.includes(t)||o.push(t)}}off(e,t){let r=e;if(r in this.listeners){let o=this.listeners[r],i=o.indexOf(t);i!==-1&&o.splice(i,1)}}onAppVersionChanged(e){let t=r=>{if(r.type!=="AppVersionChanged")return;let o=r.data;e({contextId:r.contextId,fromVersion:o?.fromVersion,toVersion:o?.toVersion})};return this.on("event",t),()=>this.off("event",t)}onMigrationEvent(e){let t=r=>{wn(r)&&e(r)};return this.on("event",t),()=>this.off("event",t)}emit(e,t){let r=e;if(r in this.listeners)for(let o of this.listeners[r])try{o(t)}catch{}}async connect(){if(!(this.abortController&&!this.closed)){this.closed=!1,this.abortController=new AbortController;try{let e=`${this.baseUrl}/sse`,t=await this.fetchImpl(e,{headers:{...await this.authorize({method:"GET",path:new URL(e).pathname}),Accept:"text/event-stream"},signal:this.abortController.signal});if(!t.ok){let r=An(t),o=await t.text().catch(()=>{});throw r?new L(r,t.status,t.statusText,e,t.headers,o):new C(t.status,t.statusText,e,t.headers,o)}if(!t.body)throw new Error("SSE response has no body");this.readStream(t.body).catch(r=>{if(this.closed)return;let o=r instanceof Error?r:new Error(String(r));this.emit("error",o),this.scheduleReconnect()})}catch(e){if(this.closed)return;let t=e instanceof Error?e:new Error(String(e));if(this.emit("error",t),t instanceof L)return;this.scheduleReconnect()}}}async readStream(e){let t=e.getReader(),r=new TextDecoder,o="";try{for(;;){let{done:i,value:a}=await t.read();if(i)break;o+=r.decode(a,{stream:!0});let s=o.split(`
2
- `);o=s.pop()??"";for(let c of s)if(c.startsWith("data:")){let u=c.slice(5).trim();u&&this.handleMessage(u)}}if(o+=r.decode(),o.startsWith("data:")){let i=o.slice(5).trim();i&&this.handleMessage(i)}}catch(i){if(this.closed)return;let a=i instanceof Error?i:new Error(String(i));this.emit("error",a)}this.closed||this.scheduleReconnect()}handleMessage(e){try{let t=JSON.parse(e);if(t.type==="connect"&&t.session_id){this.sessionId=t.session_id,this.emit("connect",t.session_id),(this.subscribedContextIds.size>0||this.subscribedGroupIds.size>0)&&this.sendSubscription("subscribe",{contextIds:[...this.subscribedContextIds],groupIds:[...this.subscribedGroupIds]});return}if(!t.result)return;let r=t.result.data;if(Array.isArray(r))try{let o=new Uint8Array(r),i=new TextDecoder().decode(o);r=JSON.parse(i)}catch{}if(t.result.contextId){this.emit("event",{contextId:t.result.contextId,type:t.result.type,data:r});return}t.result.groupId&&this.emit("event",{groupId:t.result.groupId,type:t.result.type,data:r})}catch{}}async subscribe(e){let t=Array.isArray(e)?{contextIds:e}:e,r=(t.contextIds??[]).filter(i=>!this.subscribedContextIds.has(i)),o=(t.groupIds??[]).filter(i=>!this.subscribedGroupIds.has(i));for(let i of t.contextIds??[])this.subscribedContextIds.add(i);for(let i of t.groupIds??[])this.subscribedGroupIds.add(i);(r.length>0||o.length>0)&&this.sessionId&&await this.sendSubscription("subscribe",{contextIds:r,groupIds:o})}async unsubscribe(e){let t=Array.isArray(e)?{contextIds:e}:e,r=(t.contextIds??[]).filter(i=>this.subscribedContextIds.has(i)),o=(t.groupIds??[]).filter(i=>this.subscribedGroupIds.has(i));for(let i of t.contextIds??[])this.subscribedContextIds.delete(i);for(let i of t.groupIds??[])this.subscribedGroupIds.delete(i);(r.length>0||o.length>0)&&this.sessionId&&await this.sendSubscription("unsubscribe",{contextIds:r,groupIds:o})}async sendSubscription(e,t){try{let r={};t.contextIds&&t.contextIds.length>0&&(r.contextIds=t.contextIds),t.groupIds&&t.groupIds.length>0&&(r.groupIds=t.groupIds);let o=`${this.baseUrl}/sse/subscription`,i=JSON.stringify({id:this.sessionId,method:e,params:r}),a=await this.fetchImpl(o,{method:"POST",headers:{...await this.authorize({method:"POST",path:new URL(o).pathname,body:i}),"Content-Type":"application/json"},body:i});if(!a.ok){let s=An(a),c=await a.text().catch(()=>{});this.emit("error",s?new L(s,a.status,a.statusText,`${this.baseUrl}/sse/subscription`,a.headers,c):new C(a.status,a.statusText,`${this.baseUrl}/sse/subscription`,a.headers,c))}}catch(r){this.emit("error",r instanceof Error?r:new Error(`SSE ${e} failed`))}}forceReconnect(){this.abortController&&(this.abortController.abort(),this.abortController=null),this.sessionId=null,this.connect()}scheduleReconnect(){this.closed||(this.reconnectTimer&&clearTimeout(this.reconnectTimer),this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.forceReconnect()},this.reconnectDelayMs))}close(){this.closed=!0,this.abortController&&(this.abortController.abort(),this.abortController=null),this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.sessionId=null,this.subscribedContextIds.clear(),this.subscribedGroupIds.clear()}};var qe=class qe{constructor(e){this.ws=null;this.closed=!1;this.reconnectAttempt=0;this.reconnectTimer=null;this.subscribedContextIds=new Set;this.subscribedGroupIds=new Set;this.listeners={connect:[],event:[],error:[]};this.baseUrl=e.baseUrl.replace(/\/+$/,""),this.getAuthToken=e.getAuthToken}on(e,t){let r=e;if(r in this.listeners){let o=this.listeners[r];o.includes(t)||o.push(t)}}off(e,t){let r=e;if(r in this.listeners){let o=this.listeners[r],i=o.indexOf(t);i!==-1&&o.splice(i,1)}}emit(e,t){let r=e;if(r in this.listeners)for(let o of this.listeners[r])try{o(t)}catch{}}async connect(){if(!(this.ws&&(this.ws.readyState===0||this.ws.readyState===1))){this.closed=!1;try{let e=await this.getAuthToken();if(!e)throw new Error("No authentication token available for WebSocket connection");let t=this.baseUrl.replace(/^http/,"ws");this.ws=new WebSocket(`${t}/ws?token=${encodeURIComponent(e)}`),this.ws.onopen=()=>{this.reconnectAttempt=0,this.emit("connect"),this.resubscribeAfterReconnect()},this.ws.onmessage=r=>{this.handleMessage(r.data)},this.ws.onerror=()=>{this.emit("error",new Error("WebSocket error"))},this.ws.onclose=()=>{this.closed||this.scheduleReconnect()}}catch(e){if(this.closed)return;let t=e instanceof Error?e:new Error(String(e));this.emit("error",t),this.scheduleReconnect()}}}handleMessage(e){if(typeof e=="string")try{let t=JSON.parse(e);if(!t.result)return;let r=t.result.data;if(Array.isArray(r))try{let o=new Uint8Array(r),i=new TextDecoder().decode(o);r=JSON.parse(i)}catch{}if(t.result.contextId){this.emit("event",{contextId:t.result.contextId,type:t.result.type,data:r});return}t.result.groupId&&this.emit("event",{groupId:t.result.groupId,type:t.result.type,data:r})}catch{}}subscribe(e){let t=Array.isArray(e)?{contextIds:e}:e;for(let r of t.contextIds??[])this.subscribedContextIds.add(r);for(let r of t.groupIds??[])this.subscribedGroupIds.add(r);this.ws&&this.ws.readyState===1&&this.sendMessage({id:null,method:"subscribe",params:this.buildSubscriptionParams(t.contextIds??[],t.groupIds??[])})}unsubscribe(e){let t=Array.isArray(e)?{contextIds:e}:e;for(let r of t.contextIds??[])this.subscribedContextIds.delete(r);for(let r of t.groupIds??[])this.subscribedGroupIds.delete(r);this.ws&&this.ws.readyState===1&&this.sendMessage({id:null,method:"unsubscribe",params:this.buildSubscriptionParams(t.contextIds??[],t.groupIds??[])})}resubscribeAfterReconnect(){this.subscribedContextIds.size===0&&this.subscribedGroupIds.size===0||this.sendMessage({id:null,method:"subscribe",params:this.buildSubscriptionParams([...this.subscribedContextIds],[...this.subscribedGroupIds])})}buildSubscriptionParams(e,t){let r={};return e.length>0&&(r.contextIds=e),t.length>0&&(r.groupIds=t),r}sendMessage(e){this.ws&&this.ws.readyState===1&&this.ws.send(JSON.stringify(e))}scheduleReconnect(){if(this.closed)return;this.reconnectTimer&&clearTimeout(this.reconnectTimer);let e=Math.min(1e3*Math.pow(2,this.reconnectAttempt),qe.MAX_BACKOFF_MS);this.reconnectAttempt++,this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.connect()},e)}close(){this.closed=!0,this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.ws&&(this.ws.onclose=null,this.ws.close(),this.ws=null),this.subscribedContextIds.clear(),this.subscribedGroupIds.clear()}};qe.MAX_BACKOFF_MS=3e4;var K=qe;function Le(){return{encode(n){return Array.from(new TextEncoder().encode(JSON.stringify(n)))},decode(n){return JSON.parse(new TextDecoder().decode(new Uint8Array(n)))}}}var xe=class{constructor(e){this.httpClient=e.httpClient,this.sse=e.sse}async set(e,t,r=Le()){await St(this.httpClient,"set_ephemeral",{contextId:e,state:r.encode(t)})}subscribe(e,t,r=Le()){let o=i=>{let a=i;if(a.type!=="Ephemeral"||a.contextId!==e)return;let s=a.data;if(!s?.author)return;let c=!!s.removed,u={author:s.author,state:c||s.state===void 0?void 0:r.decode(s.state),removed:c};s.ageMs!==void 0&&(u.ageMs=s.ageMs),t(u)};return this.sse.on("event",o),this.sse.connect().catch(()=>{}),this.sse.subscribe([e]).catch(()=>{}),()=>{this.sse.off("event",o)}}};var ko=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,112,4,34,4,32]);function xn(n){let e=n instanceof Error?`: ${n.message}`:"";return new Error("this runtime has no WebCrypto Ed25519, so nothing can be signed here. Node 18.4+, Safari 17+, Firefox 129+ and Chrome 137+ have it"+e)}async function ce(n,e="secret"){let t=g(n,e,32),r=f(ko,t),o,i;try{let a=await crypto.subtle.importKey("pkcs8",r,{name:"Ed25519"},!0,["sign"]),s=await crypto.subtle.exportKey("jwk",a);i=h(Uint8Array.from(atob(s.x.replace(/-/g,"+").replace(/_/g,"/")),c=>c.charCodeAt(0))),o=await crypto.subtle.importKey("pkcs8",r,{name:"Ed25519"},!1,["sign"])}catch(a){throw xn(a)}return vn(o,i)}async function Rn(n,e){if(n.type!=="private")throw new Error(`signerFromCryptoKey needs the private half of the pair, got a ${n.type} key`);if(!n.usages.includes("sign"))throw new Error("this CryptoKey cannot sign: generate it with usages ['sign', 'verify']");let t;if(typeof e=="string")g(e,"publicKey",32),t=e.trim().toLowerCase();else try{t=h(new Uint8Array(await crypto.subtle.exportKey("raw",e)))}catch(r){let o=r instanceof Error?`: ${r.message}`:"";throw new Error("could not read the public half of this key pair; pass the public key as 64 hex instead"+o)}return vn(n,t)}function vn(n,e){return{publicKey:e,async sign(t){try{return new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},n,t))}catch(r){throw xn(r)}}}}async function S(n,e,t){if(e&&n!==void 0)throw new Error(`pass either ${t} or signer, not both \u2014 they may name different keys`);if(e)return e;if(n!==void 0)return ce(n,t);throw new Error(`${t} or signer is required`)}var So=new TextEncoder().encode("calimero.device.cert.v1"),Eo=new TextEncoder().encode("calimero.account.genesis.v1"),To=new TextEncoder().encode("calimero.device.id.v1"),Ke=2,Po=237;async function Cn(n,e){if(e.length!==16)throw new Error(`nonce must be 16 bytes, got ${e.length}`);let t=g(n,"account",32);return h(await k(To,[t,e]))}async function Be(n){return k(So,[g(n.account,"account",32),g(n.device,"device",32),g(n.signPublicKey,"signPublicKey",32),g(n.kemPublicKey,"kemPublicKey",32),x(n.keyEpoch),x(n.deviceEpoch)])}function kn(n){return f(new Uint8Array([Ke]),n.rootPublicKey,x(0),g(n.account,"account",32),g(n.device,"device",32),g(n.signPublicKey,"signPublicKey",32),g(n.kemPublicKey,"kemPublicKey",32),x(n.keyEpoch),x(n.deviceEpoch),n.signature)}async function Sn(n){let e=await S(n.rootSecret,n.signer,"rootSecret"),t=g(e.publicKey,"signer.publicKey",32),r=await B(e.publicKey),o=0,i=await Be({account:r,device:n.device,signPublicKey:n.signPublicKey,kemPublicKey:n.kemPublicKey,keyEpoch:o,deviceEpoch:n.deviceEpoch}),a=await e.sign(i),s=kn({rootPublicKey:t,account:r,device:n.device,signPublicKey:n.signPublicKey,kemPublicKey:n.kemPublicKey,keyEpoch:o,deviceEpoch:n.deviceEpoch,signature:a});return h(s)}function Et(n){let e=g(n,"credential",Po);if(e[0]!==Ke)throw new Error(`this credential has account genesis version ${e[0]}, not ${Ke} \u2014 it names a different account than its root key derives here, and core would refuse it`);let t=new DataView(e.buffer,e.byteOffset,e.byteLength),r=t.getUint32(33,!0);if(r!==0)throw new Error(`this credential carries a ${r}-handoff root chain, which this SDK cannot verify yet \u2014 the signing root is not the genesis root, so checking it means walking the chain`);let o=(i,a)=>h(e.subarray(i,i+a));return{rootPublicKey:o(1,32),account:o(37,32),device:o(69,32),signPublicKey:o(101,32),kemPublicKey:o(133,32),keyEpoch:t.getUint32(165,!0),deviceEpoch:t.getUint32(169,!0),signature:o(173,64)}}async function je(n){let e=Et(n),t=await B(e.rootPublicKey);if(t!==e.account)throw new Error(`this credential names account ${e.account}, but its root key derives ${t} \u2014 the certificate was re-pointed at another account`);if(!await yn(e.rootPublicKey,g(e.signature,"signature",64),await Be(e)))throw new Error(`the root key of account ${e.account} did not sign this certificate`);return e}async function Fe(n){return B(h(await ae(n)))}async function B(n){return h(await k(Eo,[f(new Uint8Array([Ke]),g(n,"rootPublicKey",32))]))}var Tt=["abandon","ability","able","about","above","absent","absorb","abstract","absurd","abuse","access","accident","account","accuse","achieve","acid","acoustic","acquire","across","act","action","actor","actress","actual","adapt","add","addict","address","adjust","admit","adult","advance","advice","aerobic","affair","afford","afraid","again","age","agent","agree","ahead","aim","air","airport","aisle","alarm","album","alcohol","alert","alien","all","alley","allow","almost","alone","alpha","already","also","alter","always","amateur","amazing","among","amount","amused","analyst","anchor","ancient","anger","angle","angry","animal","ankle","announce","annual","another","answer","antenna","antique","anxiety","any","apart","apology","appear","apple","approve","april","arch","arctic","area","arena","argue","arm","armed","armor","army","around","arrange","arrest","arrive","arrow","art","artefact","artist","artwork","ask","aspect","assault","asset","assist","assume","asthma","athlete","atom","attack","attend","attitude","attract","auction","audit","august","aunt","author","auto","autumn","average","avocado","avoid","awake","aware","away","awesome","awful","awkward","axis","baby","bachelor","bacon","badge","bag","balance","balcony","ball","bamboo","banana","banner","bar","barely","bargain","barrel","base","basic","basket","battle","beach","bean","beauty","because","become","beef","before","begin","behave","behind","believe","below","belt","bench","benefit","best","betray","better","between","beyond","bicycle","bid","bike","bind","biology","bird","birth","bitter","black","blade","blame","blanket","blast","bleak","bless","blind","blood","blossom","blouse","blue","blur","blush","board","boat","body","boil","bomb","bone","bonus","book","boost","border","boring","borrow","boss","bottom","bounce","box","boy","bracket","brain","brand","brass","brave","bread","breeze","brick","bridge","brief","bright","bring","brisk","broccoli","broken","bronze","broom","brother","brown","brush","bubble","buddy","budget","buffalo","build","bulb","bulk","bullet","bundle","bunker","burden","burger","burst","bus","business","busy","butter","buyer","buzz","cabbage","cabin","cable","cactus","cage","cake","call","calm","camera","camp","can","canal","cancel","candy","cannon","canoe","canvas","canyon","capable","capital","captain","car","carbon","card","cargo","carpet","carry","cart","case","cash","casino","castle","casual","cat","catalog","catch","category","cattle","caught","cause","caution","cave","ceiling","celery","cement","census","century","cereal","certain","chair","chalk","champion","change","chaos","chapter","charge","chase","chat","cheap","check","cheese","chef","cherry","chest","chicken","chief","child","chimney","choice","choose","chronic","chuckle","chunk","churn","cigar","cinnamon","circle","citizen","city","civil","claim","clap","clarify","claw","clay","clean","clerk","clever","click","client","cliff","climb","clinic","clip","clock","clog","close","cloth","cloud","clown","club","clump","cluster","clutch","coach","coast","coconut","code","coffee","coil","coin","collect","color","column","combine","come","comfort","comic","common","company","concert","conduct","confirm","congress","connect","consider","control","convince","cook","cool","copper","copy","coral","core","corn","correct","cost","cotton","couch","country","couple","course","cousin","cover","coyote","crack","cradle","craft","cram","crane","crash","crater","crawl","crazy","cream","credit","creek","crew","cricket","crime","crisp","critic","crop","cross","crouch","crowd","crucial","cruel","cruise","crumble","crunch","crush","cry","crystal","cube","culture","cup","cupboard","curious","current","curtain","curve","cushion","custom","cute","cycle","dad","damage","damp","dance","danger","daring","dash","daughter","dawn","day","deal","debate","debris","decade","december","decide","decline","decorate","decrease","deer","defense","define","defy","degree","delay","deliver","demand","demise","denial","dentist","deny","depart","depend","deposit","depth","deputy","derive","describe","desert","design","desk","despair","destroy","detail","detect","develop","device","devote","diagram","dial","diamond","diary","dice","diesel","diet","differ","digital","dignity","dilemma","dinner","dinosaur","direct","dirt","disagree","discover","disease","dish","dismiss","disorder","display","distance","divert","divide","divorce","dizzy","doctor","document","dog","doll","dolphin","domain","donate","donkey","donor","door","dose","double","dove","draft","dragon","drama","drastic","draw","dream","dress","drift","drill","drink","drip","drive","drop","drum","dry","duck","dumb","dune","during","dust","dutch","duty","dwarf","dynamic","eager","eagle","early","earn","earth","easily","east","easy","echo","ecology","economy","edge","edit","educate","effort","egg","eight","either","elbow","elder","electric","elegant","element","elephant","elevator","elite","else","embark","embody","embrace","emerge","emotion","employ","empower","empty","enable","enact","end","endless","endorse","enemy","energy","enforce","engage","engine","enhance","enjoy","enlist","enough","enrich","enroll","ensure","enter","entire","entry","envelope","episode","equal","equip","era","erase","erode","erosion","error","erupt","escape","essay","essence","estate","eternal","ethics","evidence","evil","evoke","evolve","exact","example","excess","exchange","excite","exclude","excuse","execute","exercise","exhaust","exhibit","exile","exist","exit","exotic","expand","expect","expire","explain","expose","express","extend","extra","eye","eyebrow","fabric","face","faculty","fade","faint","faith","fall","false","fame","family","famous","fan","fancy","fantasy","farm","fashion","fat","fatal","father","fatigue","fault","favorite","feature","february","federal","fee","feed","feel","female","fence","festival","fetch","fever","few","fiber","fiction","field","figure","file","film","filter","final","find","fine","finger","finish","fire","firm","first","fiscal","fish","fit","fitness","fix","flag","flame","flash","flat","flavor","flee","flight","flip","float","flock","floor","flower","fluid","flush","fly","foam","focus","fog","foil","fold","follow","food","foot","force","forest","forget","fork","fortune","forum","forward","fossil","foster","found","fox","fragile","frame","frequent","fresh","friend","fringe","frog","front","frost","frown","frozen","fruit","fuel","fun","funny","furnace","fury","future","gadget","gain","galaxy","gallery","game","gap","garage","garbage","garden","garlic","garment","gas","gasp","gate","gather","gauge","gaze","general","genius","genre","gentle","genuine","gesture","ghost","giant","gift","giggle","ginger","giraffe","girl","give","glad","glance","glare","glass","glide","glimpse","globe","gloom","glory","glove","glow","glue","goat","goddess","gold","good","goose","gorilla","gospel","gossip","govern","gown","grab","grace","grain","grant","grape","grass","gravity","great","green","grid","grief","grit","grocery","group","grow","grunt","guard","guess","guide","guilt","guitar","gun","gym","habit","hair","half","hammer","hamster","hand","happy","harbor","hard","harsh","harvest","hat","have","hawk","hazard","head","health","heart","heavy","hedgehog","height","hello","helmet","help","hen","hero","hidden","high","hill","hint","hip","hire","history","hobby","hockey","hold","hole","holiday","hollow","home","honey","hood","hope","horn","horror","horse","hospital","host","hotel","hour","hover","hub","huge","human","humble","humor","hundred","hungry","hunt","hurdle","hurry","hurt","husband","hybrid","ice","icon","idea","identify","idle","ignore","ill","illegal","illness","image","imitate","immense","immune","impact","impose","improve","impulse","inch","include","income","increase","index","indicate","indoor","industry","infant","inflict","inform","inhale","inherit","initial","inject","injury","inmate","inner","innocent","input","inquiry","insane","insect","inside","inspire","install","intact","interest","into","invest","invite","involve","iron","island","isolate","issue","item","ivory","jacket","jaguar","jar","jazz","jealous","jeans","jelly","jewel","job","join","joke","journey","joy","judge","juice","jump","jungle","junior","junk","just","kangaroo","keen","keep","ketchup","key","kick","kid","kidney","kind","kingdom","kiss","kit","kitchen","kite","kitten","kiwi","knee","knife","knock","know","lab","label","labor","ladder","lady","lake","lamp","language","laptop","large","later","latin","laugh","laundry","lava","law","lawn","lawsuit","layer","lazy","leader","leaf","learn","leave","lecture","left","leg","legal","legend","leisure","lemon","lend","length","lens","leopard","lesson","letter","level","liar","liberty","library","license","life","lift","light","like","limb","limit","link","lion","liquid","list","little","live","lizard","load","loan","lobster","local","lock","logic","lonely","long","loop","lottery","loud","lounge","love","loyal","lucky","luggage","lumber","lunar","lunch","luxury","lyrics","machine","mad","magic","magnet","maid","mail","main","major","make","mammal","man","manage","mandate","mango","mansion","manual","maple","marble","march","margin","marine","market","marriage","mask","mass","master","match","material","math","matrix","matter","maximum","maze","meadow","mean","measure","meat","mechanic","medal","media","melody","melt","member","memory","mention","menu","mercy","merge","merit","merry","mesh","message","metal","method","middle","midnight","milk","million","mimic","mind","minimum","minor","minute","miracle","mirror","misery","miss","mistake","mix","mixed","mixture","mobile","model","modify","mom","moment","monitor","monkey","monster","month","moon","moral","more","morning","mosquito","mother","motion","motor","mountain","mouse","move","movie","much","muffin","mule","multiply","muscle","museum","mushroom","music","must","mutual","myself","mystery","myth","naive","name","napkin","narrow","nasty","nation","nature","near","neck","need","negative","neglect","neither","nephew","nerve","nest","net","network","neutral","never","news","next","nice","night","noble","noise","nominee","noodle","normal","north","nose","notable","note","nothing","notice","novel","now","nuclear","number","nurse","nut","oak","obey","object","oblige","obscure","observe","obtain","obvious","occur","ocean","october","odor","off","offer","office","often","oil","okay","old","olive","olympic","omit","once","one","onion","online","only","open","opera","opinion","oppose","option","orange","orbit","orchard","order","ordinary","organ","orient","original","orphan","ostrich","other","outdoor","outer","output","outside","oval","oven","over","own","owner","oxygen","oyster","ozone","pact","paddle","page","pair","palace","palm","panda","panel","panic","panther","paper","parade","parent","park","parrot","party","pass","patch","path","patient","patrol","pattern","pause","pave","payment","peace","peanut","pear","peasant","pelican","pen","penalty","pencil","people","pepper","perfect","permit","person","pet","phone","photo","phrase","physical","piano","picnic","picture","piece","pig","pigeon","pill","pilot","pink","pioneer","pipe","pistol","pitch","pizza","place","planet","plastic","plate","play","please","pledge","pluck","plug","plunge","poem","poet","point","polar","pole","police","pond","pony","pool","popular","portion","position","possible","post","potato","pottery","poverty","powder","power","practice","praise","predict","prefer","prepare","present","pretty","prevent","price","pride","primary","print","priority","prison","private","prize","problem","process","produce","profit","program","project","promote","proof","property","prosper","protect","proud","provide","public","pudding","pull","pulp","pulse","pumpkin","punch","pupil","puppy","purchase","purity","purpose","purse","push","put","puzzle","pyramid","quality","quantum","quarter","question","quick","quit","quiz","quote","rabbit","raccoon","race","rack","radar","radio","rail","rain","raise","rally","ramp","ranch","random","range","rapid","rare","rate","rather","raven","raw","razor","ready","real","reason","rebel","rebuild","recall","receive","recipe","record","recycle","reduce","reflect","reform","refuse","region","regret","regular","reject","relax","release","relief","rely","remain","remember","remind","remove","render","renew","rent","reopen","repair","repeat","replace","report","require","rescue","resemble","resist","resource","response","result","retire","retreat","return","reunion","reveal","review","reward","rhythm","rib","ribbon","rice","rich","ride","ridge","rifle","right","rigid","ring","riot","ripple","risk","ritual","rival","river","road","roast","robot","robust","rocket","romance","roof","rookie","room","rose","rotate","rough","round","route","royal","rubber","rude","rug","rule","run","runway","rural","sad","saddle","sadness","safe","sail","salad","salmon","salon","salt","salute","same","sample","sand","satisfy","satoshi","sauce","sausage","save","say","scale","scan","scare","scatter","scene","scheme","school","science","scissors","scorpion","scout","scrap","screen","script","scrub","sea","search","season","seat","second","secret","section","security","seed","seek","segment","select","sell","seminar","senior","sense","sentence","series","service","session","settle","setup","seven","shadow","shaft","shallow","share","shed","shell","sheriff","shield","shift","shine","ship","shiver","shock","shoe","shoot","shop","short","shoulder","shove","shrimp","shrug","shuffle","shy","sibling","sick","side","siege","sight","sign","silent","silk","silly","silver","similar","simple","since","sing","siren","sister","situate","six","size","skate","sketch","ski","skill","skin","skirt","skull","slab","slam","sleep","slender","slice","slide","slight","slim","slogan","slot","slow","slush","small","smart","smile","smoke","smooth","snack","snake","snap","sniff","snow","soap","soccer","social","sock","soda","soft","solar","soldier","solid","solution","solve","someone","song","soon","sorry","sort","soul","sound","soup","source","south","space","spare","spatial","spawn","speak","special","speed","spell","spend","sphere","spice","spider","spike","spin","spirit","split","spoil","sponsor","spoon","sport","spot","spray","spread","spring","spy","square","squeeze","squirrel","stable","stadium","staff","stage","stairs","stamp","stand","start","state","stay","steak","steel","stem","step","stereo","stick","still","sting","stock","stomach","stone","stool","story","stove","strategy","street","strike","strong","struggle","student","stuff","stumble","style","subject","submit","subway","success","such","sudden","suffer","sugar","suggest","suit","summer","sun","sunny","sunset","super","supply","supreme","sure","surface","surge","surprise","surround","survey","suspect","sustain","swallow","swamp","swap","swarm","swear","sweet","swift","swim","swing","switch","sword","symbol","symptom","syrup","system","table","tackle","tag","tail","talent","talk","tank","tape","target","task","taste","tattoo","taxi","teach","team","tell","ten","tenant","tennis","tent","term","test","text","thank","that","theme","then","theory","there","they","thing","this","thought","three","thrive","throw","thumb","thunder","ticket","tide","tiger","tilt","timber","time","tiny","tip","tired","tissue","title","toast","tobacco","today","toddler","toe","together","toilet","token","tomato","tomorrow","tone","tongue","tonight","tool","tooth","top","topic","topple","torch","tornado","tortoise","toss","total","tourist","toward","tower","town","toy","track","trade","traffic","tragic","train","transfer","trap","trash","travel","tray","treat","tree","trend","trial","tribe","trick","trigger","trim","trip","trophy","trouble","truck","true","truly","trumpet","trust","truth","try","tube","tuition","tumble","tuna","tunnel","turkey","turn","turtle","twelve","twenty","twice","twin","twist","two","type","typical","ugly","umbrella","unable","unaware","uncle","uncover","under","undo","unfair","unfold","unhappy","uniform","unique","unit","universe","unknown","unlock","until","unusual","unveil","update","upgrade","uphold","upon","upper","upset","urban","urge","usage","use","used","useful","useless","usual","utility","vacant","vacuum","vague","valid","valley","valve","van","vanish","vapor","various","vast","vault","vehicle","velvet","vendor","venture","venue","verb","verify","version","very","vessel","veteran","viable","vibrant","vicious","victory","video","view","village","vintage","violin","virtual","virus","visa","visit","visual","vital","vivid","vocal","voice","void","volcano","volume","vote","voyage","wage","wagon","wait","walk","wall","walnut","want","warfare","warm","warrior","wash","wasp","waste","water","wave","way","wealth","weapon","wear","weasel","weather","web","wedding","weekend","weird","welcome","west","wet","whale","what","wheat","wheel","when","where","whip","whisper","wide","width","wife","wild","will","win","window","wine","wing","wink","winner","winter","wire","wisdom","wise","wish","witness","wolf","woman","wonder","wood","wool","word","work","world","worry","worth","wrap","wreck","wrestle","wrist","write","wrong","yard","year","yellow","you","young","youth","zebra","zero","zone","zoo"];var Io=new TextEncoder().encode("calimero.mdma.account-link.v1\0"),Do=new TextEncoder().encode("calimero.mdma.account-login.v1\0"),le=256,En=le/32,Pt=(le+En)/11;async function Tn(){let n=crypto.getRandomValues(new Uint8Array(le/8));return Mn(h(n),await On(n))}async function Pn(n){let e=_n(n);return Mn(h(await Gn(e)),e.join(" "))}async function It(n){return g(n,"secret",32),{secret:n,publicKey:h(await ae(n)),accountId:await Fe(n)}}async function In(){let n=crypto.getRandomValues(new Uint8Array(le/8)),e=await On(n);return{...await Un(n),phrase:e}}async function Dn(n){return Un(await Gn(_n(n)))}async function Un(n){let e=await ce(h(n),"rootSecret");return n.fill(0),{publicKey:e.publicKey,accountId:await B(e.publicKey),signer:e}}async function H(n){let e=typeof n=="string"?await ce(n,"rootSecret"):n;return Nn(e)}async function Ve(n,e){return Nn(await S(n,e,"rootSecret"))}async function Nn(n){return{signer:n,publicKey:n.publicKey,accountId:await B(n.publicKey)}}async function Re(n){if(!n.nonce)throw new Error("nonce is required to sign an account link");let t=await(await S(n.rootSecret,n.signer,"rootSecret")).sign(f(Io,new TextEncoder().encode(n.nonce)));return qn(t)}async function We(n){if(!n.nonce)throw new Error("nonce is required to sign an account login");let t=await(await S(n.rootSecret,n.signer,"rootSecret")).sign(f(Do,new TextEncoder().encode(n.nonce)));return qn(t)}async function Mn(n,e){return{...await It(n),phrase:e}}function _n(n){let e=n.normalize("NFKD").toLowerCase().trim().split(/\s+/),t=e[0]===""?0:e.length;if(t!==Pt)throw new Error(`recovery phrase must be ${Pt} words, got ${t}`);return e}async function On(n){let e=$n(n)+await Hn(n),t=[];for(let r=0;r<Pt;r+=1){let o=Number.parseInt(e.slice(r*11,r*11+11),2);t.push(Tt[o])}return t.join(" ")}async function Gn(n){let e="";for(let r of n){let o=Tt.indexOf(r);if(o<0)throw new Error(`"${r}" is not a word in the recovery phrase list`);e+=o.toString(2).padStart(11,"0")}let t=new Uint8Array(le/8);for(let r=0;r<t.length;r+=1)t[r]=Number.parseInt(e.slice(r*8,r*8+8),2);if(e.slice(le)!==await Hn(t))throw new Error("recovery phrase checksum failed \u2014 check for a mistyped or transposed word");return t}async function Hn(n){let e=new Uint8Array(await crypto.subtle.digest("SHA-256",n));return $n(e).slice(0,En)}function $n(n){let e="";for(let t of n)e+=t.toString(2).padStart(8,"0");return e}function qn(n){let e="";for(let t of n)e+=String.fromCharCode(t);return btoa(e)}var Uo=new TextEncoder().encode("calimero.mdma.routing-read.v1\0");async function Ln(n,e){g(e,"deviceSecret",32);let t=await se(e),r=f(Uo,new TextEncoder().encode(n)),o=new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},t,r));return No(o)}async function ze(n,e){return{"X-Calimero-Credential":e.credential,"X-Calimero-Nonce":n.nonce,"X-Calimero-Signature":await Ln(n.nonce,e.deviceSecret)}}function No(n){let e="";for(let t of n)e+=String.fromCharCode(t);return btoa(e)}var Mo="https://manager.cloud.calimero.network";function Dt(n,e){return typeof n.can_execute=="boolean"?n.can_execute:e}function Ut(n){return typeof n.tee_role=="string"&&n.tee_role!==""?n.tee_role:null}function Nt(n){return n.find(e=>e.canExecute&&e.relayUrl!==null&&e.executorAccount!==null)??null}var _o="x-mdma-session-refresh",Oo="x-mdma-session-expires",_=class{constructor(e={}){this.session=null;this.baseUrl=(e.cloudBaseUrl||Mo).replace(/\/+$/,""),this.onSession=e.onSession;let t=e.fetch;this.fetchImpl=t?(r,o)=>t(r,o):(r,o)=>globalThis.fetch(r,o),this.timeoutMs=e.timeoutMs??1e4,this.routingCredential=e.routingCredential,e.sessionToken&&(this.session={sessionToken:e.sessionToken,expiresAt:0,user:{email:""}})}getSession(){return this.session}isSignedIn(){return this.session!==null}async signInWithGoogle(e){let t=await this.request("POST","/api/auth/google",{body:{id_token:e},anonymous:!0});return this.adoptSession(t)}async signInWithAccount(e){let{signer:t,publicKey:r}=await H(e),{nonce:o}=await this.getAccountLoginChallenge();return this.submitAccountLogin({rootPublicKey:r,nonce:o,signature:await We({signer:t,nonce:o})})}async getAccountLoginChallenge(){let e=await this.request("GET","/api/auth/account/challenge",{anonymous:!0});return{nonce:e.nonce,expiresAtMs:e.expires_at_ms}}async submitAccountLogin(e){let t=await this.request("POST","/api/auth/account",{body:{root_public_key:e.rootPublicKey,nonce:e.nonce,signature:e.signature},anonymous:!0});return this.adoptSession(t)}async refreshSession(){let e=await this.request("POST","/api/auth/refresh");return this.adoptSession(e)}async signOut(){try{this.session&&await this.request("POST","/api/auth/logout",{parse:"none"})}finally{this.session=null,this.notifySession(null)}}async getMyNamespaces(){return(await this.request("GET","/api/cloud/me/namespaces")).map(t=>({namespaceId:String(t.namespace_id??t.group_id??""),groupId:String(t.group_id??t.namespace_id??""),haStatus:String(t.ha_status??"none"),haEnabledAt:t.ha_enabled_at??null,contexts:Array.isArray(t.contexts)?t.contexts:[],fleetReplicas:t.fleet_replicas}))}async getNamespaceRelays(e){return((await this.request("GET",`/api/cloud/me/namespaces/${encodeURIComponent(e)}/relays`)).relays??[]).map(r=>{let o=r.relay_url??null,i=r.executor_account??null,a=r.authorship_ready===!0;return{peerId:String(r.peer_id??""),relayUrl:o,executorAccount:i,nodeKey:r.node_key??r.node_public_key??null,status:String(r.status??""),authorshipReady:a,teeRole:Ut(r),canExecute:Dt(r,a&&o!==null&&i!==null),lastSeenAt:r.last_seen_at??null,confirmedAt:r.confirmed_at??null}})}async findExecutingRelay(e){let t=await this.getNamespaceRelays(e);return Nt(t)}async getNamespaceRouting(e){let t=await this.request("GET",`/api/cloud/namespaces/${encodeURIComponent(e)}/admitters`,{anonymous:!0,headers:await this.routingProof(e)});return{namespaceId:String(t.namespace_id??e),nodes:(t.admitters??[]).map(r=>{let o=r.account??null,i=r.relay_url??null,a=r.fresh===!0,s=r.authorship_ready===!0;return{peerId:String(r.peer_id??""),account:o,relayUrl:i,admitUrl:r.admit_url??null,status:String(r.status??""),fresh:a,canAdmit:r.can_admit===!0,authorshipReady:s,teeRole:Ut(r),canExecute:Dt(r,s&&i!==null&&o!==null&&a)}}),servable:t.servable===!0,writable:t.writable===!0}}async getRoutingChallenge(e){let t=await this.request("GET",`/api/cloud/namespaces/${encodeURIComponent(e)}/challenge`,{anonymous:!0});return{namespaceId:String(t.namespace_id??e),nonce:String(t.nonce??""),expiresAtMs:Number(t.expires_at_ms??0)}}async routingProof(e){if(!this.routingCredential)return;let t=await this.getRoutingChallenge(e);return ze(t,this.routingCredential)}async getAccountRelaysChallenge(e){let t=await this.request("GET",`/api/cloud/accounts/${encodeURIComponent(e)}/challenge`,{anonymous:!0});return{accountId:String(t.account_id??e),nonce:String(t.nonce??""),expiresAtMs:Number(t.expires_at_ms??0)}}async getAccountRelays(e){if(!this.routingCredential)throw new Error("getAccountRelays needs a routingCredential: construct the client with the device certificate and its signing secret, since this read is proven by the device, not by a session.");let t=await this.getAccountRelaysChallenge(e);return((await this.request("GET",`/api/cloud/accounts/${encodeURIComponent(e)}/relays`,{anonymous:!0,headers:await ze(t,this.routingCredential)})).relays??[]).map(o=>({peerId:String(o.peer_id??""),relayUrl:o.relay_url??null,fresh:o.fresh===!0}))}async findAdmitter(e,t){let{nodes:r}=await this.getNamespaceRouting(e),o=t&&t.length>0?new Set(t.map(i=>i.toLowerCase())):null;return r.find(i=>i.canAdmit&&(o===null||i.account!==null&&o.has(i.account.toLowerCase())))??null}async getMyMachines(){return((await this.request("GET","/api/cloud/me/machines")).machines??[]).map(t=>{let r=t.relay_url??null,o=t.executor_account??null,i=(Array.isArray(t.namespaces)?t.namespaces:[]).map(a=>{let s=a;return{namespaceId:String(s.namespace_id??""),status:String(s.status??""),authorshipReady:s.authorship_ready===!0,teeRole:Ut(s),fresh:s.fresh===!0,confirmedAt:s.confirmed_at??null,lastSeenAt:s.last_seen_at??null}});return{peerId:String(t.peer_id??""),relayUrl:r,executorAccount:o,canExecute:Dt(t,r!==null&&o!==null&&i.some(a=>a.authorshipReady)),namespaces:i}})}async claimNamespace(e,t){await this.request("POST","/api/cloud/namespaces/claim",{body:{namespace_id:e,ownership_proof:t}})}async enableNamespaceHa(e,t={}){let r=t.admitterAddrs===void 0?{}:{admitter_addrs:[...t.admitterAddrs]};return this.request("POST",`/api/cloud/namespaces/${encodeURIComponent(e)}/enable-ha`,{body:r})}async disableNamespaceHa(e){return this.request("POST",`/api/cloud/namespaces/${encodeURIComponent(e)}/disable-ha`,{body:{}})}async getMyNode(){return(await this.request("GET","/api/cloud/me/node")).node??null}enableHA(e){let t=new URLSearchParams({group_id:e.groupId,context_id:e.contextId});e.redirectUrl&&t.set("redirect_url",e.redirectUrl),window.open(`${this.baseUrl}/enable-ha?${t.toString()}`)}disableHA(e){let t=new URLSearchParams({group_id:e.groupId,context_id:e.contextId});e.redirectUrl&&t.set("redirect_url",e.redirectUrl),window.open(`${this.baseUrl}/disable-ha?${t.toString()}`)}async linkAccount(e){let{signer:t,publicKey:r,accountId:o}=await H(e),{nonce:i}=await this.getAccountLinkChallenge();return this.submitAccountLink({accountId:o,rootPublicKey:r,nonce:i,signature:await Re({signer:t,nonce:i})})}async getAccountLinkChallenge(){let e=await this.request("GET","/api/cloud/me/accounts/challenge");return{nonce:e.nonce,expiresAtMs:e.expires_at_ms??null}}async submitAccountLink(e){let t=await this.request("POST","/api/cloud/me/accounts",{body:{account_id:e.accountId,root_public_key:e.rootPublicKey,nonce:e.nonce,signature:e.signature}});return{accountId:String(t.account_id??e.accountId),linkedAt:t.linked_at??null,alreadyLinked:t.already_linked===!0}}static accountLinkHandoff(e){let t=e.portalUrl.replace(/\/+$/,""),r=new URLSearchParams({"link-account":e.accountId,"callback-url":e.callbackUrl});return{url:`${t}/?${r.toString()}`,accountId:e.accountId}}static readAccountLinkCallback(e){let t=e??(typeof window>"u"?"":window.location.href);if(!t)return{};let r;try{r=new URL(t).hash}catch{return{}}let o=new URLSearchParams(r.replace(/^#/,"")),i=o.get("grant"),a=o.get("account"),s=o.get("error"),c={};return i&&(c.grant=i),a&&(c.accountId=a),s&&(c.error=s),c}async linkAccountWithGrant(e){let{signer:t,publicKey:r,accountId:o}=await Ve(e.rootSecret,e.signer),i=await this.request("POST","/api/cloud/accounts/link",{body:{grant:e.grant,root_public_key:r,signature:await Re({signer:t,nonce:e.grant})},anonymous:!0});return{accountId:String(i.account_id??o),linkedAt:i.linked_at??null,alreadyLinked:i.already_linked===!0}}async getMyAccounts(){let e=await this.request("GET","/api/cloud/me/accounts");return{accounts:(e.accounts??[]).map(t=>({accountId:String(t.account_id??""),linkedAt:t.linked_at??null,hasRecoveryEnvelope:t.has_recovery_envelope===!0})),limit:e.limit??null}}adoptSession(e){return this.session={sessionToken:e.session_token,expiresAt:e.expires_at,user:e.user},this.notifySession(this.session),this.session}async notifySession(e){try{await this.onSession?.(e)}catch{}}async request(e,t,r={}){if(!r.anonymous&&!this.session)throw new Error("Not signed in to Calimero Cloud: call signInWithGoogle() or construct the client with a sessionToken");let o={...r.headers,Accept:"application/json"};r.body!==void 0&&(o["Content-Type"]="application/json"),!r.anonymous&&this.session&&(o.Authorization=`Bearer ${this.session.sessionToken}`);let i=new AbortController,a=setTimeout(()=>i.abort(),this.timeoutMs),s;try{s=await this.fetchImpl(`${this.baseUrl}${t}`,{method:e,headers:o,body:r.body===void 0?void 0:JSON.stringify(r.body),signal:i.signal})}catch(c){throw new C(0,c instanceof Error?c.name:"NetworkError",`${this.baseUrl}${t}`,new Headers,c instanceof Error?c.message:String(c))}finally{clearTimeout(a)}if(this.adoptRollingRefresh(s),!s.ok){let c=await s.text().catch(()=>{});throw new C(s.status,s.statusText,`${this.baseUrl}${t}`,s.headers,c)}if(!(r.parse==="none"||s.status===204))return await s.json()}adoptRollingRefresh(e){let t=e.headers.get(_o);if(!t||!this.session)return;let r=e.headers.get(Oo),o=Number(r);this.session={sessionToken:t,expiresAt:Number.isFinite(o)&&o>0?o:this.session.expiresAt,user:this.session.user},this.notifySession(this.session)}};function Go(n){let e=n&&typeof n=="object"?n.data??n:void 0;if(!e||typeof e!="object")return[];let t=e.localPeerId,r=e.externalAddrs;if(typeof t!="string"||!t||!Array.isArray(r))return[];let o=`/p2p/${t}`,i=[];for(let a of r){if(typeof a!="string")continue;let s=a.trim();if(!s.startsWith("/"))continue;let c=s.endsWith(o)?s:`${s}${o}`;i.includes(c)||i.push(c)}return i}function Ho(n){if(n)return typeof n=="function"?n:He(n)}var $o="mero-js:token-refresh";function qo(){let e=globalThis.navigator?.locks;return e&&typeof e.request=="function"?e:null}function Mt(n,e){try{let t=n.split(".");if(t.length===3){let r=t[1].replace(/-/g,"+").replace(/_/g,"/");for(;r.length%4;)r+="=";let o=JSON.parse(atob(r));if(typeof o.exp=="number")return o.exp*1e3}}catch{}return e}var ue=class{constructor(e){this.tokenData=null;this.refreshPromise=null;this.rpcClient=null;this.sseClient=null;this.wsClient=null;this.wsWarned=!1;this.config={timeoutMs:1e4,...e},this.tokenStore=e.tokenStore??null,this.tokenStore&&(this.tokenData=this.tokenStore.getTokens());let t=typeof window<"u"&&"__TAURI_INTERNALS__"in window,r=Ho(this.config.requestProof);this.httpClient=re({baseUrl:this.config.baseUrl,fetch:this.config.fetch,getProof:r,getAuthToken:async()=>(await this.getValidToken())?.access_token||"",refreshToken:async()=>(await this.performTokenRefresh()).access_token,onTokenRefresh:async o=>{this.tokenData&&(this.tokenData.access_token=o,this.tokenStore?.setTokens(this.tokenData))},onAuthRevoked:async()=>{this.clearToken();try{await this.config.onAuthRevoked?.()}catch{}},timeoutMs:this.config.timeoutMs,credentials:this.config.requestCredentials??(t?"omit":void 0)}),this.authClient=un(this.httpClient,{baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||"",timeoutMs:this.config.timeoutMs}),this.adminClient=_e(this.httpClient,{baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||"",timeoutMs:this.config.timeoutMs})}get auth(){return this.authClient}get admin(){return this.adminClient}get rpc(){return this.rpcClient||(this.rpcClient=new Ae({httpClient:this.httpClient})),this.rpcClient}get events(){return this.sseClient||(this.sseClient=new M({baseUrl:this.config.baseUrl,fetch:this.config.fetch,getAuthToken:async()=>(await this.getValidToken())?.access_token||""})),this.sseClient}get ephemeral(){return this.ephemeralClient||(this.ephemeralClient=new xe({httpClient:this.httpClient,sse:this.events})),this.ephemeralClient}get cloud(){return this.cloudClient||(this.cloudClient=new _(this.config.cloud??{})),this.cloudClient}get ws(){return this.wsWarned||(this.wsWarned=!0,console.warn("[mero-js] WsClient is experimental. Use mero.events (SSE) for production.")),this.wsClient||(this.wsClient=new K({baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||""})),this.wsClient}async authenticate(e){let t=e||this.config.credentials;if(!t)throw new Error("No credentials provided for authentication");try{let r={auth_method:"user_password",public_key:t.username,client_name:"mero-js-sdk",permissions:["admin"],timestamp:Math.floor(Date.now()/1e3),provider_data:{username:t.username,password:t.password}},o=await this.authClient.generateTokens(r),i=o.data.access_token;return this.tokenData={access_token:i,refresh_token:o.data.refresh_token,expires_at:Mt(i,Date.now()+36e5)},this.tokenStore?.setTokens(this.tokenData),this.tokenData}catch(r){throw new Error(`Authentication failed: ${r instanceof Error?r.message:"Unknown error"}`)}}async getValidToken(){return this.tokenData}async performTokenRefresh(){if(this.refreshPromise)return this.refreshPromise;let e=this.tokenData?.access_token,t=this.withRefreshLock(()=>this.performTokenRefreshLocked(e));this.refreshPromise=t;try{return await t}finally{this.refreshPromise===t&&(this.refreshPromise=null)}}withRefreshLock(e){let t=qo();return t?t.request($o,e):e()}async performTokenRefreshLocked(e){let t=this.tokenStore?.getTokens()??null;if(t?.refresh_token&&(this.tokenData=t,e&&t.access_token!==e))return t;if(!this.tokenData?.refresh_token)throw new Error("No refresh token available");try{let r=await this.authClient.refreshToken({access_token:this.tokenData.access_token,refresh_token:this.tokenData.refresh_token}),o=r.data.access_token;return this.tokenData={access_token:o,refresh_token:r.data.refresh_token,expires_at:Mt(o,Date.now()+36e5)},this.tokenStore?.setTokens(this.tokenData),this.tokenData}catch(r){throw new Error(`Token refresh failed: ${r instanceof Error?r.message:"Unknown error"}`)}}clearToken(){this.refreshPromise=null,this.tokenData=null,this.tokenStore?.clear()}isAuthenticated(){return this.tokenData!==null}setTokenData(e){let t=e.expires_at||Mt(e.access_token,Date.now()+36e5);this.tokenData={...e,expires_at:t},this.tokenStore?.setTokens(this.tokenData)}getTokenData(){return this.tokenData}close(){this.sseClient?.close(),this.wsClient?.close()}static parseAuthCallback(e){return vt(e)}static buildAuthLoginUrl(e,t){return Ct(e,t)}};function Lo(n){return new ue(n)}var _t=class{constructor(){this.tokens=null}getTokens(){return this.tokens}setTokens(e){this.tokens=e}clear(){this.tokens=null}},Ko="mero-tokens",Ot=class{constructor(e=Ko){this.key=e}getTokens(){try{if(typeof localStorage>"u")return null;let e=localStorage.getItem(this.key);if(!e)return null;let t=JSON.parse(e);return t&&t.access_token&&t.refresh_token?{access_token:t.access_token,refresh_token:t.refresh_token,expires_at:typeof t.expires_at=="number"?t.expires_at:Date.now()+36e5}:null}catch{return null}}setTokens(e){try{if(typeof localStorage>"u")return;localStorage.setItem(this.key,JSON.stringify(e))}catch{}}clear(){try{if(typeof localStorage>"u")return;localStorage.removeItem(this.key)}catch{}}};var Bo=new TextEncoder().encode("calimero.warrant.v2"),jo=new TextEncoder().encode("calimero.warrant.intent.v1"),Kn=64,Fo="00".repeat(32);async function Gt(n,e){let t=new TextEncoder().encode(JSON.stringify(e));return k(jo,[new TextEncoder().encode(n),t])}async function Je(n){let e=g(n.context,"context",32),t=g(n.authorAccount,"authorAccount",32),r=g(n.executor,"executor",32),o=g(n.appVersion??Fo,"appVersion",32),i=j(n.accountHeads,"accountHeads"),a=j(n.governanceFloor,"governanceFloor"),s=await S(n.deviceSecret,n.signer,"deviceSecret"),c=g(s.publicKey,"signer.publicKey",32),u=new TextEncoder().encode(n.method),d=await Gt(n.method,n.argsJson),l=A(n.nonce),p=A(n.notAfter),b=await k(Bo,[e,t,c,r,o,u,d,A(i.length),...i,A(a.length),...a,l,p]),w=ve(await s.sign(b));return h(f(e,t,c,r,o,x(u.length),u,d,x(i.length),...i,x(a.length),...a,l,p,w))}function ve(n){if(!(n instanceof Uint8Array)||n.length!==64){let e=n instanceof Uint8Array?`${n.length} bytes`:typeof n;throw new Error(`signer returned ${e}, expected a 64-byte Ed25519 signature`)}return n}function j(n,e){let t=n??[];if(t.length>Kn)throw new Error(`${e} cites ${t.length} heads, over the ${Kn} a node accepts`);return t.map((r,o)=>g(r,`${e}[${o}]`,32))}var Vo=new TextEncoder().encode("calimero.context-creation-warrant.v1"),Wo=new TextEncoder().encode("calimero.context-creation.init.v1"),Qe=256;async function Ht(n){let e=new TextEncoder().encode(JSON.stringify(n));return k(Wo,[e])}async function zo(n){return k(Vo,[n.group,n.seed,n.authorAccount,n.deviceKey,n.executor,n.applicationId,new Uint8Array([n.serviceName===null?0:1]),n.serviceName??new Uint8Array(0),new Uint8Array([n.name===null?0:1]),n.name??new Uint8Array(0),n.initHash,A(n.accountHeads.length),...n.accountHeads,A(n.governanceFloor.length),...n.governanceFloor,A(n.nonce),A(n.notAfter)])}async function Ye(n){let e=g(n.group,"group",32),t=n.seed===void 0?crypto.getRandomValues(new Uint8Array(32)):g(n.seed,"seed",32),r=g(n.authorAccount,"authorAccount",32),o=g(n.executor,"executor",32),i=g(n.applicationId,"applicationId",32),a=Bn(n.serviceName,"serviceName"),s=Bn(n.name,"name"),c=j(n.accountHeads,"accountHeads"),u=j(n.governanceFloor,"governanceFloor"),d=await S(n.deviceSecret,n.signer,"deviceSecret"),l=g(d.publicKey,"signer.publicKey",32),p=await Ht(n.initArgs),b=await zo({group:e,seed:t,authorAccount:r,deviceKey:l,executor:o,applicationId:i,serviceName:a,name:s,initHash:p,accountHeads:c,governanceFloor:u,nonce:n.nonce,notAfter:n.notAfter}),w=ve(await d.sign(b));return{warrant:h(f(e,t,r,l,o,i,jn(a),jn(s),p,x(c.length),...c,x(u.length),...u,A(n.nonce),A(n.notAfter),w)),seed:h(t)}}function Fn(n){let e=n.trim();if(!/^[0-9a-fA-F]*$/.test(e)||e.length%2!==0)throw new Error("creation warrant must be an even number of hex characters");let t=new Uint8Array(e.length/2);for(let l=0;l<t.length;l+=1)t[l]=Number.parseInt(e.slice(l*2,l*2+2),16);let r=new DataView(t.buffer),o=0,i=(l,p)=>{if(o+l>t.length)throw new Error(`creation warrant ends inside ${p} (${t.length} bytes)`);let b=t.subarray(o,o+l);return o+=l,b},a=l=>r.getUint32(i(4,l).byteOffset,!0),s=l=>r.getBigUint64(i(8,l).byteOffset,!0),c=l=>{let p=i(1,l)[0];if(p===0)return null;if(p!==1)throw new Error(`${l} has option tag ${p}, expected 0 or 1`);let b=a(l);if(b>Qe)throw new Error(`${l} is ${b} bytes, over the ${Qe} a node accepts`);return new TextDecoder("utf-8",{fatal:!0}).decode(i(b,l))},u=l=>{let p=a(l);if(p>64)throw new Error(`${l} cites ${p} heads, over the 64 a node accepts`);return Array.from({length:p},()=>h(i(32,l)))},d={group:h(i(32,"group")),seed:h(i(32,"seed")),authorAccount:h(i(32,"authorAccount")),deviceKey:h(i(32,"deviceKey")),executor:h(i(32,"executor")),applicationId:h(i(32,"applicationId")),serviceName:c("serviceName"),name:c("name"),initHash:h(i(32,"initHash")),accountHeads:u("accountHeads"),governanceFloor:u("governanceFloor"),nonce:s("nonce"),notAfter:s("notAfter"),signature:h(i(64,"signature"))};if(o!==t.length)throw new Error(`creation warrant is ${t.length} bytes but its fields account for ${o}`);return d}function Bn(n,e){if(n===void 0)return null;let t=new TextEncoder().encode(n);if(t.length>Qe)throw new Error(`${e} is ${t.length} UTF-8 bytes, over the ${Qe} a node accepts`);return t}function jn(n){return n===null?new Uint8Array([0]):f(new Uint8Array([1]),x(n.length),n)}var Jo=new TextEncoder().encode("calimero.governance-warrant.v1"),Qo=new TextEncoder().encode("calimero.governance-warrant.op.v1"),Yo={group:0,root:1};async function $t(n){return k(Qo,[new Uint8Array([qt(n.kind)]),n.bytes])}async function Xo(n){return k(Jo,[n.scope,new Uint8Array([qt(n.kind)]),n.authorAccount,n.deviceKey,n.executor,n.opHash,A(n.accountHeads.length),...n.accountHeads,A(n.governanceFloor.length),...n.governanceFloor,A(n.nonce),A(n.notAfter)])}async function Ce(n){let e=g(n.scope,"scope",32),t=g(n.authorAccount,"authorAccount",32),r=g(n.executor,"executor",32),o=j(n.accountHeads,"accountHeads"),i=j(n.governanceFloor,"governanceFloor"),a=qt(n.op.kind),s=await S(n.deviceSecret,n.signer,"deviceSecret"),c=g(s.publicKey,"signer.publicKey",32),u=await $t(n.op),d=await Xo({scope:e,kind:n.op.kind,authorAccount:t,deviceKey:c,executor:r,opHash:u,accountHeads:o,governanceFloor:i,nonce:n.nonce,notAfter:n.notAfter}),l=ve(await s.sign(d));return h(f(e,new Uint8Array([a]),t,c,r,u,x(o.length),...o,x(i.length),...i,A(n.nonce),A(n.notAfter),l))}function Vn(n){let e=n.trim();if(!/^[0-9a-fA-F]*$/.test(e)||e.length%2!==0)throw new Error("governance warrant must be an even number of hex characters");let t=new Uint8Array(e.length/2);for(let l=0;l<t.length;l+=1)t[l]=Number.parseInt(e.slice(l*2,l*2+2),16);let r=new DataView(t.buffer),o=0,i=(l,p)=>{if(o+l>t.length)throw new Error(`governance warrant ends inside ${p} (${t.length} bytes)`);let b=t.subarray(o,o+l);return o+=l,b},a=l=>r.getUint32(i(4,l).byteOffset,!0),s=l=>r.getBigUint64(i(8,l).byteOffset,!0),c=l=>{let p=a(l);if(p>64)throw new Error(`${l} cites ${p} heads, over the 64 a node accepts`);return Array.from({length:p},()=>h(i(32,l)))},u=()=>{let l=i(1,"kind")[0];if(l===0)return"group";if(l===1)return"root";throw new Error(`governance warrant has kind ${l}, expected 0 (group) or 1 (root)`)},d={scope:h(i(32,"scope")),kind:u(),authorAccount:h(i(32,"authorAccount")),deviceKey:h(i(32,"deviceKey")),executor:h(i(32,"executor")),opHash:h(i(32,"opHash")),accountHeads:c("accountHeads"),governanceFloor:c("governanceFloor"),nonce:s("nonce"),notAfter:s("notAfter"),signature:h(i(64,"signature"))};if(o!==t.length)throw new Error(`governance warrant is ${t.length} bytes but its fields account for ${o}`);return d}function qt(n){let e=Yo[n];if(e===void 0)throw new Error(`op kind must be 'group' or 'root', got ${String(n)}`);return e}var Zo={Admin:0,Member:1,ReadOnly:2},ke={MemberAdded:1,MemberRemoved:2,MemberLeft:3,MemberRoleSet:4,DefaultCapabilitiesSet:6},Ze={GroupCreated:0,GroupReparented:1,GroupDeleted:2,NamespaceCreatedV2:9},ei=new TextEncoder().encode("calimero.namespace.id.v1"),Wn=new Uint8Array(32),Xe=x(0);function zn(n){let e=Zo[n];if(e===void 0)throw new Error(`role must be Admin, Member or ReadOnly, got ${String(n)}`);return new Uint8Array([e])}function O(n){return new Uint8Array([n])}function Jn(n,e){return{kind:"group",bytes:f(O(ke.MemberAdded),g(n,"member",32),zn(e))}}function Qn(n){return{kind:"group",bytes:f(O(ke.MemberRemoved),g(n,"member",32),Wn,Xe)}}function Yn(n){return{kind:"group",bytes:f(O(ke.MemberLeft),g(n,"member",32),Wn,Xe)}}function Xn(n,e){return{kind:"group",bytes:f(O(ke.MemberRoleSet),g(n,"member",32),zn(e))}}function et(n){if(!Number.isInteger(n)||n<0||n>4294967295)throw new Error(`capabilities must be a u32 bit mask, got ${String(n)}`);if(oe(n,P.CAN_AUTHOR_ON_BEHALF))throw new Error("capabilities may not include CAN_AUTHOR_ON_BEHALF (512): a relay never carries a change to it");return{kind:"group",bytes:f(O(ke.DefaultCapabilitiesSet),x(n))}}function Zn(n){return{kind:"root",bytes:f(O(Ze.GroupCreated),g(n.groupId,"groupId",32),g(n.parentId,"parentId",32),O(n.restricted?1:0),g(n.admin,"admin",32))}}function er(n,e){return{kind:"root",bytes:f(O(Ze.GroupReparented),g(n,"childGroupId",32),g(e,"newParentId",32))}}function tr(n){return{kind:"root",bytes:f(O(Ze.GroupDeleted),g(n,"rootGroupId",32),Xe,Xe)}}async function tt(n,e){return h(await k(ei,[g(n,"founder",32),g(e,"salt",32)]))}function nt(n){let e=ie(n.credential,"credential");if(e.length===0)throw new Error("credential must be the founder's AccountProof<DeviceCert>, got nothing");return{kind:"root",bytes:f(O(Ze.NamespaceCreatedV2),g(n.founder,"founder",32),e,g(n.salt,"salt",32))}}var rt=300,X=class extends Error{constructor(t,r,o){super(`relay refused the intent (HTTP ${o}): ${t}`);this.reason=t;this.retryable=r;this.status=o;this.name="IntentRefusedError"}},ti=n=>new Promise(e=>setTimeout(e,n));function ni(n){let e=n?.get?.("Retry-After");if(!e)return null;let t=Number.parseInt(e,10);if(Number.isFinite(t)&&t>=0)return t*1e3;let r=Date.parse(e);return Number.isFinite(r)?Math.max(0,r-Date.now()):null}var F=class{constructor(e){this.config=e,this.baseUrl=e.relayUrl.replace(/\/+$/,""),this.executorAccount=e.executorAccount;let t=e.fetch;this.fetchImpl=t?(r,o)=>t(r,o):(r,o)=>globalThis.fetch(r,o),this.timeoutMs=e.timeoutMs??1e4,this.rateLimitRetries=e.rateLimitRetries??3}get relayUrl(){return this.baseUrl}get authorAccount(){return this.config.authorAccount}get authorProof(){return this.config.authorProof}async authorSigner(){return S(this.config.deviceSecret,this.config.signer,"deviceSecret")}async describe(e){let t=await this.json("GET",`/admin-api/contexts/${encodeURIComponent(e)}/intents`);return this.executorAccount=t.data.executorAccount,t.data}async execute(e,t,r={}){let o=this.executorAccount??(await this.describe(e)).executorAccount,i=await this.authorSigner(),a=await this.config.nonces.next(),s=this.config.ttlSeconds??rt,c=await Je({context:e,authorAccount:this.config.authorAccount,executor:o,method:t,argsJson:r,nonce:a,notAfter:BigInt(Math.floor(Date.now()/1e3))+BigInt(s),signer:i}),u=await this.json("POST",`/admin-api/contexts/${encodeURIComponent(e)}/intents`,{method:t,argsJson:r,warrant:c,authorProof:this.config.authorProof});return{rootHash:u.data.rootHash,returns:u.data.returns??null}}async describeCreation(e,t={}){let r=t.author?`?author=${encodeURIComponent(t.author)}`:"";return(await this.json("GET",`/admin-api/groups/${encodeURIComponent(e)}/context-intents${r}`)).data}async createContext(e){let t=await this.describeCreation(e.groupId,{author:this.config.authorAccount});if(!t.canCreateOnBehalf)throw new X(`the relay (${t.executorAccount}) has no standing to act for members of group ${t.groupId}; an admin must admit it as a relay or grant it CAN_AUTHOR_ON_BEHALF (checked before signing \u2014 no nonce was spent)`,!1,403);if(t.authorMayCreate===!1)throw new X(`the author (${this.config.authorAccount}) may not create contexts in group ${t.groupId}; it needs CAN_CREATE_CONTEXT or admin (checked before signing \u2014 no nonce was spent)`,!1,403);let r=this.checkedExecutor(t.executorAccount),o=e.initArgs??{},i=await this.authorSigner(),a=await this.config.nonces.next(),s=this.config.ttlSeconds??rt,{warrant:c}=await Ye({group:e.groupId,seed:e.seed,authorAccount:this.config.authorAccount,executor:r,applicationId:e.applicationId,serviceName:e.serviceName,name:e.name,initArgs:o,nonce:a,notAfter:BigInt(Math.floor(Date.now()/1e3))+BigInt(s),signer:i}),u=await this.json("POST",`/admin-api/groups/${encodeURIComponent(e.groupId)}/context-intents`,{warrant:c,authorProof:this.config.authorProof,initArgs:o});return{contextId:u.data.contextId,groupId:u.data.groupId,memberPublicKey:u.data.memberPublicKey}}async describeGovernance(e){return(await this.json("GET",`/admin-api/groups/${encodeURIComponent(e)}/governance-intents`)).data}async govern(e){let t=await this.describeGovernance(e.groupId);if(!t.canActOnBehalf)throw new X(`the relay (${t.executorAccount}) has no standing to act for members of group ${t.groupId}; an admin must admit it as a relay or grant it CAN_AUTHOR_ON_BEHALF (checked before signing, no nonce was spent)`,!1,403);let r=this.checkedExecutor(t.executorAccount),o=await this.authorSigner(),i=await this.config.nonces.next(),a=this.config.ttlSeconds??rt,s=await Ce({scope:e.groupId,op:e.op,authorAccount:this.config.authorAccount,executor:r,nonce:i,notAfter:BigInt(Math.floor(Date.now()/1e3))+BigInt(a),signer:o});return{groupId:(await this.postGovernance(e.groupId,e.op,s)).groupId}}async foundNamespace(e={}){let t=e.executorAccount?this.checkedExecutor(e.executorAccount):this.executorAccount;if(!t)throw new Error("foundNamespace needs the relay's account: pass executorAccount or configure it (checked before signing, no nonce was spent)");let r=e.salt?h(g(e.salt,"salt",32)):h(crypto.getRandomValues(new Uint8Array(32))),o=await tt(this.config.authorAccount,r),i=nt({founder:this.config.authorAccount,credential:this.config.authorProof,salt:r}),a=e.defaultCapabilities===void 0?void 0:et(e.defaultCapabilities),s=await this.authorSigner(),c=await this.config.nonces.next(),u=this.config.ttlSeconds??rt,d=await Ce({scope:o,op:i,authorAccount:this.config.authorAccount,executor:t,nonce:c,notAfter:BigInt(Math.floor(Date.now()/1e3))+BigInt(u),signer:s}),l=await this.postGovernance(o,i,d),p={namespaceId:l.groupId,salt:r,teeEnabled:l.teeEnabled??!1,...l.teeError?{teeError:l.teeError}:{}};if(!a)return p;try{return await this.govern({groupId:p.namespaceId,op:a}),{...p,defaultCapabilitiesSet:!0}}catch(b){return{...p,defaultCapabilitiesSet:!1,defaultCapabilitiesError:b instanceof Error?b.message:String(b)}}}async postGovernance(e,t,r){return(await this.json("POST",`/admin-api/groups/${encodeURIComponent(e)}/governance-intents`,{warrant:r,authorProof:this.config.authorProof,op:h(t.bytes)})).data}checkedExecutor(e){let t=this.config.executorAccount;if(t&&t.toLowerCase()!==e.toLowerCase())throw new Error(`configured executorAccount ${t} is not the relay's account ${e}; a warrant naming it would be unspendable`);return this.executorAccount=e,e}async json(e,t,r){let o=250;for(let i=0;;i+=1)try{return await this.jsonOnce(e,t,r)}catch(a){if(!(a instanceof C&&a.status===429)||i>=this.rateLimitRetries)throw a;let c=ni(a.headers);await ti(c??o),o*=2}}async jsonOnce(e,t,r){let o={Accept:"application/json"};r!==void 0&&(o["Content-Type"]="application/json");let i=new AbortController,a=setTimeout(()=>i.abort(),this.timeoutMs),s;try{s=await this.fetchImpl(`${this.baseUrl}${t}`,{method:e,headers:o,body:r===void 0?void 0:JSON.stringify(r),signal:i.signal})}catch(c){throw new C(0,c instanceof Error?c.name:"NetworkError",`${this.baseUrl}${t}`,new Headers,c instanceof Error?c.message:String(c))}finally{clearTimeout(a)}if(!s.ok){let c=await s.text().catch(()=>"");if(s.status===400||s.status===403){let u=ri(c);throw new X(u,/nonce/i.test(u),s.status)}throw new C(s.status,s.statusText,`${this.baseUrl}${t}`,s.headers,c)}return await s.json()}};function ri(n){if(!n)return"no reason given";try{let e=JSON.parse(n);for(let t of[e.error,e.message])if(typeof t=="string"&&t)return t}catch{}return n}var Z=class{constructor(e,t=null){this.relay=e;this.observer=t;this.kind="relay"}get canSubscribe(){return this.observer!==null}get events(){return this.observer}get client(){return this.relay}async execute(e){let{returns:t}=await this.executeWithMetadata(e);return t}async executeWithMetadata(e){let t=await this.relay.execute(e.contextId,e.method,e.argsJson??{});return{returns:t.returns,transport:"relay",rootHash:t.rootHash}}async migrateMyEntries(e){return this.execute({contextId:e,method:"migrate_my_entries"})}async countMyPending(e){return this.execute({contextId:e,method:"count_my_pending"})}};var oi=new TextEncoder().encode("calimero.auth.login.v1"),nr={webOrigin:0,codeSigningId:1,cli:2};function rr(n){let e=new TextEncoder;switch(n.kind){case"webOrigin":return e.encode(n.origin);case"codeSigningId":return e.encode(n.id);case"cli":return new Uint8Array(0)}}function ii(n){return f(Uint8Array.from([nr[n.kind]]),rr(n))}function si(n){let e=Uint8Array.from([nr[n.kind]]);if(n.kind==="cli")return e;let t=rr(n);return f(e,x(t.length),t)}async function ot(n){let e=g(n.node,"node",32),t=g(n.challenge,"challenge",32),r=g(n.sessionKey,"sessionKey",32),o=await S(n.deviceSecret,n.signer,"deviceSecret"),i=g(o.publicKey,"signer.publicKey",32),a=A(n.issuedAt),s=A(n.expiresAt),c=await k(oi,[e,ii(n.audience),t,r,i,a,s]),u=await o.sign(c);return h(f(e,si(n.audience),t,r,i,a,s,u))}var ai=300;async function Lt(){let n=h(crypto.getRandomValues(new Uint8Array(32)));return{publicKey:h(await ae(n)),secret:n}}async function it(n){let e=n.nodeUrl.replace(/\/+$/,""),t=n.timeoutMs??1e4,r=async(p,b)=>{let w=new AbortController,y=setTimeout(()=>w.abort(),t),T;try{let R={...b,signal:w.signal};T=n.fetch?await n.fetch(`${e}${p}`,R):await globalThis.fetch(`${e}${p}`,R)}catch(R){throw new C(0,R instanceof Error?R.name:"NetworkError",`${e}${p}`,new Headers,R instanceof Error?R.message:String(R))}finally{clearTimeout(y)}let v=await T.text().catch(()=>"");if(!T.ok)throw new C(T.status,T.statusText,`${e}${p}`,T.headers,v);return v?JSON.parse(v):{}},o=await r("/auth/challenge",{method:"GET",headers:{Accept:"application/json"}}),i=o.challenge??o.data?.challenge;if(!i)throw new Error("the node issued no challenge");let a=await Lt(),s=Math.floor(Date.now()/1e3),c=await ot({node:n.node,audience:n.audience,challenge:i,sessionKey:a.publicKey,issuedAt:s,expiresAt:s+(n.ttlSeconds??ai),signer:await S(n.deviceSecret,n.signer,"deviceSecret")}),u=await r("/auth/token",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({auth_method:"account_proof",public_key:a.publicKey,client_name:n.clientName??e,timestamp:s,provider_data:{challenge:i,login_statement:c,account_proof:n.accountProof}})}),d=u.access_token??u.data?.access_token,l=u.refresh_token??u.data?.refresh_token;if(!d)throw new Error("the node minted no session");return{accessToken:d,refreshToken:l??"",sessionKey:a.publicKey,sessionSecret:a.secret}}var ci=3e4;function st(){let n=globalThis.location?.origin;return n?{kind:"webOrigin",origin:n}:{kind:"cli"}}function li(n){try{let e=n.split(".");if(e.length!==3)return null;let t=e[1].replace(/-/g,"+").replace(/_/g,"/");for(;t.length%4;)t+="=";let r=JSON.parse(atob(t));return typeof r.exp=="number"?r.exp*1e3:null}catch{return null}}var de=class{constructor(e){this.session=null;this.sessionExpiresAt=null;this.pending=null;this.sseClient=null;this.wsClient=null;this.config=e}get nodeKey(){return this.config.nodeKey}async accessToken(){let e=Date.now();return this.session&&this.sessionExpiresAt!==null&&this.sessionExpiresAt-ci>e?this.session.accessToken:(this.pending||(this.pending=this.loginNow().finally(()=>{this.pending=null})),(await this.pending).accessToken)}async loginNow(){let e=await it({nodeUrl:this.config.nodeUrl,node:this.config.nodeKey,signer:await this.config.signer(),accountProof:this.config.accountProof,audience:this.config.audience,clientName:this.config.clientName,ttlSeconds:this.config.ttlSeconds,fetch:this.config.fetch,timeoutMs:this.config.timeoutMs});return this.session=e,this.sessionExpiresAt=li(e.accessToken),e}get events(){return this.sseClient||(this.sseClient=new M({baseUrl:this.config.nodeUrl,getAuthToken:()=>this.accessToken()})),this.sseClient}get ws(){return this.wsClient||(this.wsClient=new K({baseUrl:this.config.nodeUrl,getAuthToken:()=>this.accessToken()})),this.wsClient}close(){this.sseClient?.close(),this.wsClient?.close()}};var $=n=>new TextEncoder().encode(n),ui=$("calimero.auth.request.v1"),di=$("calimero.auth.request.body.v1"),Kt="X-Calimero-Proof",pi=300;async function Bt(n){let{method:e,path:t,credential:r}=n;if(!e)throw new Error("signRequestProof needs the method the request will use");if(!t.startsWith("/"))throw new Error(`signRequestProof needs a path, got ${JSON.stringify(t)}`);if(t.includes("?"))throw new Error(`the path must carry no query string, got ${JSON.stringify(t)} \u2014 a query is excluded from the signature on purpose, because a proxy may rewrite one. Anything that must be bound belongs in the body.`);let o=n.body===void 0?new Uint8Array:typeof n.body=="string"?$(n.body):n.body,i=await k(di,[o]),a=Math.floor(n.now??Date.now()/1e3),s=a+(n.validForSeconds??pi),c=await k(ui,[$(e),$(t),i,A(a),A(s)]),u=await gi(c,n);if(u.length!==64)throw new Error(`the signer returned ${u.length} bytes, not a 64-byte signature`);let d=f(x($(e).length),$(e),x($(t).length),$(t),i,A(a),A(s),u),l=mi(r,"credential");return h(f(l,new Uint8Array([0]),d))}async function gi(n,e){if(e.signer)return e.signer.sign(n);if(!e.deviceSecret)throw new Error("signRequestProof needs either `deviceSecret` or `signer`");let t=await se(e.deviceSecret);return new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},t,n))}function mi(n,e){let t=n.trim();if(!/^[0-9a-fA-F]*$/.test(t)||t.length%2!==0)throw new Error(`${e} is not an even-length hex string`);return g(t,e,t.length/2)}function jt(n){if(!n.credential)throw new Error("a proof authorizer needs the `credential` from signDeviceCert");if(!n.deviceSecret&&!n.signer)throw new Error("a proof authorizer needs either `deviceSecret` or `signer`");return async({method:e,path:t,body:r})=>{let o=await Bt({method:e,path:t,body:r,credential:n.credential,deviceSecret:n.deviceSecret,signer:n.signer,validForSeconds:n.validForSeconds});return{[Kt]:o}}}function hi(n){return new URL(n).pathname}function Ft(n,e){return new Error(`this client was constructed with the relay transport, which has no ${n}: ${e}. Construct a node client (createMeroClient({ baseUrl })) for that surface \u2014 nothing here will silently connect to a node you did not choose.`)}function or(n){return new Error(`this relay-transport client cannot open ${n}: it was given no relay node key. A relay is an ordinary node and does serve /sse and /ws \u2014 but the login statement must be signed against the node's device signing key, learned out of band (never read from the node, and never derived from its peerId). Pass it as \`observe: { nodeKey }\`. For a cloud-hosted relay the cloud does not publish it yet \u2014 see mdma #312.`)}function fi(n,e){let t=e?.nodeKey;return t?new de({nodeUrl:e?.nodeUrl??n.relayUrl,nodeKey:t,accountProof:e?.accountProof??n.authorProof,audience:e?.audience??st(),signer:e?.signer?async()=>e.signer:()=>n.authorSigner(),clientName:e?.clientName,ttlSeconds:e?.ttlSeconds,fetch:e?.fetch,timeoutMs:e?.timeoutMs}):null}var ee=class{constructor(e){this.relayObserver=null;this.relayAdmin=null;this.proofAuthorizer=null;this.relayUrl=null;this.proofEvents=null;if(e.transport==="relay"){this.transport="relay",this.nodeClient=null;let o=e.relay instanceof F?e.relay:new F(e.relay);if(this.relayObserver=fi(o,e.observe),this.rpcTransport=new Z(o,this.relayObserver),this.relayUrl=o.relayUrl,e.proof&&(this.proofAuthorizer=jt(e.proof)),e.session){let i=e.session;this.relayAdmin=hn({baseUrl:o.relayUrl,getAuthToken:typeof i=="string"?async()=>i:i})}else if(this.proofAuthorizer){let i=this.proofAuthorizer;this.relayAdmin=_e(be({fetch:(a,s)=>globalThis.fetch(a,s),baseUrl:o.relayUrl,authorizeRequest:i}),{baseUrl:o.relayUrl})}return}this.transport="node";let{transport:t,...r}=e;this.nodeClient=new ue(r),this.rpcTransport=this.nodeClient.rpc}get rpc(){return this.rpcTransport}get canSubscribe(){return this.rpcTransport.canSubscribe||this.proofAuthorizer!==null}get node(){if(!this.nodeClient)throw Ft("node connection","it holds a signing key and a relay URL, not a node");return this.nodeClient}get relay(){if(!(this.rpcTransport instanceof Z))throw new Error("this client was constructed with the node transport and has no relay");return this.rpcTransport.client}get admin(){if(this.nodeClient)return this.nodeClient.admin;if(this.relayAdmin)return this.relayAdmin;throw new Error("this relay-transport client has no admin surface because it was given neither a `proof` nor a `session`. A warrant authorises one intent and is not a credential for reading. The caller-scoped reads (getContexts, listNamespaces) want one of the other two: pass `proof: { credential, deviceSecret }` \u2014 the device cert you already hold, which needs no login and no node key \u2014 or a `session` minted with `login()`. Context STATE reads work through execute/query either way.")}get auth(){return this.node.auth}get events(){if(this.nodeClient)return this.nodeClient.events;if(this.relayObserver)return this.relayObserver.events;if(this.proofAuthorizer&&this.relayUrl)return this.proofEvents??(this.proofEvents=new M({baseUrl:this.relayUrl,authorize:this.proofAuthorizer})),this.proofEvents;throw or("SSE events")}get ws(){if(this.nodeClient)return this.nodeClient.ws;if(this.relayObserver)return this.relayObserver.ws;throw this.proofAuthorizer?new Error("this client authenticates with a request proof, which cannot open a WebSocket from a browser: `WebSocket` cannot set the X-Calimero-Proof header, and core's guard reads the proof from a header only (the ?token= query parameter is the session equivalent and has no proof counterpart). Use `client.events` \u2014 SSE is fetch-based, carries the header, and is the recommended transport anyway."):or("WebSocket events")}get ephemeral(){if(!this.nodeClient)throw Ft("ephemeral presence","publishing resolves the author from an owned context identity on the node, which a delegated session is not known to have \u2014 read presence off `client.events` instead");return this.nodeClient.ephemeral}get cloud(){if(!this.nodeClient)throw Ft("bundled cloud client","a relay client is built from a cloud connection rather than owning one \u2014 reach it through the `cloud` field that `connectCloud` returns, or construct a `CloudClient` directly");return this.nodeClient.cloud}close(){this.nodeClient?.close(),this.relayObserver?.close(),this.proofEvents?.close()}};function ir(n){return new ee(n)}function ct(n=1){let e=BigInt(n);if(e<1n)throw new Error("nonce sequence starts at 1");return{next(){let t=e;return e+=1n,Promise.resolve(t)},advanceTo(t){return t>e&&(e=t),Promise.resolve()}}}function Vt(n,e){let t=e??globalThis.localStorage;if(!t)throw new Error("no localStorage in this runtime: pass a storage implementation, or use createMemoryNonceSource for a process that owns its whole sequence");let r=()=>{let o=t.getItem(n);if(o===null||o==="")return 0n;try{let i=BigInt(o);return i>0n?i:0n}catch{return 0n}};return{next(){let o=r()+1n;return t.setItem(n,o.toString()),Promise.resolve(o)},advanceTo(o){let i=o>0n?o-1n:0n;return i>r()&&t.setItem(n,i.toString()),Promise.resolve()}}}function yi(n){return{getWarrantNonce:(e,t)=>n.client.getWarrantNonceAsAuthor(e,n.authorProof)}}var at=class extends Error{constructor(t,r){super(`author device ${r} has spent every nonce in context ${t}; it must re-key to write again`);this.contextId=t;this.authorDeviceKey=r;this.name="WarrantNonceExhaustedError"}};function bi(n){let e=Array.isArray(n.lookups)?n.lookups:[n.lookups];if(e.length===0)throw new Error("a recovering nonce source needs at least one node to ask");let t=n.local??ct(1),r=n.onLookupFailure??"throw",o=null,i=null,a=async()=>{let s=await Promise.allSettled(e.map(d=>d.getWarrantNonce(n.contextId,n.authorDeviceKey))),c=null,u=!1;for(let d of s){if(d.status!=="fulfilled")continue;let l=d.value;if(l.kind==="exhausted"){u=!0;continue}(c===null||l.nextNonce>c)&&(c=l.nextNonce)}if(c===null&&u)throw new at(n.contextId,n.authorDeviceKey);if(c===null){let d=s.find(p=>p.status==="rejected"),l=d&&d.status==="rejected"?d.reason:void 0;if(r==="local"){o=0n;return}throw l instanceof Error?l:new Error(`no node could answer where the warrant-nonce sequence stands: ${String(l)}`)}o=c,await t.advanceTo?.(c)};return{async next(){o===null&&(i??(i=a().finally(()=>{i=null})),await i);let s=await t.next(),c=o!==null&&o>s?o:s;return o=c+1n,c},async advanceTo(s){(o===null||s>o)&&(o=s),await t.advanceTo?.(s)}}}var wi="Noise_NK_25519_AESGCM_SHA256",Wt=32,Ai=16,xi=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,110,4,34,4,32]),Jt=class n{constructor(e){this.k=null;this.n=0;this.ck=e,this.h=e}static async initialize(){let e=new TextEncoder().encode(wi),t=new Uint8Array(32);return t.set(e),new n(t)}async mixHash(e){this.h=await vi(f(this.h,e))}async mixKey(e){let[t,r]=await cr(this.ck,e);this.ck=t,this.k=await crypto.subtle.importKey("raw",r,"AES-GCM",!1,["encrypt","decrypt"]),this.n=0}async encryptAndHash(e){if(!this.k)throw new Error("Noise: no cipher key yet");let t=new Uint8Array(await crypto.subtle.encrypt({name:"AES-GCM",iv:ar(this.n),additionalData:this.h},this.k,e));return this.n+=1,await this.mixHash(t),t}async decryptAndHash(e){if(!this.k)throw new Error("Noise: no cipher key yet");let t=new Uint8Array(await crypto.subtle.decrypt({name:"AES-GCM",iv:ar(this.n),additionalData:this.h},this.k,e));return this.n+=1,await this.mixHash(e),t}split(){return cr(this.ck,new Uint8Array)}};async function lr(n,e,t){let r=await Jt.initialize();await r.mixHash(e),await r.mixHash(n);let o=await Ri(t);return await r.mixHash(o.publicKey),await r.mixKey(await sr(o.privateKey,n)),{message1:f(o.publicKey,await r.encryptAndHash(new Uint8Array)),async finish(a){if(a.length<Wt+Ai)throw new Error("Noise: message 2 is too short");let s=a.slice(0,Wt);return await r.mixHash(s),await r.mixKey(await sr(o.privateKey,s)),{payload:await r.decryptAndHash(a.slice(Wt)),split:await r.split()}}}}async function Ri(n){if(!n){let r;try{r=await crypto.subtle.generateKey({name:"X25519"},!0,["deriveBits"])}catch(i){throw new Error(`Sealed transport needs WebCrypto with X25519, which this runtime lacks (${i?.name??"no crypto.subtle"}). Current browsers and Node have it; in React Native, install react-native-quick-crypto as the global crypto.`)}let o=new Uint8Array(await crypto.subtle.exportKey("raw",r.publicKey));return{privateKey:r.privateKey,publicKey:o}}let e=await crypto.subtle.importKey("pkcs8",f(xi,n),{name:"X25519"},!0,["deriveBits"]),t=await crypto.subtle.exportKey("jwk",e);return{privateKey:e,publicKey:Ci(t.x)}}async function sr(n,e){let t=await crypto.subtle.importKey("raw",e,{name:"X25519"},!1,[]);return new Uint8Array(await crypto.subtle.deriveBits({name:"X25519",public:t},n,256))}function ar(n){let e=new Uint8Array(12);return new DataView(e.buffer).setBigUint64(4,BigInt(n),!1),e}async function vi(n){return new Uint8Array(await crypto.subtle.digest("SHA-256",n))}async function zt(n,e){let t=await crypto.subtle.importKey("raw",n,{name:"HMAC",hash:"SHA-256"},!1,["sign"]);return new Uint8Array(await crypto.subtle.sign("HMAC",t,e))}async function cr(n,e){let t=await zt(n,e),r=await zt(t,new Uint8Array([1])),o=await zt(t,f(r,new Uint8Array([2])));return[r,o]}function Ci(n){let e=n.replace(/-/g,"+").replace(/_/g,"/"),t=atob(e+"=".repeat((4-e.length%4)%4));return Uint8Array.from(t,r=>r.charCodeAt(0))}var gr="/sealed/v2/handshake",mr="/sealed/v2",Ee="application/vnd.calimero.sealed",Qt=2,ki=new TextEncoder().encode("calimero/sealed-http/v2"),Se=16,Si=1+Se+8,Ei=0,Ti=1,Pi=2,Ii=1+64*1024+16,Di=1024,Ui=6e4,Ni="calimero.tee-attest.transport-key.v1",Mi=[101,204,205,304],hr=new TextEncoder,Te=class extends Error{constructor(){super("The node no longer holds the attested transport key; attest again for the current one");this.name="StaleTransportKeyError"}},pe=class extends Error{constructor(t,r,o,i){super(o);this.status=t;this.code=r;this.retryAfterMs=i;this.name="SealedTransportError"}};async function fr(n,e){let t=await crypto.subtle.digest("SHA-256",f(hr.encode(Ni),n,e));return new Uint8Array(t)}async function yr(n,e,t={}){if(t.applicationId===void 0!=(t.applicationHash===void 0))throw new Error("applicationId and applicationHash are given together or not at all");let r=h(crypto.getRandomValues(new Uint8Array(32))),o=await n.teeAttest({nonce:r,applicationId:t.applicationId,bindTransportKey:!0,...e.includeCollateral?{includeCollateral:!0}:{}});if(!o.transportPublicKey)throw new Error("The node did not report a transport key; it predates sealed transport");let i=g(o.transportPublicKey,"transportPublicKey",32),a=t.applicationHash?g(t.applicationHash,"applicationHash",32):new Uint8Array(32),s=h(await fr(a,i));if(!await e({quoteB64:o.quoteB64,nonce:r,reportDataSuffix:s,collateral:o.collateral}))throw new Error("The attestation did not verify, so its transport key is not trusted");return i}function Pe(n){let e=n.fetch??((o,i)=>fetch(o,i)),t=`${n.baseUrl.replace(/\/+$/,"")}/admin-api/tee/attest`,r={async teeAttest(o){let i=await e(t,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(o)});if(!i.ok)throw new Error(`The node refused to attest: HTTP ${i.status}`);let a=await i.json();if(!a.data)throw new Error("The attestation response is malformed");return a.data}};return br({baseUrl:n.baseUrl,transportPublicKey:()=>yr(r,n.verify,{applicationId:n.applicationId,applicationHash:n.applicationHash}),fetch:e})}function br(n){let e=new URL(n.baseUrl),t=e.pathname.replace(/\/+$/,""),r=`${e.origin}${t}`,o=n.fetch??((l,p)=>fetch(l,p)),i=typeof n.transportPublicKey=="function"?n.transportPublicKey:void 0,a=i?Promise.resolve().then(i):Promise.resolve(n.transportPublicKey);a.catch(()=>{});let s,c=async()=>{try{return await dr(o,r,await ur(a))}catch(l){if(!(l instanceof Te)||!i)throw l;return a=Promise.resolve().then(i),dr(o,r,await ur(a))}},u=async()=>{let l=s??d(void 0),p=await l;if(Date.now()<p.renewAt)return[p,l];let b=d(l);return[await b,b]},d=l=>{if(s===l){let p=c();s=p,p.catch(()=>{s===p&&(s=void 0)})}return s};return async(l,p)=>{let b=new Request(l,p),w=new URL(b.url);if(w.origin!==e.origin||!w.pathname.startsWith(`${t}/`))throw new Error(`Refusing to send ${w.href} outside the sealed node at ${n.baseUrl}`);let y=[];b.headers.forEach((I,N)=>y.push([N,I]));let T={method:b.method,path:w.pathname.slice(t.length)+w.search,headers:y},v=new Uint8Array(await b.arrayBuffer()),R=async I=>{let{requestId:N,header:W,envelope:z}=await Oi(I,T,v),J=await o(`${r}${mr}`,{method:"POST",headers:{"content-type":Ee},body:z,signal:b.signal});if(J.headers.get("content-type")!==Ee)throw await Ar(J);return Hi(J,I.responseKey,W,N)},[q,U]=await u();try{return await R(q)}catch(I){if(!(I instanceof pe)||I.code!=="unknown_session")throw I;return R(await d(U))}}}async function ur(n){let e=await n;if(e.length!==32)throw new Error("transportPublicKey must be 32 bytes");return e}async function dr(n,e,t){try{return await pr(n,e,t)}catch(r){if(!(r instanceof pe)||r.code!=="busy")throw r;return await new Promise(o=>setTimeout(o,r.retryAfterMs??1e3)),pr(n,e,t)}}async function pr(n,e,t){let r=await lr(t,ki),o=await n(`${e}${gr}`,{method:"POST",headers:{"content-type":Ee},body:f(new Uint8Array([Qt]),t,r.message1)});if(o.headers.get("content-type")!==Ee)throw await Ar(o);let i=await qi(o,Di);return _i(r,i)}async function _i(n,e){if(e[0]!==Qt)throw new Error("The handshake reply is malformed");let t;try{t=await n.finish(e.slice(1))}catch{throw new Error("The handshake reply did not open: it did not come from the attested node")}let{payload:r,split:o}=t;if(r.length!==Se+4)throw new Error("The handshake reply is malformed");let i=r.slice(0,Se),a=new DataView(r.buffer,r.byteOffset).getUint32(Se,!1),[s,c]=await Promise.all([crypto.subtle.importKey("raw",o[0],"AES-GCM",!1,["encrypt"]),crypto.subtle.importKey("raw",o[1],"AES-GCM",!1,["decrypt"])]);return o[0].fill(0),o[1].fill(0),{requestKey:s,responseKey:c,nextRequestId:1,renewAt:Date.now()+a*1e3-Ui,header(u){let d=new Uint8Array(Si);return d[0]=Qt,d.set(i,1),new DataView(d.buffer).setBigUint64(1+Se,BigInt(u),!1),d}}}async function Oi(n,e,t){let r=n.nextRequestId;n.nextRequestId+=1;let o=n.header(r),i=await crypto.subtle.encrypt({name:"AES-GCM",iv:wr(r,0),additionalData:o},n.requestKey,Gi(e,t));return{requestId:r,header:o,envelope:f(o,new Uint8Array(i))}}function wr(n,e){let t=new Uint8Array(12),r=new DataView(t.buffer);return r.setBigUint64(0,BigInt(n),!1),r.setUint32(8,e,!1),t}function Gi(n,e){let t=hr.encode(JSON.stringify(n)),r=new Uint8Array(4);return new DataView(r.buffer).setUint32(0,t.length,!1),f(r,t,e)}async function Hi(n,e,t,r){if(!n.body)throw new Error("The sealed response has no body");let o=$i(n.body.getReader()),i=0,a=async()=>{let d=await o.next();if(!d)return null;let l;try{l=new Uint8Array(await crypto.subtle.decrypt({name:"AES-GCM",iv:wr(r,i),additionalData:t},e,d))}catch{throw new Error("A sealed response frame did not open: it was not sealed by the attested node")}return i+=1,{kind:l[0],data:l.slice(1)}},s=await a();if(!s||s.kind!==Ei)throw new Error("The sealed response is malformed");let c=JSON.parse(new TextDecoder().decode(s.data));if(Mi.includes(c.status))return await o.cancel(),new Response(null,{status:c.status,headers:c.headers});let u=new ReadableStream({async pull(d){try{let l=await a();l?l.kind===Ti?d.enqueue(l.data):l.kind===Pi?(d.close(),await o.cancel()):d.error(new Error("The sealed response is malformed")):d.error(new Error("The sealed response was cut short"))}catch(l){d.error(l)}},cancel(){return o.cancel()}});return new Response(u,{status:c.status,headers:c.headers})}function $i(n){let e=new Uint8Array,t=async r=>{for(;e.length<r;){let{done:o,value:i}=await n.read();if(o)return!1;e=f(e,i)}return!0};return{async next(){if(!await t(4))return null;let r=new DataView(e.buffer,e.byteOffset).getUint32(0,!1);if(r>Ii)throw await n.cancel(),new Error("The sealed response is malformed: a frame is larger than the node sends");if(!await t(4+r))return null;let o=e.slice(4,4+r);return e=e.slice(4+r),o},cancel:()=>n.cancel()}}async function qi(n,e){if(!n.body)return new Uint8Array;let t=n.body.getReader(),r=new Uint8Array;for(;;){let{done:o,value:i}=await t.read();if(o)return r;if(r=f(r,i),r.length>e)throw await t.cancel(),new Error("The handshake reply is malformed: it is too long")}}async function Ar(n){let e,t=`Sealed request refused: HTTP ${n.status}`;try{let i=await n.json();e=i?.error?.code,i?.error?.message&&(t=`Sealed request refused: ${i.error.message}`)}catch{}if(e==="stale_transport_key")return new Te;let r=Number(n.headers.get("retry-after")),o=Number.isFinite(r)&&r>0?Math.min(r,5)*1e3:void 0;return new pe(n.status,e,t,o)}async function xr(n){if(!n.sessionToken&&!n.googleIdToken)throw new Error("connectCloud needs either a sessionToken or a googleIdToken");let e=await S(n.deviceSecret,n.signer,"deviceSecret"),t=new _({cloudBaseUrl:n.cloudBaseUrl,sessionToken:n.sessionToken,onSession:n.onSession,fetch:n.fetch,timeoutMs:n.timeoutMs});!n.sessionToken&&n.googleIdToken&&await t.signInWithGoogle(n.googleIdToken);let r=await t.getMyNamespaces(),o=Ki(r,n.namespaceId),i=await t.getNamespaceRelays(o.namespaceId),a=Nt(i);if(!a)throw new Error(Bi(o,i));let s=new F({relayUrl:a.relayUrl,executorAccount:a.executorAccount,authorAccount:n.authorAccount,authorProof:n.authorProof,signer:e,nonces:n.nonces??ji(e.publicKey),ttlSeconds:n.ttlSeconds,fetch:n.seal?Pe({baseUrl:a.relayUrl,verify:n.seal,fetch:n.fetch}):n.fetch,timeoutMs:n.timeoutMs});return{cloud:t,relay:s,namespaceId:o.namespaceId,namespace:o,relayInfo:a,execute:(c,u,d)=>s.execute(c,u,d),client:new ee({transport:"relay",relay:s,observe:{nodeKey:n.relayNodeKey??a.nodeKey,audience:n.observeAudience,fetch:n.fetch,timeoutMs:n.timeoutMs}})}}async function Li(n){let{root:e,authorAccount:t,...r}=n,o=await S(r.deviceSecret,r.signer,"deviceSecret"),i=await H(e),s=await new _({cloudBaseUrl:n.cloudBaseUrl,onSession:n.onSession,fetch:n.fetch,timeoutMs:n.timeoutMs}).signInWithAccount(i.signer);return xr({...r,deviceSecret:void 0,signer:o,sessionToken:s.sessionToken,authorAccount:t??i.accountId})}function Ki(n,e){if(e){let t=n.find(r=>r.namespaceId===e);if(!t)throw new Error(`this account owns no namespace ${e}; it owns: ${n.map(r=>r.namespaceId).join(", ")||"(none)"}`);return t}if(n.length===0)throw new Error("this account owns no namespaces in the cloud: claim one first, then enable HA on it so a relay is assigned");if(n.length>1)throw new Error(`this account owns ${n.length} namespaces \u2014 pass namespaceId to say which: ${n.map(t=>t.namespaceId).join(", ")}`);return n[0]}function Bi(n,e){if(e.length===0)return n.haStatus==="enabled"?`namespace ${n.namespaceId} has HA enabled but no relay has been assigned to it yet \u2014 retry shortly`:`namespace ${n.namespaceId} has no relays: enable HA on it in the cloud to have an attested node assigned`;let t=e.filter(o=>o.teeRole!==null&&o.teeRole!=="RelayTee");if(t.length===e.length)return`every node on namespace ${n.namespaceId} is a read-only TEE replica (ReadOnlyTee), which never relays delegated writes: an admin of the namespace must set its TEE admission policy with mode: 'relay' \u2014 AdminClient.setTeeAdmissionPolicy(namespaceId, { ..., mode: 'relay' }) \u2014 so fleet nodes are admitted as RelayTee`;let r=e.filter(o=>o.teeRole===null&&!o.authorshipReady);return r.length>0&&r.length+t.length===e.length?`every relay on namespace ${n.namespaceId} is waiting for the authorship grant: an admin of the namespace must grant CAN_AUTHOR_ON_BEHALF to ${r.map(o=>o.executorAccount??o.peerId).join(", ")||"the relay account"} \u2014 with AdminClient.grantAuthorship(namespaceId, account) for these relays, and AdminClient.openToDelegatedExecution(namespaceId) so relays assigned later need no further op`:`namespace ${n.namespaceId} has ${e.length} relay(s), but none is ready to relay yet (a URL, an executor account and a recent heartbeat) \u2014 retry shortly`}function ji(n){let e=`mero-js:warrant-nonce:${n}`;try{return Vt(e)}catch{return ct(1)}}var Fi="https://cloud.calimero.network";function vr(n){if(!/^[0-9a-f]{64}$/.test(n.accountId))throw new Error("accountId must be 64 lowercase hex characters");let e=new URL(n.cloudWebUrl??Fi);return e.searchParams.set("link-account",n.accountId),e.searchParams.set("callback-url",n.returnTo),e.toString()}function Vi(n){throw window.location.assign(vr(n)),new Error("redirecting to the cloud to authorise this link")}function Wi(n=window.location){let e=new URLSearchParams(n.hash.replace(/^#/,"")),t=e.get("error");if(t)throw Rr(),new Error(t==="denied"?"the account link was declined at the cloud":`the cloud refused this link: ${t}`);let r=e.get("grant"),o=e.get("account");return!r||!o?null:(Rr(),{grant:r,account:o})}function Rr(){typeof history>"u"||!history.replaceState||history.replaceState(null,"",location.pathname+location.search)}async function zi(n){let e=await H(n.root);if(e.accountId!==n.account)throw new Error(`this grant is for account ${n.account}, but the root here derives ${e.accountId} \u2014 it was minted for a different account`);return new _({cloudBaseUrl:n.cloudBaseUrl,fetch:n.fetch}).linkAccountWithGrant({grant:n.grant,signer:e.signer})}var Ji="enrol-device",Qi="enrol-kem",Yi="callback-url",Xi="state";function Sr(n){kr(n.devicePublicKey,"devicePublicKey"),kr(n.kemPublicKey,"kemPublicKey"),rs(n.returnTo),ns(n.returnTo);let e=new URL(n.walletUrl);return e.searchParams.set(Ji,n.devicePublicKey),e.searchParams.set(Qi,n.kemPublicKey),e.searchParams.set(Yi,n.returnTo),n.state&&e.searchParams.set(Xi,n.state),e.toString()}function Zi(n){throw window.location.assign(Sr(n)),new Error("redirecting to the wallet to approve this device")}function es(n=window.location){let e=new URLSearchParams(n.hash.replace(/^#/,"")),t=e.get("error");if(t)throw Cr(),new Error(t==="denied"||t==="cancelled"?"the device was not approved at the wallet":`the wallet refused this enrolment: ${t}`);let r=e.get("credential"),o=e.get("account"),i=e.get("device");if(!r||!o||!i)return null;Cr();let a=e.get("state");return{credential:r,account:o,device:i,...a?{state:a}:{}}}function Cr(){typeof history>"u"||!history.replaceState||history.replaceState(null,"",location.pathname+location.search)}async function ts(n){if(n.expectState!==void 0&&n.expectState!==n.state)throw new Error("this enrolment answers a request this app did not make \u2014 the state it carries is not the one sent");let e=await je(n.credential);if(e.signPublicKey!==te(n.devicePublicKey))throw new Error(`this credential certifies device key ${e.signPublicKey}, but this app holds ${te(n.devicePublicKey)} \u2014 it would sign with a key the certificate does not cover`);if(n.kemPublicKey!==void 0&&e.kemPublicKey!==te(n.kemPublicKey))throw new Error(`this credential names delivery key ${e.kemPublicKey}, not the one this app asked about \u2014 group keys would be sealed to somebody else`);if(e.account!==te(n.account))throw new Error(`the wallet reported account ${te(n.account)}, but the credential names ${e.account}`);if(e.device!==te(n.device))throw new Error(`the wallet reported device ${te(n.device)}, but the credential names ${e.device}`);return{credential:n.credential,account:e.account,device:e.device,certificate:e}}function kr(n,e){if(!/^[0-9a-f]{64}$/.test(n))throw new Error(`${e} must be 64 lowercase hex characters`)}function te(n){return n.trim().toLowerCase()}function Er(n,e){let t=e??(typeof window>"u"?void 0:window.location.origin);if(!t)return!1;try{return new URL(n).origin!==t}catch{return!1}}function ns(n){Er(n)&&console.warn(`[calimero] enrolling a device but sending the credential to ${new URL(n).origin}, which is not this page's origin. Legitimate when deliberate; worth a second look otherwise.`)}function rs(n){let e;try{e=new URL(n)}catch{throw new Error(`returnTo must be an absolute URL, got ${n}`)}let t=e.hostname==="localhost"||e.hostname==="127.0.0.1"||e.hostname==="[::1]"||e.hostname==="::1";if(e.protocol!=="https:"&&!(e.protocol==="http:"&&t))throw new Error(`returnTo must be https:, or http: on localhost \u2014 got ${e.protocol}//${e.hostname}`)}var os=/^[0-9a-f]{96}$/,is=["mrtd","rtmr0","rtmr1","rtmr2","rtmr3"];function Yt(n){let e=ge(n.allowedMrtd??[],"allowedMrtd"),t=(n.allowedMeasurements??[]).map((s,c)=>{let u=`allowedMeasurements[${c}]`;return is.map(d=>ge([s?.[d]??""],`${u}.${d}`)[0]).join()}),r=[ge(n.allowedRtmr0??[],"allowedRtmr0"),ge(n.allowedRtmr1??[],"allowedRtmr1"),ge(n.allowedRtmr2??[],"allowedRtmr2"),ge(n.allowedRtmr3??[],"allowedRtmr3")];if(n.allowedMeasurements!==void 0&&t.length===0)throw new Error("allowedMeasurements is empty, so no quote would ever be accepted");if(t.length===0){if(e.length===0)throw new Error("No image is trusted: give allowedMeasurements, or allowedMrtd with allowedRtmr1-3");if(r.slice(1).some(s=>s.length===0))throw new Error("allowedMrtd alone does not name an image: the MRTD measures the TD firmware, which images share, and the image is in RTMR1-3. Give allowedMeasurements, or allowedRtmr1-3 too")}let o=n.allowedTcbStatuses??["UpToDate"],i=n.now??Date.now;return Object.assign(async({quoteB64:s,nonce:c,reportDataSuffix:u,collateral:d})=>{let l=as(s),p=d??await n.fetchCollateral?.(l);if(!p)throw new Error("The node sent no collateral for its quote, and no fetchCollateral was given to get it");let b;try{b=n.dcapVerify(l,p,Math.floor(i()/1e3))}catch(v){throw new Error(`The quote did not verify: ${v?.message??String(v)}`)}if(b.status==="Revoked"||!o.includes(b.status))throw new Error(`The platform's TCB status is ${b.status}, which is not accepted`);let w=ss(b.report),y=[w.mrTd,w.rtMr0,w.rtMr1,w.rtMr2,w.rtMr3].map(v=>h(v));if(t.length>0&&!t.includes(y.join()))throw new Error(`The measurements (MRTD ${y[0]}, RTMR0-3 ${y.slice(1).join(", ")}) are not an image this verifier trusts`);if(e.length>0&&!e.includes(y[0]))throw new Error(`MRTD ${y[0]} is not an image this verifier trusts`);if([w.rtMr0,w.rtMr1,w.rtMr2,w.rtMr3].forEach((v,R)=>{let q=r[R];if(q.length>0&&!q.includes(h(v)))throw new Error(`RTMR${R} ${h(v)} is not one this verifier trusts`)}),h(w.reportData)!==`${c}${u}`.toLowerCase())throw new Error("The quote does not commit to this nonce and binding");return!0},{includeCollateral:!0})}function ge(n,e){return n.map(t=>{let r=t.trim().toLowerCase();if(!os.test(r))throw new Error(`${e} holds ${JSON.stringify(t)}, which is not a 48-byte hex measurement`);return r})}function ss(n){let e=n.data;if(n.type==="td10"&&e)return e;if(n.type==="td15"&&e?.base)return e.base;throw new Error(`The quote is a ${n.type} quote, not a TDX one`)}function as(n){let e=atob(n),t=new Uint8Array(e.length);for(let r=0;r<e.length;r+=1)t[r]=e.charCodeAt(r);return t}var cs=["UpToDate","SWHardeningNeeded","ConfigurationNeeded","ConfigurationAndSWHardeningNeeded","OutOfDate","OutOfDateConfigurationNeeded"];function Xt(n,{profile:e}){if(n.length===0)throw new Error("No release given, so no image would be trusted");let t,r=n.map((o,i)=>{let a=o?.tag??`releases[${i}]`;if(o?.role!==void 0&&o.role!=="node")throw new Error(`${a} lists the measurements of a ${o.role}, not of a node image`);let s=o?.profiles?.[e];if(!s){let u=Object.keys(o?.profiles??{}).join(", ")||"none";throw new Error(`${a} has no profile ${JSON.stringify(e)} (it has: ${u})`)}let c=(s.allowed_tcb_statuses??["uptodate"]).map(u=>ls(u,a));return t=t===void 0?c:t.filter(u=>c.includes(u)),{mrtd:s.mrtd,rtmr0:s.rtmr0,rtmr1:s.rtmr1,rtmr2:s.rtmr2,rtmr3:s.rtmr3}});if(!t||t.length===0)throw new Error("The releases given accept no TCB status in common");return{allowedMeasurements:r,allowedTcbStatuses:t}}function ls(n,e){let t=cs.find(r=>r.toLowerCase()===String(n).toLowerCase());if(!t)throw new Error(`${e} accepts TCB status ${JSON.stringify(n)}, which this verifier does not know`);return t}var Tr=[{uri:"https://fulcio.sigstore.dev",validFor:{start:"2021-03-07T03:20:29Z",end:"2022-12-31T23:59:59.999Z"},certChain:["MIIB+DCCAX6gAwIBAgITNVkDZoCiofPDsy7dfm6geLbuhzAKBggqhkjOPQQDAzAqMRUwEwYDVQQKEwxzaWdzdG9yZS5kZXYxETAPBgNVBAMTCHNpZ3N0b3JlMB4XDTIxMDMwNzAzMjAyOVoXDTMxMDIyMzAzMjAyOVowKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTB2MBAGByqGSM49AgEGBSuBBAAiA2IABLSyA7Ii5k+pNO8ZEWY0ylemWDowOkNa3kL+GZE5Z5GWehL9/A9bRNA3RbrsZ5i0JcastaRL7Sp5fp/jD5dxqc/UdTVnlvS16an+2Yfswe/QuLolRUCrcOE2+2iA5+tzd6NmMGQwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEwHQYDVR0OBBYEFMjFHQBBmiQpMlEk6w2uSu1KBtPsMB8GA1UdIwQYMBaAFMjFHQBBmiQpMlEk6w2uSu1KBtPsMAoGCCqGSM49BAMDA2gAMGUCMH8liWJfMui6vXXBhjDgY4MwslmN/TJxVe/83WrFomwmNf056y1X48F9c4m3a3ozXAIxAKjRay5/aj/jsKKGIkmQatjI8uupHr/+CxFvaJWmpYqNkLDGRU+9orzh5hI2RrcuaQ=="]},{uri:"https://fulcio.sigstore.dev",validFor:{start:"2022-04-13T20:06:15Z"},certChain:["MIICGjCCAaGgAwIBAgIUALnViVfnU0brJasmRkHrn/UnfaQwCgYIKoZIzj0EAwMwKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTAeFw0yMjA0MTMyMDA2MTVaFw0zMTEwMDUxMzU2NThaMDcxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjEeMBwGA1UEAxMVc2lnc3RvcmUtaW50ZXJtZWRpYXRlMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE8RVS/ysH+NOvuDZyPIZtilgUF9NlarYpAd9HP1vBBH1U5CV77LSS7s0ZiH4nE7Hv7ptS6LvvR/STk798LVgMzLlJ4HeIfF3tHSaexLcYpSASr1kS0N/RgBJz/9jWCiXno3sweTAOBgNVHQ8BAf8EBAMCAQYwEwYDVR0lBAwwCgYIKwYBBQUHAwMwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQU39Ppz1YkEZb5qNjpKFWixi4YZD8wHwYDVR0jBBgwFoAUWMAeX5FFpWapesyQoZMi0CrFxfowCgYIKoZIzj0EAwMDZwAwZAIwPCsQK4DYiZYDPIaDi5HFKnfxXx6ASSVmERfsynYBiX2X6SJRnZU84/9DZdnFvvxmAjBOt6QpBlc4J/0DxvkTCqpclvziL6BCCPnjdlIB3Pu3BxsPmygUY7Ii2zbdCdliiow=","MIIB9zCCAXygAwIBAgIUALZNAPFdxHPwjeDloDwyYChAO/4wCgYIKoZIzj0EAwMwKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTAeFw0yMTEwMDcxMzU2NTlaFw0zMTEwMDUxMzU2NThaMCoxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjERMA8GA1UEAxMIc2lnc3RvcmUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAT7XeFT4rb3PQGwS4IajtLk3/OlnpgangaBclYpsYBr5i+4ynB07ceb3LP0OIOZdxexX69c5iVuyJRQ+Hz05yi+UF3uBWAlHpiS5sh0+H2GHE7SXrk1EC5m1Tr19L9gg92jYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRYwB5fkUWlZql6zJChkyLQKsXF+jAfBgNVHSMEGDAWgBRYwB5fkUWlZql6zJChkyLQKsXF+jAKBggqhkjOPQQDAwNpADBmAjEAj1nHeXZp+13NWBNa+EDsDP8G1WWg1tCMWP/WHPqpaVo0jhsweNFZgSs0eE7wYI4qAjEA2WB9ot98sIkoF3vZYdd3/VtWB5b9TNMea7Ix/stJ5TfcLLeABLE4BNJOsQ4vnBHJ"]}],Pr=[{baseUrl:"https://rekor.sigstore.dev",logId:"c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d",publicKey:"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE2G2Y+2tabdTV5BcGiBIx0a9fAFwrkBbmLSGtks4L3qX6yYY0zufBnhC8Ur/iy55GhWP/9A/bY2LhC30M9+RYtw==",validFor:{start:"2021-01-12T11:53:27Z"}}];var us="1.2.840.10045.2.1",ds={"1.2.840.10045.3.1.7":"P-256","1.3.132.0.34":"P-384"},ps={"P-256":32,"P-384":48},gs={"1.2.840.10045.4.3.2":"SHA-256","1.2.840.10045.4.3.3":"SHA-384"};function Ir(n,e,t){if(e+2>t)throw new Error("it is truncated");let r=n[e];if((r&31)===31)throw new Error("it uses a tag this parser does not read");let o=n[e+1],i=e+2;if(o&128){let s=o&127;if(s===0||s>4||i+s>t)throw new Error("it has a length this parser does not read");o=0;for(let c=0;c<s;c+=1)o=o*256+n[i+c];i+=s}let a=i+o;if(a>t)throw new Error("it is truncated");return{tag:r,bytes:n,offset:e,start:i,end:a}}function he(n){let e=Ir(n,0,n.length);if(e.end!==n.length)throw new Error("it has trailing bytes");return e}function D(n){let e=[];for(let t=n.start;t<n.end;){let r=Ir(n.bytes,t,n.end);e.push(r),t=r.end}return e}function E(n,e,t){if(!n||n.tag!==e)throw new Error(`${t} is not where it should be`);return n}function V(n){return n.bytes.slice(n.start,n.end)}function lt(n){return n.bytes.slice(n.offset,n.end)}function me(n){let e=V(E(n,6,"An object identifier"));if(e.length===0||e[e.length-1]&128)throw new Error("it has a malformed object identifier");let t=[],r=0;for(let a of e)r=r*128+(a&127),a&128||(t.push(r),r=0);let o=t.shift();return[...o<80?[Math.floor(o/40),o%40]:[2,o-80],...t].join(".")}function ms(n){let e=new TextDecoder().decode(V(n)),t=n.tag===23?/^(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})Z$/.exec(e):null,r=n.tag===24?/^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})Z$/.exec(e):null,o=t??r;if(!o)throw new Error(`it holds the time ${JSON.stringify(e)}, which is not one a certificate may hold`);let i=Number(o[1]);t&&(i+=i<50?2e3:1900);let[a,s,c,u,d]=o.slice(2).map(Number);return Date.UTC(i,a-1,s,c,u,d)}function Zt(n){try{let[e,t,r,...o]=D(E(he(n),48,"The certificate"));if(o.length>0)throw new Error("it has fields after its signature");let i=D(E(e,48,"The signed part")),a=i[0]?.tag===160?1:0,[s,c,u,d,l,p,...b]=i.slice(a);E(s,2,"The serial number");let w=me(D(E(t,48,"The signature algorithm"))[0]);if(me(D(E(c,48,"The signature algorithm"))[0])!==w)throw new Error("it names two different signature algorithms");let T=gs[w];if(!T)throw new Error(`it is signed with ${w}, not ECDSA with SHA-256 or SHA-384`);let[v,R]=D(E(d,48,"The validity")).map(ms);if(R===void 0)throw new Error("its validity is incomplete");let[q,U]=D(E(p,48,"The public key"));E(U,3,"The public key");let[I,N]=D(E(q,48,"The key algorithm"));if(me(I)!==us)throw new Error("its key is not an elliptic-curve key");let W=ds[me(N)];if(!W)throw new Error("its key is on a curve other than P-256 or P-384");let z=new Map,J=b.find(mt=>mt.tag===163);if(J){let[mt]=D(J);for(let ro of D(E(mt,48,"The extensions"))){let ne=D(E(ro,48,"An extension"));if(ne.length===3)E(ne[1],1,"An extension's critical flag");else if(ne.length!==2)throw new Error("it has a malformed extension");let ht=me(ne[0]);if(z.has(ht))throw new Error(`it has extension ${ht} twice`);z.set(ht,V(E(ne[ne.length-1],4,"An extension value")))}}let cn=V(E(r,3,"The signature"));if(cn[0]!==0)throw new Error("its signature is not a whole number of bytes");return{der:n,tbs:lt(e),signatureHash:T,signature:cn.slice(1),issuer:lt(E(u,48,"The issuer")),subject:lt(E(l,48,"The subject")),notBefore:v,notAfter:R,spki:lt(p),curve:W,extensions:z}}catch(e){throw new Error(`The certificate is malformed: ${e.message}`)}}function Dr(n){return D(E(he(n),48,"The list")).map(me)}function hs(n,e){let t=ps[e],r=D(E(he(n),48,"The signature"));if(r.length!==2)throw new Error("The signature is not an ECDSA signature");let o=new Uint8Array(t*2);return r.forEach((i,a)=>{let s=V(E(i,2,"The signature"));if(s.length===0||s[0]&128)throw new Error("The signature is not an ECDSA signature");for(;s.length>1&&s[0]===0;)s=s.subarray(1);if(s.length>t)throw new Error("The signature is not an ECDSA signature");o.set(s,a*t+t-s.length)}),o}async function ut(n,e,t,r,o){let i;try{i=hs(r,e)}catch{return!1}let a=await crypto.subtle.importKey("spki",n,{name:"ECDSA",namedCurve:e},!1,["verify"]);return crypto.subtle.verify({name:"ECDSA",hash:t},a,i,o)}function G(n,e){let t=n.replace(/\s+/g,"");if(!/^[A-Za-z0-9+/]*={0,2}$/.test(t)||t.length%4!==0)throw new Error(`${e} is not base64`);let r=atob(t),o=new Uint8Array(r.length);for(let i=0;i<r.length;i+=1)o[i]=r.charCodeAt(i);return o}function en(n,e){let t=[...n.matchAll(/-----BEGIN CERTIFICATE-----([^-]*)-----END CERTIFICATE-----/g)];if(t.length!==1||n.replace(t[0][0],"").trim()!=="")throw new Error(`${e} is not exactly one PEM certificate`);return G(t[0][1],e)}var fs="2.5.29.17",ys="2.5.29.37",bs="1.3.6.1.5.5.7.3.3",ws="1.3.6.1.4.1.57264.1.8",As="1.3.6.1.4.1.57264.1.1",xs=134,Rs=12,vs=48,Cs=new TextEncoder,fe=n=>new TextDecoder().decode(n);async function Ur(n,e,t,r){let{base64Signature:o,cert:i,rekorBundle:a}=Ts(e),s=a.Payload;if(r!==void 0&&r.trim()!==o.trim())throw new Error("The detached signature is not the one in the bundle");let c=G(o,"The bundle signature"),u=en(fe(G(i,"The bundle certificate")),"The bundle certificate"),d=Zt(u),l=Pr.find(R=>R.logId===s.logID.toLowerCase());if(!l)throw new Error(`The bundle names Rekor log ${s.logID}, which the Sigstore trust root does not know`);let p=Cs.encode(`{"body":${JSON.stringify(s.body)},"integratedTime":${s.integratedTime},"logID":${JSON.stringify(s.logID)},"logIndex":${s.logIndex}}`);if(!await ut(G(l.publicKey,"The Rekor key"),"P-256","SHA-256",G(a.SignedEntryTimestamp,"The signed entry timestamp"),p))throw new Error("Rekor's signed entry timestamp does not verify: the log entry, its time or its index was altered");let w=s.integratedTime*1e3;if(!_r(w,l.validFor))throw new Error(`Rekor log ${l.baseUrl} was not in use at ${Ie(w)}, when the entry says it was logged`);let y=Ps(s.body),T=h(new Uint8Array(await crypto.subtle.digest("SHA-256",n)));if(y.hash!==T)throw new Error("The file's SHA-256 is not the one Rekor logged: the file is not the one signed");if(!tn(G(y.signature,"The logged signature"),c))throw new Error("The bundle's signature is not the one Rekor logged");let v=en(fe(G(y.publicKey,"The logged certificate")),"The logged certificate");if(!tn(v,u))throw new Error("The bundle's certificate is not the one Rekor logged");if(d.curve!=="P-256"||!await ut(d.spki,"P-256","SHA-256",c,n))throw new Error("The signature over the file does not verify with the bundle's certificate");return await ks(d,w),Es(d,t),{integratedTime:s.integratedTime}}async function ks(n,e){if(!Mr(n,e))throw new Error(`The signing certificate was valid ${Ie(n.notBefore)} to ${Ie(n.notAfter)}, not at ${Ie(e)} when Rekor logged it`);let t=[];for(let r of Tr){let o=r.certChain.map(a=>Zt(G(a,"A Fulcio certificate")));if(!await Nr(n,o[0]))continue;let i=await Ss(o,r.validFor,e);if(!i)return;t.push(`${r.uri} (valid from ${r.validFor.start}): ${i}`)}throw new Error(t.length>0?`The signing certificate's CA is not trusted at ${Ie(e)}: ${t.join("; ")}`:"The signing certificate was not issued by a Fulcio CA in the Sigstore trust root")}async function Ss(n,e,t){if(!_r(t,e))return"the trust root says it was not issuing certificates then";for(let[r,o]of n.entries()){if(!Mr(o,t))return`its certificate ${r} was not valid then`;let i=n[r+1]??o;if(!await Nr(o,i))return`its certificate ${r} is not signed by the next`}}async function Nr(n,e){return tn(n.issuer,e.subject)?ut(e.spki,e.curve,n.signatureHash,n.signature,n.tbs):!1}function Es(n,e){let t=n.extensions.get(fs);if(!t)throw new Error("The signing certificate names no identity");let r=D(E(he(t),vs,"The subject alternative name")),o=r.filter(u=>u.tag===xs).map(u=>fe(V(u)));if(o.length!==1||r.length!==1||o[0]!==e.identity)throw new Error(`The release was signed by ${JSON.stringify(o.length===1?o[0]:o)}, not by ${e.identity}`);let i=n.extensions.get(ws),a=n.extensions.get(As),s=i?fe(V(E(he(i),Rs,"The OIDC issuer"))):a?fe(a):void 0;if(s!==e.issuer)throw new Error(`The signing certificate's OIDC issuer is ${s===void 0?"missing":JSON.stringify(s)}, not ${e.issuer}`);let c=n.extensions.get(ys);if(!c||!Dr(c).includes(bs))throw new Error("The signing certificate is not for code signing")}function Ts(n){let e=n;if(typeof e=="string")try{e=JSON.parse(e)}catch{throw new Error("The bundle is not JSON")}let t=e,r=t?.rekorBundle?.Payload;if(!(typeof t?.base64Signature=="string"&&typeof t.cert=="string"&&typeof t.rekorBundle?.SignedEntryTimestamp=="string"&&typeof r?.body=="string"&&typeof r.logID=="string"&&/^[0-9a-fA-F]{64}$/.test(r.logID)&&Number.isSafeInteger(r.integratedTime)&&r.integratedTime>=0&&Number.isSafeInteger(r.logIndex)&&r.logIndex>=0))throw new Error("The bundle is not a cosign bundle with a Rekor entry");return t}function Ps(n){let e;try{e=JSON.parse(fe(G(n,"The logged entry")))}catch{throw new Error("The logged entry is not JSON")}let t=e?.spec?.data?.hash,r=e?.spec?.signature;if(e?.kind!=="hashedrekord"||t?.algorithm!=="sha256"||typeof t.value!="string"||typeof r?.content!="string"||typeof r.publicKey?.content!="string")throw new Error("The logged entry is not a SHA-256 hashedrekord");return{hash:t.value.toLowerCase(),signature:r.content,publicKey:r.publicKey.content}}function Mr(n,e){return n.notBefore<=e&&e<=n.notAfter}function _r(n,e){return Date.parse(e.start)<=n&&(e.end===void 0||n<=Date.parse(e.end))}function Ie(n){return new Date(n).toISOString()}function tn(n,e){return n.length===e.length&&n.every((t,r)=>t===e[r])}var nn=Object.freeze({identity:"https://github.com/calimero-network/mero-tee/.github/workflows/release-node-image-gcp.yaml@refs/heads/master",issuer:"https://token.actions.githubusercontent.com"}),Is=["mrtd","rtmr0","rtmr1","rtmr2","rtmr3"],Gr="https://cloud.calimero.network";async function Hr(n,e,t={}){let r=typeof n=="string"?new TextEncoder().encode(n):n;await Ur(r,e,{identity:t.identity??nn.identity,issuer:t.issuer??nn.issuer},t.signature);let o;try{o=JSON.parse(new TextDecoder().decode(r))}catch{throw new Error("The signed release is not JSON")}if(o?.role!=="node")throw new Error(`The signed release is a ${JSON.stringify(o?.role)} release, not a node one`);let i=Object.values(o.profiles??{}),a=s=>Is.every(c=>/^[0-9a-f]{96}$/i.test(String(s?.[c])));if(typeof o.tag!="string"||i.length===0||!i.every(a))throw new Error("The signed file is not a release's published-mrtds.json: it lists no measured profiles");if(t.expectedVersion!==void 0&&o.tag!==t.expectedVersion)throw new Error(`The signed release is ${o.tag}, not ${t.expectedVersion}`);return o}async function $r(n,e={}){let t=await(e.fetch??fetch)(n,{headers:{accept:"application/json"}});if(!t.ok)throw new Error(`Fetching the node release from ${n} failed: HTTP ${t.status}`);let r;try{r=(await t.json())?.data}catch{throw new Error(`${n} did not answer with JSON`)}if(typeof r?.version!="string"||typeof r.publishedMrtds!="string"||typeof r.bundle!="string")throw new Error(`${n} did not answer with a signed node release`);return{version:r.version,publishedMrtds:r.publishedMrtds,bundle:r.bundle}}function qr(n){let e=/^merotee-.+-(\d+)-(\d+)-(\d+)$/.exec(n);if(!e)throw new Error(`${JSON.stringify(n)} is not the image of a mero-tee node release`);return`${Number(e[1])}.${Number(e[2])}.${Number(e[3])}`}async function Lr(n,e={}){let t=await Br(n,e.fetch??fetch);if(t===void 0)throw new Error(`${Kr(n)} was refused unsealed: the node requires sealing and is too old to name its release before a session exists. Name the release it runs yourself (createSignedReleaseSealedFetch's \`releaseVersion\`), or upgrade the node`);return t}function Kr(n){return`${n.replace(/\/+$/,"")}/admin-api/tee/info`}async function Br(n,e){let t=Kr(n),r=await e(t,{headers:{accept:"application/json"}});if(r.status===403&&await r.json().then(a=>a?.error?.code).catch(()=>{})==="sealed_required")return;if(!r.ok)throw new Error(`Fetching ${t} failed: HTTP ${r.status}`);let o;try{o=(await r.json())?.data?.osImage}catch{throw new Error(`${t} did not answer with JSON`)}if(typeof o!="string")throw new Error(`${t} did not name the node's image`);return qr(o)}function jr(n,e){return`${n.replace(/\/+$/,"")}/api/tee/node-releases/${De(e,"version")}`}async function Fr(n){let e=De(n.minReleaseVersion,"minReleaseVersion"),t=De(n.release?.version,"The release version"),r=await Hr(n.release.publishedMrtds,n.release.bundle,{expectedVersion:t,identity:n.identity,issuer:n.issuer});if(Us(t,e)<0)throw new Error(`Release ${t} is older than the minimum trusted, ${e}`);return Xt([r],{profile:n.profile})}function Vr(n){return De(n.minReleaseVersion,"minReleaseVersion"),Object.assign(async t=>{let r=await Fr({release:await n.release(),profile:n.profile,minReleaseVersion:n.minReleaseVersion,identity:n.identity,issuer:n.issuer});return Yt({dcapVerify:n.dcapVerify,fetchCollateral:n.fetchCollateral,now:n.now,...r})(t)},{includeCollateral:!0})}function Ds(n){let{baseUrl:e,releaseSource:t,releaseVersion:r,applicationId:o,applicationHash:i,fetch:a,...s}=n;r!==void 0&&De(r,"releaseVersion");let c=a??((d,l)=>fetch(d,l));return Pe({baseUrl:e,verify:Vr({...s,release:async()=>{let d=r===void 0?await Lr(e,{fetch:c}):await Br(e,c)??r;return typeof t=="function"?t({baseUrl:e,version:d,fetch:c}):$r(jr(t??Gr,d),{fetch:c})}}),applicationId:o,applicationHash:i,fetch:c})}var Wr=/^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/;function De(n,e){let t=typeof n=="string"?Wr.exec(n):null,r=t?.[4];if(!t||r!==void 0&&r.split(".").some(o=>o===""))throw new Error(`${e} is ${JSON.stringify(n)}, not a release version like 2.3.87`);return n}function Us(n,e){let[t,r]=Or(n),[o,i]=Or(e);for(let c=0;c<3;c+=1)if(t[c]!==o[c])return t[c]<o[c]?-1:1;if(r===void 0||i===void 0)return r===i?0:r===void 0?1:-1;let a=r.split("."),s=i.split(".");for(let c=0;c<Math.max(a.length,s.length);c+=1){let[u,d]=[a[c],s[c]];if(u===void 0||d===void 0)return u===void 0?-1:1;let[l,p]=[/^\d+$/.test(u),/^\d+$/.test(d)],b=l&&p?Math.sign(Number(u)-Number(d)):l!==p?l?-1:1:u<d?-1:u>d?1:0;if(b!==0)return b}return 0}function Or(n){let e=Wr.exec(n);return[[Number(e[1]),Number(e[2]),Number(e[3])],e[4]]}var on=16,Ns=new TextEncoder().encode("calimero.namespace.v1"),Ms=0,zr={GroupCreated:0,GroupReparented:1,GroupDeleted:2,AdminChanged:3,PolicyUpdated:4,MemberJoined:5,KeyDelivery:6,MemberJoinedOpen:7,MemberJoinedAt:8,NamespaceCreatedV2:9,MemberJoinedViaTeeAttestation:10};function rn(n,e){if(n.length!==32)throw new Error(`${e} must be 32 bytes, got ${n.length}`);return new Uint8Array(n)}function Jr(n,e){if(n==null)return new Uint8Array([0]);if(n.length!==32)throw new Error(`${e} must be 32 bytes, got ${n.length}`);return f(new Uint8Array([1]),new Uint8Array(n))}function Qr(n){let e=new TextEncoder().encode(n);return f(x(e.length),e)}function dt(n){let e=n.invitation,t=e.admitters??[],r=n.admitter_addrs??[];return f(rn(e.inviter_identity,"inviter_identity"),rn(e.group_id,"group_id"),A(e.expiration_timestamp),rn(e.secret_salt,"secret_salt"),new Uint8Array([e.invited_role]),x(t.length),...t.map((o,i)=>g(o,`admitters[${i}]`,32)),Qr(n.inviter_signature),n.inviter_account?f(new Uint8Array([1]),g(n.inviter_account,"inviter_account",32)):new Uint8Array([0]),x(r.length),...r.map(Qr),Jr(n.application_id,"application_id"),Jr(n.app_key,"app_key"))}async function Yr(n){let e=n.parentOpHashes??[],t=g(n.credential,"credential",n.credential.length/2),r=BigInt(n.invitation.invitation.expiration_timestamp??0)!==0n,o=n.joinedAt??BigInt(Math.floor(Date.now()/1e3)),i=r?f(new Uint8Array([zr.MemberJoinedAt]),g(n.member,"member",32),dt(n.invitation),A(o),t):f(new Uint8Array([zr.MemberJoined]),g(n.member,"member",32),dt(n.invitation),t),a=f(new Uint8Array([Ms]),i),s=await S(n.deviceSecret,n.signer,"deviceSecret"),c=g(s.publicKey,"signer.publicKey",32),u=f(new Uint8Array([on]),g(n.namespaceId,"namespaceId",32),x(e.length),...e.map((p,b)=>g(p,`parentOpHashes[${b}]`,32)),c,A(n.nonce),a),d=await s.sign(f(Ns,u)),l=new Uint8Array([0]);return h(f(u,d,l))}var Xr=[2428,2429,2528,2529],_s="localhost",Os=2e3;function Zr(n){return`http://${_s}:${n}`}function eo(n,e){let t=n.endsWith("/")?n:`${n}/`;return new URL(e,t).toString()}async function to(n,e={}){let{timeoutMs:t=Os,signal:r}=e;if(r?.aborted)return!1;let o=new AbortController,i=()=>o.abort(),a=r;a&&a.addEventListener("abort",i,{once:!0});let s=setTimeout(()=>o.abort(),t);try{let c=eo(n,"admin-api/health"),u=await fetch(c,{method:"GET",signal:o.signal});if(!u.ok)return!1;try{let d=await u.json(),l=d?.data?.status!==void 0?d?.data?.status:d?.status;return l===void 0?!0:typeof l=="string"&&l.toLowerCase()==="alive"}catch{return!0}}catch{return!1}finally{clearTimeout(s),a&&a.removeEventListener("abort",i)}}async function Gs(n={}){let{ports:e=Xr,timeoutMs:t,signal:r}=n;return(await Promise.all(e.map(async i=>{let a=Zr(i);return await to(a,{timeoutMs:t,signal:r})?a:null}))).filter(i=>i!==null)}var Hs=new TextEncoder().encode("calimero.tee-attest.key-binding.v1"),pt=new TextEncoder().encode("MOCK_TDX_QUOTE_V1"),$s=568;function qs(...n){let e=new Uint8Array(n.reduce((r,o)=>r+o.length,0)),t=0;for(let r of n)e.set(r,t),t+=r.length;return e}function sn(n,e){if(n.length!==e.length)return!1;let t=0;for(let r=0;r<n.length;r+=1)t|=n[r]^e[r];return t===0}function Ls(n){let e=atob(n),t=new Uint8Array(e.length);for(let r=0;r<e.length;r+=1)t[r]=e.charCodeAt(r);return t}function Ks(n,e){if(typeof n!="string"||!/^[0-9a-fA-F]{64}$/.test(n))throw new Error(`${e} must be 64 hex characters`);let t=new Uint8Array(32);for(let r=0;r<32;r+=1)t[r]=Number.parseInt(n.slice(r*2,r*2+2),16);return t}async function gt(n){let e=await crypto.subtle.digest("SHA-256",qs(Hs,new Uint8Array(32),n));return new Uint8Array(e)}function an(n){let e=n.length>=pt.length&&sn(n.subarray(0,pt.length),pt),t=e?pt.length:$s;if(n.length<t+64)throw new Error(`the quote is too short to carry report data (${n.length} bytes)`);return{reportData:n.slice(t,t+64),mock:e}}async function no(n){let e=crypto.getRandomValues(new Uint8Array(32)),t=`${n.relayUrl.replace(/\/+$/,"")}/admin-api/tee/attest`,r=JSON.stringify({nonce:h(e),bindNodeKey:!0,...n.verify?.includeCollateral?{includeCollateral:!0}:{}}),o={method:"POST",headers:{"Content-Type":"application/json"},body:r},i=n.fetch?await n.fetch(t,o):await globalThis.fetch(t,o);if(!i.ok){let p=await i.text().catch(()=>"");throw new Error(`the relay would not attest (HTTP ${i.status})${p?`: ${p}`:""}`)}let a=await i.json(),s=a.data??a;if(typeof s.quoteB64!="string")throw new Error("the relay returned no quote");let c=Ks(s.boundPublicKey,"boundPublicKey"),u=Ls(s.quoteB64),{reportData:d,mock:l}=an(u);if(l){if(!n.allowMock)throw new Error("the relay answered with a MOCK quote, which proves nothing about the hardware")}else if(n.verify){if(!await n.verify({quoteB64:s.quoteB64,nonce:h(e),reportDataSuffix:h(await gt(c)),...s.collateral?{collateral:s.collateral}:{}}))throw new Error("the relay's quote did not verify: not a trusted image, or not bound to this request")}else if(n.verifyQuote)await n.verifyQuote(u);else throw new Error("a real TDX quote needs a verify (or verifyQuote) to check its signature and measurements");if(!sn(d.subarray(0,32),e))throw new Error("the quote does not carry our nonce: it was not made for this request");if(!sn(d.subarray(32,64),await gt(c)))throw new Error("the quote does not bind the key the relay named: refusing it");return{nodeKey:h(c),mock:l}}export{Y as AdminApiClient,Q as AuthApiClient,L as AuthRevokedError,P as CAPABILITIES,ca as CAPABILITY_PRESETS,_ as CloudClient,Xr as DEFAULT_LOCAL_NODE_PORTS,Gr as DEFAULT_RELEASE_MIRROR,xe as EphemeralClient,gr as HANDSHAKE_PATH,C as HTTPError,X as IntentRefusedError,Ot as LocalStorageTokenStore,_t as MemoryTokenStore,ee as MeroClient,ue as MeroJs,nn as NODE_RELEASE_SIGNER,Kt as REQUEST_PROOF_HEADER,F as RelayClient,de as RelayObserver,Z as RelayTransport,Ae as RpcClient,$e as RpcError,Ee as SEALED_CONTENT_TYPE,mr as SEALED_PATH,on as SIGNED_NAMESPACE_OP_SCHEMA_VERSION,pe as SealedTransportError,M as SseClient,Te as StaleTransportKeyError,at as WarrantNonceExhaustedError,Me as WarrantNonceRouteUnavailableError,ye as WebHttpClient,K as WsClient,Fe as accountForRoot,B as accountForRootPublicKey,Pn as accountRootFromPhrase,It as accountRootFromSecret,Dn as accountRootSignerFromPhrase,Go as admitterAddrsFromNetworkStatus,gt as attestKeyBinding,no as attestRelayNodeKey,yi as authorNonceLookup,Vi as beginCloudLink,Zi as beginDeviceEnrolment,Ct as buildAuthLoginUrl,Er as callbackIsForeign,Ge as callerProof,la as capMask,ua as capNames,xt as classifyError,vr as cloudLinkUrl,jr as cloudNodeReleaseUrl,ft as combineSignals,yo as compareSemver,zi as completeCloudLink,ts as completeDeviceEnrolment,xr as connectCloud,Li as connectCloudWithAccount,In as createAccountRootSigner,hn as createAdminApiClient,_e as createAdminApiClientFromHttpClient,Pe as createAttestedSealedFetch,sa as createAuthApiClient,un as createAuthApiClientFromHttpClient,Ea as createBrowserAdminApiClient,oa as createBrowserAuthApiClient,re as createBrowserHttpClient,be as createHttpClient,Vt as createLocalStorageNonceSource,ct as createMemoryNonceSource,ir as createMeroClient,Lo as createMeroJs,Ta as createNodeAdminApiClient,ia as createNodeAuthApiClient,Ue as createNodeHttpClient,jt as createProofAuthorizer,He as createProofSigner,Yt as createQuoteVerifier,bi as createRecoveringNonceSource,lo as createRetryableMethod,br as createSealedFetch,Ds as createSignedReleaseSealedFetch,Vr as createSignedReleaseVerifier,yt as createTimeoutSignal,bt as createUniversalHttpClient,Ht as creationInitHash,st as defaultAudience,et as defaultCapabilitiesSetOp,Be as deviceCertPayload,Sr as deviceEnrolmentUrl,Gs as discoverLocalNodes,dt as encodeSignedInvitation,yr as fetchAttestedTransportKey,$r as fetchNodeRelease,Lr as fetchNodeReleaseVersion,tt as foundedNamespaceId,Tn as generateAccountRoot,Lt as generateSessionKey,$t as governanceOpHash,Zn as groupCreatedOp,tr as groupDeletedOp,er as groupReparentedOp,oe as hasCap,Ra as hexEncodeUtf8,Gt as intentHash,mo as isSettled,Le as jsonCodec,Zr as localNodeUrl,it as login,Jn as memberAddedOp,Yn as memberLeftOp,Qn as memberRemovedOp,Xn as memberRoleSetOp,Cn as mintDeviceId,nt as namespaceCreatedOp,eo as nodeEndpoint,qr as nodeReleaseVersionFromImage,vt as parseAuthCallback,Fn as parseCreationWarrant,Et as parseDeviceCredential,Vn as parseGovernanceWarrant,pn as parseWarrantNonce,to as probeNodeHealth,Wi as readCloudLinkCallback,es as readEnrolmentCallback,dn as redeemInvitation,an as reportDataOf,kt as requestBodyHash,H as resolveRoot,Ve as resolveRootPair,ze as routingProofHeaders,ha as shouldRetain,Re as signAccountLink,We as signAccountLogin,Ye as signCreationWarrant,Sn as signDeviceCert,Ce as signGovernanceWarrant,ot as signLoginStatement,Yr as signMemberJoinOp,Oe as signRequest,Bt as signRequestProof,Ln as signRoutingChallenge,Je as signWarrant,hi as signedPath,Rn as signerFromCryptoKey,ce as signerFromSecret,fr as transportKeyBinding,Fr as trustSignedRelease,Xt as trustedMeasurementsFromReleases,je as verifyDeviceCredential,Hr as verifySignedNodeRelease,wt as withCap,Ne as withRetry,da as withoutCap};
1
+ function bt(t){let e=t.filter(Boolean);if(e.length===0)return;let n=AbortSignal;if(typeof n.any=="function")try{return n.any(e)}catch{}let r=new AbortController,o=i=>{r.abort(i.target.reason);for(let a of e)a.removeEventListener("abort",o)};for(let i of e){if(i.aborted)return AbortSignal.abort(i.reason);i.addEventListener("abort",o,{once:!0})}return r.signal}function wt(t){if(typeof AbortSignal.timeout=="function")return AbortSignal.timeout(t);let e=new AbortController;return setTimeout(()=>{e.abort(new DOMException("Timeout","TimeoutError"))},t),e.signal}var go=new Set(["token_reuse","token_revoked"]);function mo(t){if(t)try{let e=JSON.parse(t),n=e?.error;if(typeof n=="string"&&n.trim()!=="")return n;let r=n?.message;if(typeof r=="string"&&r.trim()!=="")return r;let o=e?.detail;if(typeof o=="string"&&o.trim()!=="")return o}catch{}}var k=class extends Error{constructor(n,r,o,i,a){let s=mo(a)??(n===0&&a?.trim()?a.trim():void 0);super(s?`HTTP ${n} ${r}: ${s}`:`HTTP ${n} ${r}`);this.status=n;this.statusText=r;this.url=o;this.headers=i;this.bodyText=a;this.name="HTTPError";this.explanation=s}toJSON(){return{status:this.status,statusText:this.statusText,url:this.url,headers:hn(this.headers),bodyText:this.bodyText}}},K=class extends k{constructor(n,r,o,i,a,s){super(r,o,i,a,s);this.reason=n;this.name="AuthRevokedError";this.message=`Authentication revoked (${n}): HTTP ${r} ${o}`}};function hn(t){let e={};return t.forEach((n,r)=>{e[r]=n}),e}function ho(t){try{return new URL(t).pathname}catch{let e=t.indexOf("?");return e===-1?t:t.slice(0,e)}}var be=class{constructor(e){this.transport=e;this.refreshTokenPromise=null;this.onTokenRefreshPromise=null}async get(e,n){return this.request(e,{...n,method:"GET"})}async post(e,n,r){return this.request(e,{...r,method:"POST",body:n?JSON.stringify(n):void 0,headers:{"Content-Type":"application/json",...r?.headers}})}async put(e,n,r){return this.request(e,{...r,method:"PUT",body:n?JSON.stringify(n):void 0,headers:{"Content-Type":"application/json",...r?.headers}})}async delete(e,n){return this.request(e,{...n,method:"DELETE"})}async patch(e,n,r){return this.request(e,{...r,method:"PATCH",body:n?JSON.stringify(n):void 0,headers:{"Content-Type":"application/json",...r?.headers}})}async head(e,n){let r=await this.makeRequest(e,{...n,method:"HEAD",parse:"response"});return{headers:hn(r.headers),status:r.status}}async request(e,n){return this.makeRequest(e,n)}async makeRequest(e,n,r=0,o){let a=this.buildUrl(e),s=o??Date.now(),c=this.createAbortSignal(n),u=await this.buildHeaders(n?.headers),d;u instanceof Headers?(d={},u.forEach((b,I)=>{d[I]=b})):d=u;let l=n?.method||"GET";if(this.transport.authorizeRequest){let b=n?.body;if(b!==void 0&&typeof b!="string"&&!(b instanceof Uint8Array))throw new Error("this transport authorizes each request against its body, so the body must be a string or Uint8Array \u2014 a stream cannot be signed, because the signature would have to read bytes the request then cannot send.");Object.assign(d,await this.transport.authorizeRequest({method:l,path:new URL(a).pathname,body:b}))}let g={method:l,headers:d},y=n?.body instanceof ReadableStream||typeof n?.body=="object"&&n?.body!==null&&"getReader"in n.body&&!(n.body instanceof Blob);(n?.body!==void 0&&!y||n?.body!==void 0&&y&&r===0)&&(g.body=n.body);let A;if(r>0&&o!==void 0){let b=n?.timeoutMs||this.transport.timeoutMs;if(b){let I=Date.now()-s,S=Math.max(0,b-I);A=this.createAbortSignal({...n,timeoutMs:S})}else A=this.createAbortSignal(n)}else A=c;if(A&&(g.signal=A),this.transport.credentials!==void 0&&(g.credentials=this.transport.credentials),n?.mode!==void 0&&(g.mode=n.mode),n?.cache!==void 0&&(g.cache=n.cache),n?.redirect!==void 0&&(g.redirect=n.redirect),n?.referrer!==void 0&&(g.referrer=n.referrer),n?.referrerPolicy!==void 0&&(g.referrerPolicy=n.referrerPolicy),n?.integrity!==void 0&&(g.integrity=n.integrity),n?.keepalive!==void 0&&(g.keepalive=n.keepalive),this.transport.getProof){let b=await this.transport.getProof({method:g.method??"GET",path:ho(a),body:g.body});b&&(d["X-Calimero-Proof"]=b)}try{let b=await this.transport.fetch(a,g);if(!b.ok){let I=await this.getBodyText(b),S=new k(b.status,b.statusText,a,b.headers,I),C=b.headers.get("x-auth-error");if((b.status===401||b.status===403)&&C&&go.has(C)){if(this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,this.transport.onAuthRevoked)try{await this.transport.onAuthRevoked()}catch{}throw new K(C,b.status,b.statusText,a,b.headers,I)}let q=n?.signal?.aborted===!0;if(b.status===401&&this.transport.refreshToken&&C==="token_expired"&&r<1&&!y&&!q)try{let U=this.refreshTokenPromise;U||(U=this.transport.refreshToken(),this.refreshTokenPromise=U);let P=await U;if(!P||P.trim()==="")throw this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,new Error("Refresh token returned empty token");if(!this.transport.onTokenRefresh)throw this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,new Error("onTokenRefresh callback is required when refreshToken is provided. The callback must update the token storage so getAuthToken() returns the new token.");let N=this.onTokenRefreshPromise;N||(N=this.transport.onTokenRefresh(P),this.onTokenRefreshPromise=N),await N,this.refreshTokenPromise=null,this.onTokenRefreshPromise=null;let W=n?.timeoutMs||this.transport.timeoutMs;if(W&&o!==void 0){let z=Date.now()-s;if(W-z<=0)throw S}return this.makeRequest(e,n,r+1,s)}catch(U){throw this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,U instanceof Error&&U.message.includes("onTokenRefresh")?U:S}throw S}return this.parseResponse(b,n?.parse)}catch(b){throw b instanceof k||b instanceof Error&&b.message.includes("onTokenRefresh")?b:new k(0,"Network Error",a,new Headers,b instanceof Error?b.message:"Unknown error")}}buildUrl(e){if(e.startsWith("http://")||e.startsWith("https://"))return e;let n=this.transport.baseUrl;return e.startsWith("/")?`${n.endsWith("/")?n.slice(0,-1):n}${e}`:`${n.endsWith("/")?n:`${n}/`}${e}`}createAbortSignal(e){let n=[];this.transport.defaultAbortSignal&&n.push(this.transport.defaultAbortSignal),e?.signal&&n.push(e.signal);let r=e?.timeoutMs||this.transport.timeoutMs;return r&&n.push(wt(r)),n.length>0?bt(n):void 0}async buildHeaders(e){let n={...this.transport.defaultHeaders};if(this.transport.getAuthToken)try{let r=await this.transport.getAuthToken();r&&r.trim()!==""&&(n.Authorization=`Bearer ${r}`)}catch{}return e&&(e instanceof Headers?e.forEach((r,o)=>{n[o]=r}):Array.isArray(e)?e.forEach(([r,o])=>{n[r]=o}):Object.assign(n,e)),n}async parseResponse(e,n){switch(n){case"text":return await e.text();case"blob":return await e.blob();case"arrayBuffer":return await e.arrayBuffer();case"response":return e;default:{let r=await e.text();if(!r)return null;try{return JSON.parse(r)}catch{throw new Error(`Expected a JSON response (status ${e.status}) but body was not JSON: ${r.slice(0,200)}`)}}}}async getBodyText(e){try{let n=await e.text();return n.length>65536?n.slice(0,65536)+"...":n}catch{return""}}};function we(t){return new be(t)}function re(t){let e={fetch:(n,r)=>t.fetch?t.fetch(n,r):globalThis.fetch(n,r),baseUrl:t.baseUrl,getAuthToken:t.getAuthToken,getProof:t.getProof,onTokenRefresh:t.onTokenRefresh,refreshToken:t.refreshToken,onAuthRevoked:t.onAuthRevoked,defaultHeaders:t.defaultHeaders,timeoutMs:t.timeoutMs,credentials:t.credentials,defaultAbortSignal:t.defaultAbortSignal};return we(e)}function Me(t){let e=t.fetch??globalThis.fetch;if(!e)throw new Error("No fetch implementation available. Please provide a fetch implementation (e.g., undici.fetch) or use Node.js 18+ which has native fetch support.");let r={fetch:e===globalThis.fetch?(o,i)=>globalThis.fetch(o,i):(o,i)=>e(o,i),baseUrl:t.baseUrl,getAuthToken:t.getAuthToken,getProof:t.getProof,onTokenRefresh:t.onTokenRefresh,refreshToken:t.refreshToken,onAuthRevoked:t.onAuthRevoked,defaultHeaders:t.defaultHeaders,timeoutMs:t.timeoutMs,credentials:t.credentials,defaultAbortSignal:t.defaultAbortSignal};return we(r)}function At(t){return typeof window<"u"?re(t):Me(t)}function fo(t,e){if(e<=0)return!1;let r=t?.name;if(r==="TimeoutError")return!0;if(r==="AbortError")return!1;let o=t;if("status"in o&&typeof o.status=="number"){let i=o.status;return i>=500||i===429}return r==="TypeError"}function yo(t){let n=250*Math.pow(2,t-1),r=(Math.random()-.5)*.4*n;return Math.max(0,n+r)}async function _e(t,e={}){let{attempts:n=3}=e,r;for(let o=1;o<=n;o++)try{return await t(o)}catch(i){if(r=i,!fo(r,n-o))throw r;let a=yo(o),u=r.headers?.get?.("Retry-After");if(u){let d=parseInt(u,10);if(!isNaN(d))a=Math.max(a,d*1e3);else{let l=new Date(u);if(!isNaN(l.getTime())){let g=Math.max(0,l.getTime()-Date.now());a=Math.max(a,Math.min(g,6e4))}}}await new Promise(d=>setTimeout(d,a))}throw r||new Error("Retry failed without error")}function bo(t,e={}){return async(...n)=>_e(()=>t(...n),e)}var Q=class{constructor(e){this.httpClient=e}async getHealth(){let e=await this.httpClient.get("/auth/health");if(!e.data)throw new Error("Health response data is null");return e.data}async getIdentity(){let e=await this.httpClient.get("/admin/identity");if(!e.data)throw new Error("Identity response data is null");return e.data}async getProviders(){let e=await this.httpClient.get("/auth/providers");if(!e.data)throw new Error("Providers response data is null");return e.data}async getLoginPage(){return this.httpClient.get("/auth/login",{parse:"text"})}async generateTokens(e){return this.httpClient.post("/auth/token",e)}async refreshToken(e){return this.httpClient.post("/auth/refresh",e)}async generateMockTokens(e){return this.httpClient.post("/auth/mock-token",e)}async validateToken(e){try{let n=await this.validateTokenGet(e);return{valid:n.status===200,headers:n.headers,status:n.status}}catch{return{valid:!1,headers:{},status:401}}}async validateTokenGet(e){let n=await this.httpClient.head("/auth/validate",{headers:{Authorization:`Bearer ${e}`}});return{status:n.status,headers:n.headers}}async revokeTokens(e){let n=await this.httpClient.post("/admin/revoke",e);if(!n.data)throw new Error("Revoke tokens response data is null");return n.data}async listRootKeys(){let e=await this.httpClient.get("/admin/keys");if(!e.data)throw new Error("Root keys response data is null");return e.data}async createRootKey(e){let n=await this.httpClient.post("/admin/keys",e);if(!n.data)throw new Error("Create root key response data is null");return n.data}async deleteRootKey(e){return this.httpClient.delete(`/admin/keys/${e}`)}async listClientKeys(){let e=await this.httpClient.get("/admin/keys/clients");if(!e.data)throw new Error("Client keys response data is null");return e.data}async generateClientKey(e){return this.httpClient.post("/admin/client-key",e)}async deleteClientKey(e,n){return this.httpClient.delete(`/admin/keys/${e}/clients/${n}`)}async getKeyPermissions(e){return this.httpClient.get(`/admin/keys/${e}/permissions`)}async updateKeyPermissions(e,n){return this.httpClient.put(`/admin/keys/${e}/permissions`,{add:n.add,remove:n.remove})}};var Ae=class{async get(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async post(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async put(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async delete(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async patch(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async head(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async request(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}};function ga(t){let e=new Ae;return new Q(e)}function ma(t){let e=new Ae;return new Q(e)}function ha(t){let e=new Ae;return new Q(e)}function fn(t,e){return new Q(t)}var T={CAN_CREATE_CONTEXT:1,CAN_INVITE_MEMBERS:2,CAN_JOIN_OPEN_SUBGROUPS:4,MANAGE_MEMBERS:8,MANAGE_APPLICATION:16,CAN_CREATE_SUBGROUP:32,CAN_DELETE_SUBGROUP:64,CAN_MANAGE_VISIBILITY:128,CAN_MANAGE_METADATA:256,CAN_AUTHOR_ON_BEHALF:512},ya={NONE:0,JOIN_ONLY:T.CAN_JOIN_OPEN_SUBGROUPS,CONTRIBUTOR:T.CAN_CREATE_CONTEXT|T.CAN_INVITE_MEMBERS|T.CAN_JOIN_OPEN_SUBGROUPS,COLLABORATOR:T.CAN_CREATE_CONTEXT|T.CAN_INVITE_MEMBERS|T.CAN_JOIN_OPEN_SUBGROUPS|T.CAN_CREATE_SUBGROUP|T.CAN_DELETE_SUBGROUP|T.CAN_MANAGE_VISIBILITY};function ba(...t){let e=0;for(let n of t)if(typeof n=="number")e|=n;else if(Object.prototype.hasOwnProperty.call(T,n))e|=T[n];else throw new Error(`unknown capability: ${String(n)}`);return e>>>0}function wa(t){return Object.keys(T).filter(e=>oe(t,T[e]))}function oe(t,e){let n=e>>>0;return(t&n)>>>0===n}function xt(t,e){return(t|e)>>>0}function Aa(t,e){return(t&~e)>>>0}var wo={invalid:!1,unauthorized:!0,forbidden:!1,"not-found":!0,conflict:!1,gone:!1,"too-large":!1,"rate-limited":!0,unavailable:!0,server:!0,unreachable:!0,unknown:!0};function Ao(t){switch(t){case 0:return"unreachable";case 400:return"invalid";case 401:return"unauthorized";case 403:return"forbidden";case 404:return"not-found";case 409:return"conflict";case 410:return"gone";case 413:return"too-large";case 429:return"rate-limited";case 503:case 504:return"unavailable"}return t>=500&&t<600?"server":t>=400&&t<500?"invalid":"unknown"}function xo(t){if(!t||typeof t!="object")return;let e=t;for(let n of[e.status,e.response?.status,e.statusCode])if(typeof n=="number"&&Number.isFinite(n))return n}function Rt(t,e="Request failed"){if(typeof t=="string")return t.trim()||e;if(!t||typeof t!="object")return e;let n=t;for(let r of[n.explanation,n.response?.data?.error,n.response?.data?.message,n.data?.message,n.error,n.message])if(typeof r=="string"&&r.trim())return r;return e}function vt(t){let e=xo(t),n;return e!==void 0?n=Ao(e):t instanceof TypeError?n="unreachable":n="unknown",{kind:n,status:e,retryable:wo[n],message:Rt(t)}}function Ro(t){return t.status!=="failed"||!t.retryable}function Ca(t){return!Ro(t)}function vo(t){let e=t.toLowerCase();return e.includes("invitation has expired")||e.includes("invitation expired")||/\binvitation for group .+? expired at \d+/.test(e)?"expired":e.includes("malformed")||e.includes("does not match namespace_id")||e.includes("invalid invitation")||/\binvitation for group .+? is invalid:/.test(e)?"invalid":null}function Co(t,e){let{kind:n,status:r}=vt(t),o=vo(e);return r===401?{reason:"signed-out",retryable:!0}:r===400?{reason:o??"invalid",retryable:!1}:r===410?{reason:"expired",retryable:!1}:r===403?{reason:"refused",retryable:!1}:r===409?{reason:o??"refused",retryable:!1}:n==="unavailable"?{reason:"no-one-online",retryable:!0}:n==="unreachable"?{reason:"node-unreachable",retryable:!0}:o?{reason:o,retryable:!1}:{reason:"unknown",retryable:!0}}async function yn(t,e){let{namespaceId:n,invitation:r,teamName:o}=t,i=null;try{await e.join(n,r)}catch(d){i=d}let a=null;try{a=(await e.memberships()).includes(n)}catch{a=null}if(i===null)return{status:"joined",namespaceId:n,teamName:o};if(a===!0)return{status:"already-member",namespaceId:n,teamName:o};let s=Rt(i,"Could not join. Check the invitation."),{reason:c,retryable:u}=Co(i,s);return{status:"failed",namespaceId:n,message:s,reason:c,retryable:u}}var Oe=class extends Error{constructor(n,r){super(`this node does not serve warrant-nonce discovery (404 on ${n}); it predates the route, so a client must fall back to its own nonce counter`);this.path=n;this.cause=r;this.name="WarrantNonceRouteUnavailableError"}};function Ct(t,e,n){let r=e[n];if(r==null)return;let o=new RegExp(`"${n}"\\s*:\\s*(\\d+)`).exec(t);if(o)return BigInt(o[1]);if(typeof r=="string"&&/^\d+$/.test(r))return BigInt(r);throw new Error(`warrant-nonce response field \`${n}\` is not a u64: ${JSON.stringify(r)}`)}function bn(t){let n=JSON.parse(t)?.data;if(!n||typeof n!="object")throw new Error(`warrant-nonce response had no \`data\`: ${t.slice(0,200)}`);let r={contextId:String(n.contextId??""),authorDeviceKey:String(n.authorDeviceKey??""),seen:n.seen===!0,highWaterNonce:Ct(t,n,"highWaterNonce"),windowWidth:Ct(t,n,"windowWidth")??0n},o=Ct(t,n,"nextNonce");return o===void 0?{...r,kind:"exhausted",seen:!0,highWaterNonce:r.highWaterNonce??0xffffffffffffffffn}:{...r,kind:"open",nextNonce:o}}function h(t){return t?.data}function So(t,e){let[n,r]=wn(t),[o,i]=wn(e),a=n.split("."),s=o.split("."),c=Math.max(a.length,s.length);for(let g=0;g<c;g++){let y=An(a[g]??"0",s[g]??"0");if(y!==0)return y}if(r===void 0&&i===void 0)return 0;if(r===void 0)return 1;if(i===void 0)return-1;let u=r.split("."),d=i.split("."),l=Math.max(u.length,d.length);for(let g=0;g<l;g++){if(g>=u.length)return-1;if(g>=d.length)return 1;let y=An(u[g],d[g]);if(y!==0)return y}return 0}function wn(t){let e=t.split("+",1)[0],n=e.indexOf("-");return n===-1?[e,void 0]:[e.slice(0,n),e.slice(n+1)]}function An(t,e){let n=/^\d+$/.test(t),r=/^\d+$/.test(e);if(n&&r){let o=Number(t)-Number(e);return o<0?-1:o>0?1:0}return n?-1:r?1:t<e?-1:t>e?1:0}async function ko(t,e,n){return _e(async()=>{let r=await fetch(t,{signal:AbortSignal.timeout(1e4)});if(!r.ok){let o=new Error(`registry ${e} fetch failed (${r.status}) for ${n}`);throw o.status=r.status,o}return r},{attempts:3})}var Y=class{constructor(e){this.httpClient=e}async healthCheck(){return h(await this.httpClient.get("/admin-api/health"))}async readinessCheck(){return h(await this.httpClient.get("/admin-api/ready"))}async isAuthed(){return this.httpClient.get("/admin-api/is-authed")}async installApplication(e){return h(await this.httpClient.post("/admin-api/install-application",e))}async getRegistryVersions(e,n){let r=new URL("/api/v2/bundles",new URL(e).origin);r.searchParams.set("package",n);let i=await(await ko(r.toString(),"versions",n)).json();return(Array.isArray(i)?i:[]).map(a=>a.appVersion).filter(a=>typeof a=="string").sort((a,s)=>So(s,a))}async installDevApplication(e){return h(await this.httpClient.post("/admin-api/install-dev-application",e))}async uninstallApplication(e){return h(await this.httpClient.delete(`/admin-api/applications/${e}`))}async listApplications(){return h(await this.httpClient.get("/admin-api/applications"))}async getApplication(e){return h(await this.httpClient.get(`/admin-api/applications/${e}`))}async listApplicationVersions(e){return h(await this.httpClient.get(`/admin-api/applications/${e}/versions`))}async getApplicationAbi(e,n){let r=n?`?service_name=${encodeURIComponent(n)}`:"";return h(await this.httpClient.get(`/admin-api/applications/${e}/abi${r}`))}async listPackages(){let e=await this.httpClient.get("/admin-api/packages");return e?.data??e}async listPackageVersions(e){let n=await this.httpClient.get(`/admin-api/packages/${encodeURIComponent(e)}/versions`);return n?.data??n}async getLatestPackageVersion(e){return this.httpClient.get(`/admin-api/packages/${encodeURIComponent(e)}/latest`)}async createContext(e){let n={...e,initializationParams:e.initializationParams??[]};return h(await this.httpClient.post("/admin-api/contexts",n))}async deleteContext(e){return h(await this.httpClient.delete(`/admin-api/contexts/${e}`))}async getContexts(){return h(await this.httpClient.get("/admin-api/contexts"))}async getContext(e){return h(await this.httpClient.get(`/admin-api/contexts/${e}`))}async getContextsForApplication(e){return h(await this.httpClient.get(`/admin-api/contexts/for-application/${e}`))}async generateContextIdentity(){return h(await this.httpClient.post("/admin-api/identity/context",{}))}async getContextIdentities(e){return h(await this.httpClient.get(`/admin-api/contexts/${e}/identities`))}async getContextIdentitiesOwned(e){return h(await this.httpClient.get(`/admin-api/contexts/${e}/identities-owned`))}async joinContext(e){return h(await this.httpClient.post(`/admin-api/contexts/${e}/join`,{}))}async getContextGroup(e){return h(await this.httpClient.get(`/admin-api/contexts/${e}/group`))}async getContextStorage(e){return h(await this.httpClient.get(`/admin-api/contexts/${e}/storage`))}async syncContext(e){let n=e?`/admin-api/contexts/sync/${e}`:"/admin-api/contexts/sync";await this.httpClient.post(n,{})}async resyncContext(e,n={}){return await this.httpClient.post(`/admin-api/contexts/${e}/resync`,n)??{contextId:e,resyncStarted:!0}}async inviteSpecializedNode(e){return h(await this.httpClient.post("/admin-api/contexts/invite-specialized-node",e))}async updateContextApplication(e,n){await this.httpClient.post(`/admin-api/contexts/${e}/application`,n)}async getContextsWithExecutorsForApplication(e){let n=await this.httpClient.get(`/admin-api/contexts/with-executors/for-application/${e}`);return Array.isArray(n)?n:n?.contexts??n?.data??[]}async uploadBlob(e){let n=new URLSearchParams;e.hash&&n.set("hash",e.hash),e.contextId&&n.set("context_id",e.contextId);let r=n.toString(),o=r?`/admin-api/blobs?${r}`:"/admin-api/blobs",i=h(await this.httpClient.request(o,{method:"PUT",body:e.data,headers:{"Content-Type":"application/octet-stream"}}));return{blobId:i.blob_id,size:i.size}}async deleteBlob(e){let n=await this.httpClient.delete(`/admin-api/blobs/${e}`);return{blobId:n.blob_id,deleted:n.deleted}}async listBlobs(){return{blobs:h(await this.httpClient.get("/admin-api/blobs")).blobs.map(n=>({blobId:n.blob_id,size:n.size}))}}blobPath(e,n){if(!n?.contextId)return`/admin-api/blobs/${e}`;let r=new URLSearchParams({context_id:n.contextId});return`/admin-api/blobs/${e}?${r.toString()}`}async getBlob(e,n){return this.httpClient.get(this.blobPath(e,n),{parse:"arrayBuffer"})}async getBlobInfo(e,n){let{headers:r}=await this.httpClient.head(this.blobPath(e,n)),o=Number(r["content-length"]);return{blobId:r["x-blob-id"]??e,size:Number.isFinite(o)?o:0,hash:r["x-blob-hash"],mimeType:r["x-blob-mime-type"],source:r["x-blob-source"]}}async createContextAlias(e){return h(await this.httpClient.post("/admin-api/alias/create/context",{alias:e.alias,contextId:e.contextId}))}async createApplicationAlias(e){return h(await this.httpClient.post("/admin-api/alias/create/application",{alias:e.alias,applicationId:e.applicationId}))}async lookupContextAlias(e){return h(await this.httpClient.post(`/admin-api/alias/lookup/context/${encodeURIComponent(e)}`,{}))}async lookupApplicationAlias(e){return h(await this.httpClient.post(`/admin-api/alias/lookup/application/${encodeURIComponent(e)}`,{}))}async deleteContextAlias(e){return h(await this.httpClient.post(`/admin-api/alias/delete/context/${encodeURIComponent(e)}`,{}))}async deleteApplicationAlias(e){return h(await this.httpClient.post(`/admin-api/alias/delete/application/${encodeURIComponent(e)}`,{}))}async listContextAliases(){return h(await this.httpClient.get("/admin-api/alias/list/context"))}async listApplicationAliases(){return h(await this.httpClient.get("/admin-api/alias/list/application"))}async createDeviceAlias(e){return h(await this.httpClient.post("/admin-api/alias/create/device",{alias:e.alias,deviceId:e.deviceId}))}async lookupDeviceAlias(e){return h(await this.httpClient.post(`/admin-api/alias/lookup/device/${encodeURIComponent(e)}`,{}))}async deleteDeviceAlias(e){return h(await this.httpClient.post(`/admin-api/alias/delete/device/${encodeURIComponent(e)}`,{}))}async listDeviceAliases(){return h(await this.httpClient.get("/admin-api/alias/list/device"))}async listNamespaces(){return h(await this.httpClient.get("/admin-api/namespaces"))}async getNamespace(e){return h(await this.httpClient.get(`/admin-api/namespaces/${e}`))}async getNodeIdentity(){return h(await this.httpClient.get("/admin-api/identity"))}async getNamespaceIdentity(e){let n=await this.getNodeIdentity();return{namespaceId:e,publicKey:n.publicKey,account:n.accountId}}async performIntent(e,n){return h(await this.httpClient.post(`/admin-api/contexts/${e}/intents`,n))}async queryContext(e,n){return h(await this.httpClient.post(`/admin-api/contexts/${e}/query`,n))}async getIntentRelay(e){return h(await this.httpClient.get(`/admin-api/contexts/${e}/intents`))}async listNamespacesForApplication(e){return h(await this.httpClient.get(`/admin-api/namespaces/for-application/${e}`))}async createNamespace(e){return h(await this.httpClient.post("/admin-api/namespaces",e))}async deleteNamespace(e){return h(await this.httpClient.request(`/admin-api/namespaces/${e}`,{method:"DELETE",body:"{}",headers:{"Content-Type":"application/json"}}))}async createNamespaceInvitation(e,n){return h(await this.httpClient.post(`/admin-api/namespaces/${e}/invite`,n??{}))}async admitJoin(e,n){return h(await this.httpClient.post(`/admin-api/namespaces/${e}/admit`,n,{timeoutMs:65e3}))}async joinNamespace(e,n){let r=h(await this.httpClient.post(`/admin-api/namespaces/${e}/join`,n,{timeoutMs:65e3}));return r&&r.namespaceId===void 0&&r.groupId!==void 0?{...r,namespaceId:r.groupId}:r}async redeemInvitation(e,n,r={}){let{groupName:o,teamName:i}=r;return yn({namespaceId:e,invitation:n,teamName:i},{join:async()=>{await this.joinNamespace(e,o===void 0?{invitation:n}:{invitation:n,groupName:o})},memberships:async()=>(await this.listNamespaces()??[]).map(a=>a.namespaceId)})}async createGroupInNamespace(e,n){return h(await this.httpClient.post(`/admin-api/namespaces/${e}/groups`,n??{}))}async listNamespaceGroups(e){return h(await this.httpClient.get(`/admin-api/namespaces/${e}/groups`))}async initAccountPairing(e){return h(await this.httpClient.post("/admin-api/account/pair-init",e))}async completeAccountPairing(e){return h(await this.httpClient.post("/admin-api/account/pair-complete",e))}async relinkAccountDevice(e,n){return h(await this.httpClient.post(`/admin-api/account/devices/${e}/relink`,n??{}))}async rescopeAccountDevice(e,n){return h(await this.httpClient.put(`/admin-api/account/devices/${encodeURIComponent(e)}/scope`,n))}async signWithAccountRoot(e){return h(await this.httpClient.post("/admin-api/account/sign-with-root",e))}async labelAccountDevice(e,n){return h(await this.httpClient.put(`/admin-api/account/devices/${encodeURIComponent(e)}/label`,n))}async listAccountDevices(){return(await this.httpClient.get("/admin-api/account/devices")).devices}async listAccountApplications(){return(await this.httpClient.get("/admin-api/account/applications")).applications}async revokeAccountDevice(e,n){return h(await this.httpClient.post(`/admin-api/namespaces/${e}/account/revoke`,n))}async linkAccountDevice(e,n){return h(await this.httpClient.post(`/admin-api/namespaces/${e}/account/link-device`,n))}async getGroupInfo(e){return h(await this.httpClient.get(`/admin-api/groups/${e}`))}async getDefaultCapabilities(e){return(await this.getGroupInfo(e)).defaultCapabilities}async getSubgroupVisibility(e){return(await this.getGroupInfo(e)).subgroupVisibility}async deleteGroup(e){return h(await this.httpClient.request(`/admin-api/groups/${e}`,{method:"DELETE",body:"{}",headers:{"Content-Type":"application/json"}}))}async listGroupMembers(e){let n=await this.httpClient.get(`/admin-api/groups/${e}/members`);if(!Array.isArray(n?.members)){let r=String(e).replace(/[\r\n\t\s]/g,"").slice(0,64);throw new Error(`Invalid listGroupMembers response for group ${r}: missing or non-array \`members\` field`)}return n}async listGroupMemberDevices(e,n){let r=new URLSearchParams;n?.offset!==void 0&&r.set("offset",String(n.offset)),n?.limit!==void 0&&r.set("limit",String(n.limit));let o=r.toString(),i=`/admin-api/groups/${encodeURIComponent(e)}/member-devices`;return(await this.httpClient.get(o?`${i}?${o}`:i)).members}async getWarrantNonce(e,n){let r=`/admin-api/contexts/${encodeURIComponent(e)}/warrant-nonce/${encodeURIComponent(n)}`,o;try{o=await this.httpClient.get(r,{parse:"text"})}catch(i){throw i instanceof k&&i.status===404?new Oe(r,i):i}return bn(o)}async getWarrantNonceAsAuthor(e,n){let r=`/admin-api/contexts/${encodeURIComponent(e)}/warrant-nonce`,o;try{o=await this.httpClient.post(r,{authorProof:n},{parse:"text"})}catch(i){throw i instanceof k&&i.status===404?new Oe(r,i):i}return bn(o)}async listMemberDevices(e,n={}){let r=new URLSearchParams;n.offset!==void 0&&r.set("offset",String(n.offset)),n.limit!==void 0&&r.set("limit",String(n.limit));let o=r.toString(),i=`/admin-api/groups/${e}/member-devices${o?`?${o}`:""}`;return this.httpClient.get(i)}async sealToAccount(e,n,r){return h(await this.httpClient.post(`/admin-api/groups/${e}/accounts/${n}/seal`,r))}async listGroupContexts(e){return h(await this.httpClient.get(`/admin-api/groups/${e}/contexts`))}async addGroupMembers(e,n){await this.httpClient.post(`/admin-api/groups/${e}/members`,n)}async removeGroupMembers(e,n){await this.httpClient.post(`/admin-api/groups/${e}/members/remove`,n)}async updateMemberRole(e,n,r){await this.httpClient.put(`/admin-api/groups/${e}/members/${n}/role`,r)}async getMemberCapabilities(e,n){return h(await this.httpClient.get(`/admin-api/groups/${e}/members/${n}/capabilities`))}async setMemberCapabilities(e,n,r){await this.httpClient.put(`/admin-api/groups/${e}/members/${n}/capabilities`,r)}async setDefaultCapabilities(e,n){await this.httpClient.put(`/admin-api/groups/${e}/settings/default-capabilities`,n)}async openToDelegatedExecution(e){let n=await this.getDefaultCapabilities(e);if(oe(n,T.CAN_AUTHOR_ON_BEHALF))return{changed:!1,defaultCapabilities:n};let r=xt(n,T.CAN_AUTHOR_ON_BEHALF);return await this.setDefaultCapabilities(e,{defaultCapabilities:r}),{changed:!0,defaultCapabilities:r}}async grantAuthorship(e,n){let{capabilities:r}=await this.getMemberCapabilities(e,n);if(oe(r,T.CAN_AUTHOR_ON_BEHALF))return{changed:!1,capabilities:r};let o=xt(r,T.CAN_AUTHOR_ON_BEHALF);return await this.setMemberCapabilities(e,n,{capabilities:o}),{changed:!0,capabilities:o}}async setSubgroupVisibility(e,n){await this.httpClient.put(`/admin-api/groups/${e}/settings/subgroup-visibility`,n)}async setTeeAdmissionPolicy(e,n){await this.httpClient.put(`/admin-api/groups/${e}/settings/tee-admission-policy`,n)}async getTeeAdmissionPolicy(e){let n=await this.httpClient.get(`/admin-api/groups/${e}/settings/tee-admission-policy`);return n.data??n}async setTeeAuthoringPolicy(e,n){await this.httpClient.put(`/admin-api/groups/${e}/settings/tee-authoring-policy`,n)}async disableTeeAuthoringPolicy(e){await this.httpClient.delete(`/admin-api/groups/${e}/settings/tee-authoring-policy`)}async setGroupMetadata(e,n){await this.httpClient.put(`/admin-api/groups/${e}/metadata`,n)}async getGroupMetadata(e){return(await this.httpClient.get(`/admin-api/groups/${e}/metadata`))?.data??null}async setMemberMetadata(e,n,r){await this.httpClient.put(`/admin-api/groups/${e}/members/${n}/metadata`,r)}async getMemberMetadata(e,n){return(await this.httpClient.get(`/admin-api/groups/${e}/members/${n}/metadata`))?.data??null}async setContextMetadata(e,n,r){await this.httpClient.put(`/admin-api/groups/${e}/contexts/${n}/metadata`,r)}async getContextMetadata(e,n){return(await this.httpClient.get(`/admin-api/groups/${e}/contexts/${n}/metadata`))?.data??null}async syncGroup(e){return h(await this.httpClient.post(`/admin-api/groups/${e}/sync`,{}))}async upgradeGroup(e,n){return h(await this.httpClient.post(`/admin-api/groups/${e}/upgrade`,n))}async getGroupUpgradeStatus(e){return h(await this.httpClient.get(`/admin-api/groups/${e}/upgrade/status`))}async getMigrationStatus(e){let n=encodeURIComponent(e);return this.httpClient.get(`/admin-api/groups/${n}/migration-status`)}async getCascadeStatus(e){let n=encodeURIComponent(e);return h(await this.httpClient.get(`/admin-api/groups/${n}/cascade-status`))}async retryGroupUpgrade(e){return h(await this.httpClient.post(`/admin-api/groups/${e}/upgrade/retry`,{}))}async reparentGroup(e,n){let r=await this.httpClient.post(`/admin-api/groups/${e}/reparent`,n);return r?.data??r}async listSubgroups(e){let n=await this.httpClient.get(`/admin-api/groups/${e}/subgroups`);return n.subgroups??n.data??[]}async detachContextFromGroup(e,n){await this.httpClient.post(`/admin-api/groups/${e}/contexts/${n}/remove`,{})}async createGroupInvitation(e,n){return h(await this.httpClient.post(`/admin-api/groups/${e}/invite`,n??{}))}async joinGroup(e){return h(await this.httpClient.post("/admin-api/groups/join",e))}async joinSubgroupInheritance(e){return h(await this.httpClient.post(`/admin-api/groups/${e}/join-via-inheritance`,{}))}async getTeeInfo(){return h(await this.httpClient.get("/admin-api/tee/info"))}async teeAttest(e){return h(await this.httpClient.post("/admin-api/tee/attest",e))}async teeVerifyQuote(e){return h(await this.httpClient.post("/admin-api/tee/verify-quote",e))}async getPeersCount(){return this.httpClient.get("/admin-api/peers")}async getNetworkStatus(){return this.httpClient.get("/admin-api/network/status")}async getUsage(){return this.httpClient.get("/admin-api/usage")}async createGroup(e){return h(await this.httpClient.post("/admin-api/groups",e))}async leaveGroup(e){await this.httpClient.post(`/admin-api/groups/${e}/leave`,{})}async leaveContext(e){await this.httpClient.post(`/admin-api/contexts/${e}/leave`,{})}async leaveNamespace(e){await this.httpClient.post(`/admin-api/namespaces/${e}/leave`,{})}async issueOwnershipProof(e,n){return this.httpClient.post(`/admin-api/groups/${e}/issue-ownership-proof`,n)}async issueNamespaceOwnershipProof(e,n){return this.httpClient.post(`/admin-api/groups/${e}/issue-namespace-ownership-proof`,n)}async setMemberAutoFollow(e,n,r){await this.httpClient.put(`/admin-api/groups/${e}/members/${n}/auto-follow`,r)}async abortMigration(e){return this.httpClient.post(`/admin-api/groups/${e}/migration/abort`,{})}};function Da(t){return Array.from(new TextEncoder().encode(t),e=>e.toString(16).padStart(2,"0")).join("")}function Oa(t){return new Y(re(t))}function Ga(t){return new Y(Me(t))}function xn(t){return new Y(At(t))}function Ge(t,e){return new Y(t)}function St(t){try{let e=t.indexOf("#");if(e===-1)return null;let n=t.substring(e+1),r=new URLSearchParams(n),o=r.get("access_token");return o?{accessToken:o,refreshToken:r.get("refresh_token")??"",applicationId:r.get("application_id")??"",contextId:r.get("context_id")??"",contextIdentity:r.get("context_identity")??"",nodeUrl:r.get("node_url")??""}:null}catch{return null}}function kt(t,e){let n=new URLSearchParams;return n.set("callback-url",e.callbackUrl),e.permissions&&e.permissions.length>0&&n.set("permissions",e.permissions.join(",")),n.set("mode",e.mode),e.packageName&&(n.set("package-name",e.packageName),e.packageVersion&&n.set("package-version",e.packageVersion),e.registryUrl&&n.set("registry-url",e.registryUrl)),`${t.replace(/\/+$/,"")}/auth/login?${n.toString()}`}var Rn=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,112,4,34,4,32]);function w(t){let e=new Uint8Array(4);return new DataView(e.buffer).setUint32(0,t,!0),e}function m(t){return Array.from(t,e=>e.toString(16).padStart(2,"0")).join("")}function p(t,e,n){let r=t.trim();if(!/^[0-9a-fA-F]*$/.test(r)||r.length!==n*2)throw new Error(`${e} must be ${n*2} hex characters, got ${r.length}`);let o=new Uint8Array(n);for(let i=0;i<n;i+=1)o[i]=Number.parseInt(r.slice(i*2,i*2+2),16);return o}function ie(t,e){let n=t.trim();if(!/^[0-9a-fA-F]*$/.test(n)||n.length%2!==0)throw new Error(`${e} must be an even number of hex characters`);let r=new Uint8Array(n.length/2);for(let o=0;o<r.length;o+=1)r[o]=Number.parseInt(n.slice(o*2,o*2+2),16);return r}function x(t){let e=new Uint8Array(8);return new DataView(e.buffer).setBigUint64(0,BigInt(t),!0),e}function f(...t){let e=new Uint8Array(t.reduce((r,o)=>r+o.length,0)),n=0;for(let r of t)e.set(r,n),n+=r.length;return e}async function v(t,e){let n=[x(t.length),t];for(let r of e)n.push(x(r.length),r);return new Uint8Array(await crypto.subtle.digest("SHA-256",f(...n)))}async function se(t){let e=p(t,"deviceSecret",32),n=f(Rn,e);try{return await crypto.subtle.importKey("pkcs8",n,{name:"Ed25519"},!1,["sign"])}catch(r){let o=r instanceof Error?`: ${r.message}`:"";throw new Error("this runtime has no WebCrypto Ed25519, so a warrant cannot be signed here. Node 18.4+, Safari 17+, Firefox 129+ and Chrome 137+ have it; otherwise mint the warrant with `merod account warrant`"+o)}}async function vn(t,e,n){let r=await crypto.subtle.importKey("raw",p(t,"publicKey",32),{name:"Ed25519"},!1,["verify"]);return crypto.subtle.verify({name:"Ed25519"},r,e,n)}async function ae(t){let e=p(t,"deviceSecret",32),n=f(Rn,e),r=await crypto.subtle.importKey("pkcs8",n,{name:"Ed25519"},!0,["sign"]),i=(await crypto.subtle.exportKey("jwk",r)).x;return Uint8Array.from(atob(i.replace(/-/g,"+").replace(/_/g,"/")),a=>a.charCodeAt(0))}var Eo=new TextEncoder().encode("calimero.auth.request.v1"),Io=new TextEncoder().encode("calimero.auth.request.body.v1");function Cn(t){let e=new TextEncoder().encode(t);return f(w(e.length),e)}async function Et(t=new Uint8Array(0)){let e=typeof t=="string"?new TextEncoder().encode(t):t;return v(Io,[e])}async function He(t){let e=await se(t.signerSecret),n=await Et(t.body),r=x(t.issuedAt),o=x(t.expiresAt),i=new TextEncoder,a=await v(Eo,[i.encode(t.method),i.encode(t.path),n,r,o]),s=new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},e,a));return m(f(Cn(t.method),Cn(t.path),n,r,o,s))}function $e(t){let e=ie(t.credential,"credential"),n=ie(t.request,"request signature"),r=t.session===void 0?new Uint8Array([0]):f(new Uint8Array([1]),ie(t.session,"session statement"));return m(f(e,r,n))}function To(t){if(t==null)return new Uint8Array(0);if(typeof t=="string"||t instanceof Uint8Array)return t;if(t instanceof ArrayBuffer)return new Uint8Array(t);if(ArrayBuffer.isView(t))return new Uint8Array(t.buffer,t.byteOffset,t.byteLength);throw new Error(`a request-carried proof cannot commit to a ${t?.constructor?.name??typeof t} body: pass a string or bytes, or use a session for this call`)}function Le(t){let e=t.ttlSeconds??120,n=t.now??(()=>Math.floor(Date.now()/1e3));return async r=>{let o=n();return $e({credential:t.credential,session:t.session,request:await He({method:r.method,path:r.path,body:To(r.body),issuedAt:o,expiresAt:o+e,signerSecret:t.signerSecret})})}}var qe=class extends Error{constructor(e,n,r,o){super(n),this.name="RpcError",this.code=e,this.data=r,this.type=o}};async function It(t,e,n){let r=await t.post("/jsonrpc",{jsonrpc:"2.0",id:1,method:e,params:n});if(r.error){let o=r.error;throw new qe(o.code??-1,o.message??o.type??"RPC error",o.data,o.type)}return r.result}var xe=class{constructor(e){this.kind="node";this.canSubscribe=!0;this.httpClient=e.httpClient}async execute(e){let n=await It(this.httpClient,"execute",{contextId:e.contextId,method:e.method,argsJson:e.argsJson??{}});return n&&"output"in n?n.output:n}async executeWithMetadata(e){return{returns:await this.execute(e),transport:"node"}}async migrateMyEntries(e){return this.execute({contextId:e,method:"migrate_my_entries"})}async countMyPending(e){return this.execute({contextId:e,method:"count_my_pending"})}};var Po=new Set(["MigrationStarted","MigrationProgress","CascadeProgress","MigrationCompleted"]);function Sn(t){return t.type!==void 0&&Po.has(t.type)}var Do=new Set(["token_reuse","token_revoked"]),Uo=new Set([401,403]);function kn(t){let e=t.headers.get("x-auth-error");return!e||!Uo.has(t.status)?null:Do.has(e)?e:null}var M=class{constructor(e){this.sessionId=null;this.abortController=null;this.reconnectTimer=null;this.subscribedContextIds=new Set;this.subscribedGroupIds=new Set;this.closed=!1;this.listeners={connect:[],event:[],error:[]};if(this.baseUrl=e.baseUrl.replace(/\/+$/,""),e.authorize)this.authorize=e.authorize;else if(e.getAuthToken){let n=e.getAuthToken;this.authorize=async()=>({Authorization:`Bearer ${await n()}`})}else throw new Error("SseClient needs either `getAuthToken` or `authorize`");this.reconnectDelayMs=e.reconnectDelayMs??3e3,this.fetchImpl=(n,r)=>e.fetch?e.fetch(n,r):globalThis.fetch(n,r)}on(e,n){let r=e;if(r in this.listeners){let o=this.listeners[r];o.includes(n)||o.push(n)}}off(e,n){let r=e;if(r in this.listeners){let o=this.listeners[r],i=o.indexOf(n);i!==-1&&o.splice(i,1)}}onAppVersionChanged(e){let n=r=>{if(r.type!=="AppVersionChanged")return;let o=r.data;e({contextId:r.contextId,fromVersion:o?.fromVersion,toVersion:o?.toVersion})};return this.on("event",n),()=>this.off("event",n)}onMigrationEvent(e){let n=r=>{Sn(r)&&e(r)};return this.on("event",n),()=>this.off("event",n)}emit(e,n){let r=e;if(r in this.listeners)for(let o of this.listeners[r])try{o(n)}catch{}}async connect(){if(!(this.abortController&&!this.closed)){this.closed=!1,this.abortController=new AbortController;try{let e=`${this.baseUrl}/sse`,n=await this.fetchImpl(e,{headers:{...await this.authorize({method:"GET",path:new URL(e).pathname}),Accept:"text/event-stream"},signal:this.abortController.signal});if(!n.ok){let r=kn(n),o=await n.text().catch(()=>{});throw r?new K(r,n.status,n.statusText,e,n.headers,o):new k(n.status,n.statusText,e,n.headers,o)}if(!n.body)throw new Error("SSE response has no body");this.readStream(n.body).catch(r=>{if(this.closed)return;let o=r instanceof Error?r:new Error(String(r));this.emit("error",o),this.scheduleReconnect()})}catch(e){if(this.closed)return;let n=e instanceof Error?e:new Error(String(e));if(this.emit("error",n),n instanceof K)return;this.scheduleReconnect()}}}async readStream(e){let n=e.getReader(),r=new TextDecoder,o="";try{for(;;){let{done:i,value:a}=await n.read();if(i)break;o+=r.decode(a,{stream:!0});let s=o.split(`
2
+ `);o=s.pop()??"";for(let c of s)if(c.startsWith("data:")){let u=c.slice(5).trim();u&&this.handleMessage(u)}}if(o+=r.decode(),o.startsWith("data:")){let i=o.slice(5).trim();i&&this.handleMessage(i)}}catch(i){if(this.closed)return;let a=i instanceof Error?i:new Error(String(i));this.emit("error",a)}this.closed||this.scheduleReconnect()}handleMessage(e){try{let n=JSON.parse(e);if(n.type==="connect"&&n.session_id){this.sessionId=n.session_id,this.emit("connect",n.session_id),(this.subscribedContextIds.size>0||this.subscribedGroupIds.size>0)&&this.sendSubscription("subscribe",{contextIds:[...this.subscribedContextIds],groupIds:[...this.subscribedGroupIds]});return}if(!n.result)return;let r=n.result.data;if(Array.isArray(r))try{let o=new Uint8Array(r),i=new TextDecoder().decode(o);r=JSON.parse(i)}catch{}if(n.result.contextId){this.emit("event",{contextId:n.result.contextId,type:n.result.type,data:r});return}n.result.groupId&&this.emit("event",{groupId:n.result.groupId,type:n.result.type,data:r})}catch{}}async subscribe(e){let n=Array.isArray(e)?{contextIds:e}:e,r=(n.contextIds??[]).filter(i=>!this.subscribedContextIds.has(i)),o=(n.groupIds??[]).filter(i=>!this.subscribedGroupIds.has(i));for(let i of n.contextIds??[])this.subscribedContextIds.add(i);for(let i of n.groupIds??[])this.subscribedGroupIds.add(i);(r.length>0||o.length>0)&&this.sessionId&&await this.sendSubscription("subscribe",{contextIds:r,groupIds:o})}async unsubscribe(e){let n=Array.isArray(e)?{contextIds:e}:e,r=(n.contextIds??[]).filter(i=>this.subscribedContextIds.has(i)),o=(n.groupIds??[]).filter(i=>this.subscribedGroupIds.has(i));for(let i of n.contextIds??[])this.subscribedContextIds.delete(i);for(let i of n.groupIds??[])this.subscribedGroupIds.delete(i);(r.length>0||o.length>0)&&this.sessionId&&await this.sendSubscription("unsubscribe",{contextIds:r,groupIds:o})}async sendSubscription(e,n){try{let r={};n.contextIds&&n.contextIds.length>0&&(r.contextIds=n.contextIds),n.groupIds&&n.groupIds.length>0&&(r.groupIds=n.groupIds);let o=`${this.baseUrl}/sse/subscription`,i=JSON.stringify({id:this.sessionId,method:e,params:r}),a=await this.fetchImpl(o,{method:"POST",headers:{...await this.authorize({method:"POST",path:new URL(o).pathname,body:i}),"Content-Type":"application/json"},body:i});if(!a.ok){let s=kn(a),c=await a.text().catch(()=>{});this.emit("error",s?new K(s,a.status,a.statusText,`${this.baseUrl}/sse/subscription`,a.headers,c):new k(a.status,a.statusText,`${this.baseUrl}/sse/subscription`,a.headers,c))}}catch(r){this.emit("error",r instanceof Error?r:new Error(`SSE ${e} failed`))}}forceReconnect(){this.abortController&&(this.abortController.abort(),this.abortController=null),this.sessionId=null,this.connect()}scheduleReconnect(){this.closed||(this.reconnectTimer&&clearTimeout(this.reconnectTimer),this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.forceReconnect()},this.reconnectDelayMs))}close(){this.closed=!0,this.abortController&&(this.abortController.abort(),this.abortController=null),this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.sessionId=null,this.subscribedContextIds.clear(),this.subscribedGroupIds.clear()}};var Ke=class Ke{constructor(e){this.ws=null;this.closed=!1;this.reconnectAttempt=0;this.reconnectTimer=null;this.subscribedContextIds=new Set;this.subscribedGroupIds=new Set;this.listeners={connect:[],event:[],error:[]};this.baseUrl=e.baseUrl.replace(/\/+$/,""),this.getAuthToken=e.getAuthToken}on(e,n){let r=e;if(r in this.listeners){let o=this.listeners[r];o.includes(n)||o.push(n)}}off(e,n){let r=e;if(r in this.listeners){let o=this.listeners[r],i=o.indexOf(n);i!==-1&&o.splice(i,1)}}emit(e,n){let r=e;if(r in this.listeners)for(let o of this.listeners[r])try{o(n)}catch{}}async connect(){if(!(this.ws&&(this.ws.readyState===0||this.ws.readyState===1))){this.closed=!1;try{let e=await this.getAuthToken();if(!e)throw new Error("No authentication token available for WebSocket connection");let n=this.baseUrl.replace(/^http/,"ws");this.ws=new WebSocket(`${n}/ws?token=${encodeURIComponent(e)}`),this.ws.onopen=()=>{this.reconnectAttempt=0,this.emit("connect"),this.resubscribeAfterReconnect()},this.ws.onmessage=r=>{this.handleMessage(r.data)},this.ws.onerror=()=>{this.emit("error",new Error("WebSocket error"))},this.ws.onclose=()=>{this.closed||this.scheduleReconnect()}}catch(e){if(this.closed)return;let n=e instanceof Error?e:new Error(String(e));this.emit("error",n),this.scheduleReconnect()}}}handleMessage(e){if(typeof e=="string")try{let n=JSON.parse(e);if(!n.result)return;let r=n.result.data;if(Array.isArray(r))try{let o=new Uint8Array(r),i=new TextDecoder().decode(o);r=JSON.parse(i)}catch{}if(n.result.contextId){this.emit("event",{contextId:n.result.contextId,type:n.result.type,data:r});return}n.result.groupId&&this.emit("event",{groupId:n.result.groupId,type:n.result.type,data:r})}catch{}}subscribe(e){let n=Array.isArray(e)?{contextIds:e}:e;for(let r of n.contextIds??[])this.subscribedContextIds.add(r);for(let r of n.groupIds??[])this.subscribedGroupIds.add(r);this.ws&&this.ws.readyState===1&&this.sendMessage({id:null,method:"subscribe",params:this.buildSubscriptionParams(n.contextIds??[],n.groupIds??[])})}unsubscribe(e){let n=Array.isArray(e)?{contextIds:e}:e;for(let r of n.contextIds??[])this.subscribedContextIds.delete(r);for(let r of n.groupIds??[])this.subscribedGroupIds.delete(r);this.ws&&this.ws.readyState===1&&this.sendMessage({id:null,method:"unsubscribe",params:this.buildSubscriptionParams(n.contextIds??[],n.groupIds??[])})}resubscribeAfterReconnect(){this.subscribedContextIds.size===0&&this.subscribedGroupIds.size===0||this.sendMessage({id:null,method:"subscribe",params:this.buildSubscriptionParams([...this.subscribedContextIds],[...this.subscribedGroupIds])})}buildSubscriptionParams(e,n){let r={};return e.length>0&&(r.contextIds=e),n.length>0&&(r.groupIds=n),r}sendMessage(e){this.ws&&this.ws.readyState===1&&this.ws.send(JSON.stringify(e))}scheduleReconnect(){if(this.closed)return;this.reconnectTimer&&clearTimeout(this.reconnectTimer);let e=Math.min(1e3*Math.pow(2,this.reconnectAttempt),Ke.MAX_BACKOFF_MS);this.reconnectAttempt++,this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.connect()},e)}close(){this.closed=!0,this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.ws&&(this.ws.onclose=null,this.ws.close(),this.ws=null),this.subscribedContextIds.clear(),this.subscribedGroupIds.clear()}};Ke.MAX_BACKOFF_MS=3e4;var B=Ke;function Be(){return{encode(t){return Array.from(new TextEncoder().encode(JSON.stringify(t)))},decode(t){return JSON.parse(new TextDecoder().decode(new Uint8Array(t)))}}}var Re=class{constructor(e){this.httpClient=e.httpClient,this.sse=e.sse}async set(e,n,r=Be()){await It(this.httpClient,"set_ephemeral",{contextId:e,state:r.encode(n)})}subscribe(e,n,r=Be()){let o=i=>{let a=i;if(a.type!=="Ephemeral"||a.contextId!==e)return;let s=a.data;if(!s?.author)return;let c=!!s.removed,u={author:s.author,state:c||s.state===void 0?void 0:r.decode(s.state),removed:c};s.ageMs!==void 0&&(u.ageMs=s.ageMs),n(u)};return this.sse.on("event",o),this.sse.connect().catch(()=>{}),this.sse.subscribe([e]).catch(()=>{}),()=>{this.sse.off("event",o)}}};var No=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,112,4,34,4,32]);function En(t){let e=t instanceof Error?`: ${t.message}`:"";return new Error("this runtime has no WebCrypto Ed25519, so nothing can be signed here. Node 18.4+, Safari 17+, Firefox 129+ and Chrome 137+ have it"+e)}async function ce(t,e="secret"){let n=p(t,e,32),r=f(No,n),o,i;try{let a=await crypto.subtle.importKey("pkcs8",r,{name:"Ed25519"},!0,["sign"]),s=await crypto.subtle.exportKey("jwk",a);i=m(Uint8Array.from(atob(s.x.replace(/-/g,"+").replace(/_/g,"/")),c=>c.charCodeAt(0))),o=await crypto.subtle.importKey("pkcs8",r,{name:"Ed25519"},!1,["sign"])}catch(a){throw En(a)}return Tn(o,i)}async function In(t,e){if(t.type!=="private")throw new Error(`signerFromCryptoKey needs the private half of the pair, got a ${t.type} key`);if(!t.usages.includes("sign"))throw new Error("this CryptoKey cannot sign: generate it with usages ['sign', 'verify']");let n;if(typeof e=="string")p(e,"publicKey",32),n=e.trim().toLowerCase();else try{n=m(new Uint8Array(await crypto.subtle.exportKey("raw",e)))}catch(r){let o=r instanceof Error?`: ${r.message}`:"";throw new Error("could not read the public half of this key pair; pass the public key as 64 hex instead"+o)}return Tn(t,n)}function Tn(t,e){return{publicKey:e,async sign(n){try{return new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},t,n))}catch(r){throw En(r)}}}}async function R(t,e,n){if(e&&t!==void 0)throw new Error(`pass either ${n} or signer, not both \u2014 they may name different keys`);if(e)return e;if(t!==void 0)return ce(t,n);throw new Error(`${n} or signer is required`)}var Mo=new TextEncoder().encode("calimero.device.cert.v1"),_o=new TextEncoder().encode("calimero.account.genesis.v1"),Oo=new TextEncoder().encode("calimero.device.id.v1"),le=2,Go=237;async function Pn(t,e){if(e.length!==16)throw new Error(`nonce must be 16 bytes, got ${e.length}`);let n=p(t,"account",32);return m(await v(Oo,[n,e]))}async function je(t){return v(Mo,[p(t.account,"account",32),p(t.device,"device",32),p(t.signPublicKey,"signPublicKey",32),p(t.kemPublicKey,"kemPublicKey",32),w(t.keyEpoch),w(t.deviceEpoch)])}function Dn(t){return f(new Uint8Array([le]),t.rootPublicKey,w(0),p(t.account,"account",32),p(t.device,"device",32),p(t.signPublicKey,"signPublicKey",32),p(t.kemPublicKey,"kemPublicKey",32),w(t.keyEpoch),w(t.deviceEpoch),t.signature)}async function Un(t){let e=await R(t.rootSecret,t.signer,"rootSecret"),n=p(e.publicKey,"signer.publicKey",32),r=await _(e.publicKey),o=0,i=await je({account:r,device:t.device,signPublicKey:t.signPublicKey,kemPublicKey:t.kemPublicKey,keyEpoch:o,deviceEpoch:t.deviceEpoch}),a=await e.sign(i),s=Dn({rootPublicKey:n,account:r,device:t.device,signPublicKey:t.signPublicKey,kemPublicKey:t.kemPublicKey,keyEpoch:o,deviceEpoch:t.deviceEpoch,signature:a});return m(s)}function Tt(t){let e=p(t,"credential",Go);if(e[0]!==le)throw new Error(`this credential has account genesis version ${e[0]}, not ${le} \u2014 it names a different account than its root key derives here, and core would refuse it`);let n=new DataView(e.buffer,e.byteOffset,e.byteLength),r=n.getUint32(33,!0);if(r!==0)throw new Error(`this credential carries a ${r}-handoff root chain, which this SDK cannot verify yet \u2014 the signing root is not the genesis root, so checking it means walking the chain`);let o=(i,a)=>m(e.subarray(i,i+a));return{rootPublicKey:o(1,32),account:o(37,32),device:o(69,32),signPublicKey:o(101,32),kemPublicKey:o(133,32),keyEpoch:n.getUint32(165,!0),deviceEpoch:n.getUint32(169,!0),signature:o(173,64)}}async function Fe(t){let e=Tt(t),n=await _(e.rootPublicKey);if(n!==e.account)throw new Error(`this credential names account ${e.account}, but its root key derives ${n} \u2014 the certificate was re-pointed at another account`);if(!await vn(e.rootPublicKey,p(e.signature,"signature",64),await je(e)))throw new Error(`the root key of account ${e.account} did not sign this certificate`);return e}async function Ve(t){return _(m(await ae(t)))}async function _(t){return m(await v(_o,[f(new Uint8Array([le]),p(t,"rootPublicKey",32))]))}var Ho=new TextEncoder().encode("calimero.device.scope.v1");async function Pt(t){return v(Ho,[p(t.account,"account",32),p(t.device,"device",32),w(t.scopeEpoch),w(t.keyEpoch),...t.applications.map((e,n)=>p(e,`applications[${n}]`,32))])}async function Nn(t){let e=await R(t.rootSecret,t.signer,"rootSecret"),n=p(e.publicKey,"signer.publicKey",32),r=await _(m(n)),o=t.applications??[],i=t.scopeEpoch??0;if(!Number.isInteger(i)||i<0||i>4294967295)throw new Error(`scopeEpoch must be a u32, got ${i}`);let a=0,s=await Pt({account:r,device:t.device,applications:o,scopeEpoch:i,keyEpoch:a}),c=await e.sign(s);if(c.length!==64)throw new Error(`signer returned ${c.length} bytes, expected a 64-byte Ed25519 signature`);return m(f(new Uint8Array([le]),n,w(0),p(r,"account",32),p(t.device,"device",32),w(o.length),...o.map((u,d)=>p(u,`applications[${d}]`,32)),w(i),w(a),c))}var Dt=["abandon","ability","able","about","above","absent","absorb","abstract","absurd","abuse","access","accident","account","accuse","achieve","acid","acoustic","acquire","across","act","action","actor","actress","actual","adapt","add","addict","address","adjust","admit","adult","advance","advice","aerobic","affair","afford","afraid","again","age","agent","agree","ahead","aim","air","airport","aisle","alarm","album","alcohol","alert","alien","all","alley","allow","almost","alone","alpha","already","also","alter","always","amateur","amazing","among","amount","amused","analyst","anchor","ancient","anger","angle","angry","animal","ankle","announce","annual","another","answer","antenna","antique","anxiety","any","apart","apology","appear","apple","approve","april","arch","arctic","area","arena","argue","arm","armed","armor","army","around","arrange","arrest","arrive","arrow","art","artefact","artist","artwork","ask","aspect","assault","asset","assist","assume","asthma","athlete","atom","attack","attend","attitude","attract","auction","audit","august","aunt","author","auto","autumn","average","avocado","avoid","awake","aware","away","awesome","awful","awkward","axis","baby","bachelor","bacon","badge","bag","balance","balcony","ball","bamboo","banana","banner","bar","barely","bargain","barrel","base","basic","basket","battle","beach","bean","beauty","because","become","beef","before","begin","behave","behind","believe","below","belt","bench","benefit","best","betray","better","between","beyond","bicycle","bid","bike","bind","biology","bird","birth","bitter","black","blade","blame","blanket","blast","bleak","bless","blind","blood","blossom","blouse","blue","blur","blush","board","boat","body","boil","bomb","bone","bonus","book","boost","border","boring","borrow","boss","bottom","bounce","box","boy","bracket","brain","brand","brass","brave","bread","breeze","brick","bridge","brief","bright","bring","brisk","broccoli","broken","bronze","broom","brother","brown","brush","bubble","buddy","budget","buffalo","build","bulb","bulk","bullet","bundle","bunker","burden","burger","burst","bus","business","busy","butter","buyer","buzz","cabbage","cabin","cable","cactus","cage","cake","call","calm","camera","camp","can","canal","cancel","candy","cannon","canoe","canvas","canyon","capable","capital","captain","car","carbon","card","cargo","carpet","carry","cart","case","cash","casino","castle","casual","cat","catalog","catch","category","cattle","caught","cause","caution","cave","ceiling","celery","cement","census","century","cereal","certain","chair","chalk","champion","change","chaos","chapter","charge","chase","chat","cheap","check","cheese","chef","cherry","chest","chicken","chief","child","chimney","choice","choose","chronic","chuckle","chunk","churn","cigar","cinnamon","circle","citizen","city","civil","claim","clap","clarify","claw","clay","clean","clerk","clever","click","client","cliff","climb","clinic","clip","clock","clog","close","cloth","cloud","clown","club","clump","cluster","clutch","coach","coast","coconut","code","coffee","coil","coin","collect","color","column","combine","come","comfort","comic","common","company","concert","conduct","confirm","congress","connect","consider","control","convince","cook","cool","copper","copy","coral","core","corn","correct","cost","cotton","couch","country","couple","course","cousin","cover","coyote","crack","cradle","craft","cram","crane","crash","crater","crawl","crazy","cream","credit","creek","crew","cricket","crime","crisp","critic","crop","cross","crouch","crowd","crucial","cruel","cruise","crumble","crunch","crush","cry","crystal","cube","culture","cup","cupboard","curious","current","curtain","curve","cushion","custom","cute","cycle","dad","damage","damp","dance","danger","daring","dash","daughter","dawn","day","deal","debate","debris","decade","december","decide","decline","decorate","decrease","deer","defense","define","defy","degree","delay","deliver","demand","demise","denial","dentist","deny","depart","depend","deposit","depth","deputy","derive","describe","desert","design","desk","despair","destroy","detail","detect","develop","device","devote","diagram","dial","diamond","diary","dice","diesel","diet","differ","digital","dignity","dilemma","dinner","dinosaur","direct","dirt","disagree","discover","disease","dish","dismiss","disorder","display","distance","divert","divide","divorce","dizzy","doctor","document","dog","doll","dolphin","domain","donate","donkey","donor","door","dose","double","dove","draft","dragon","drama","drastic","draw","dream","dress","drift","drill","drink","drip","drive","drop","drum","dry","duck","dumb","dune","during","dust","dutch","duty","dwarf","dynamic","eager","eagle","early","earn","earth","easily","east","easy","echo","ecology","economy","edge","edit","educate","effort","egg","eight","either","elbow","elder","electric","elegant","element","elephant","elevator","elite","else","embark","embody","embrace","emerge","emotion","employ","empower","empty","enable","enact","end","endless","endorse","enemy","energy","enforce","engage","engine","enhance","enjoy","enlist","enough","enrich","enroll","ensure","enter","entire","entry","envelope","episode","equal","equip","era","erase","erode","erosion","error","erupt","escape","essay","essence","estate","eternal","ethics","evidence","evil","evoke","evolve","exact","example","excess","exchange","excite","exclude","excuse","execute","exercise","exhaust","exhibit","exile","exist","exit","exotic","expand","expect","expire","explain","expose","express","extend","extra","eye","eyebrow","fabric","face","faculty","fade","faint","faith","fall","false","fame","family","famous","fan","fancy","fantasy","farm","fashion","fat","fatal","father","fatigue","fault","favorite","feature","february","federal","fee","feed","feel","female","fence","festival","fetch","fever","few","fiber","fiction","field","figure","file","film","filter","final","find","fine","finger","finish","fire","firm","first","fiscal","fish","fit","fitness","fix","flag","flame","flash","flat","flavor","flee","flight","flip","float","flock","floor","flower","fluid","flush","fly","foam","focus","fog","foil","fold","follow","food","foot","force","forest","forget","fork","fortune","forum","forward","fossil","foster","found","fox","fragile","frame","frequent","fresh","friend","fringe","frog","front","frost","frown","frozen","fruit","fuel","fun","funny","furnace","fury","future","gadget","gain","galaxy","gallery","game","gap","garage","garbage","garden","garlic","garment","gas","gasp","gate","gather","gauge","gaze","general","genius","genre","gentle","genuine","gesture","ghost","giant","gift","giggle","ginger","giraffe","girl","give","glad","glance","glare","glass","glide","glimpse","globe","gloom","glory","glove","glow","glue","goat","goddess","gold","good","goose","gorilla","gospel","gossip","govern","gown","grab","grace","grain","grant","grape","grass","gravity","great","green","grid","grief","grit","grocery","group","grow","grunt","guard","guess","guide","guilt","guitar","gun","gym","habit","hair","half","hammer","hamster","hand","happy","harbor","hard","harsh","harvest","hat","have","hawk","hazard","head","health","heart","heavy","hedgehog","height","hello","helmet","help","hen","hero","hidden","high","hill","hint","hip","hire","history","hobby","hockey","hold","hole","holiday","hollow","home","honey","hood","hope","horn","horror","horse","hospital","host","hotel","hour","hover","hub","huge","human","humble","humor","hundred","hungry","hunt","hurdle","hurry","hurt","husband","hybrid","ice","icon","idea","identify","idle","ignore","ill","illegal","illness","image","imitate","immense","immune","impact","impose","improve","impulse","inch","include","income","increase","index","indicate","indoor","industry","infant","inflict","inform","inhale","inherit","initial","inject","injury","inmate","inner","innocent","input","inquiry","insane","insect","inside","inspire","install","intact","interest","into","invest","invite","involve","iron","island","isolate","issue","item","ivory","jacket","jaguar","jar","jazz","jealous","jeans","jelly","jewel","job","join","joke","journey","joy","judge","juice","jump","jungle","junior","junk","just","kangaroo","keen","keep","ketchup","key","kick","kid","kidney","kind","kingdom","kiss","kit","kitchen","kite","kitten","kiwi","knee","knife","knock","know","lab","label","labor","ladder","lady","lake","lamp","language","laptop","large","later","latin","laugh","laundry","lava","law","lawn","lawsuit","layer","lazy","leader","leaf","learn","leave","lecture","left","leg","legal","legend","leisure","lemon","lend","length","lens","leopard","lesson","letter","level","liar","liberty","library","license","life","lift","light","like","limb","limit","link","lion","liquid","list","little","live","lizard","load","loan","lobster","local","lock","logic","lonely","long","loop","lottery","loud","lounge","love","loyal","lucky","luggage","lumber","lunar","lunch","luxury","lyrics","machine","mad","magic","magnet","maid","mail","main","major","make","mammal","man","manage","mandate","mango","mansion","manual","maple","marble","march","margin","marine","market","marriage","mask","mass","master","match","material","math","matrix","matter","maximum","maze","meadow","mean","measure","meat","mechanic","medal","media","melody","melt","member","memory","mention","menu","mercy","merge","merit","merry","mesh","message","metal","method","middle","midnight","milk","million","mimic","mind","minimum","minor","minute","miracle","mirror","misery","miss","mistake","mix","mixed","mixture","mobile","model","modify","mom","moment","monitor","monkey","monster","month","moon","moral","more","morning","mosquito","mother","motion","motor","mountain","mouse","move","movie","much","muffin","mule","multiply","muscle","museum","mushroom","music","must","mutual","myself","mystery","myth","naive","name","napkin","narrow","nasty","nation","nature","near","neck","need","negative","neglect","neither","nephew","nerve","nest","net","network","neutral","never","news","next","nice","night","noble","noise","nominee","noodle","normal","north","nose","notable","note","nothing","notice","novel","now","nuclear","number","nurse","nut","oak","obey","object","oblige","obscure","observe","obtain","obvious","occur","ocean","october","odor","off","offer","office","often","oil","okay","old","olive","olympic","omit","once","one","onion","online","only","open","opera","opinion","oppose","option","orange","orbit","orchard","order","ordinary","organ","orient","original","orphan","ostrich","other","outdoor","outer","output","outside","oval","oven","over","own","owner","oxygen","oyster","ozone","pact","paddle","page","pair","palace","palm","panda","panel","panic","panther","paper","parade","parent","park","parrot","party","pass","patch","path","patient","patrol","pattern","pause","pave","payment","peace","peanut","pear","peasant","pelican","pen","penalty","pencil","people","pepper","perfect","permit","person","pet","phone","photo","phrase","physical","piano","picnic","picture","piece","pig","pigeon","pill","pilot","pink","pioneer","pipe","pistol","pitch","pizza","place","planet","plastic","plate","play","please","pledge","pluck","plug","plunge","poem","poet","point","polar","pole","police","pond","pony","pool","popular","portion","position","possible","post","potato","pottery","poverty","powder","power","practice","praise","predict","prefer","prepare","present","pretty","prevent","price","pride","primary","print","priority","prison","private","prize","problem","process","produce","profit","program","project","promote","proof","property","prosper","protect","proud","provide","public","pudding","pull","pulp","pulse","pumpkin","punch","pupil","puppy","purchase","purity","purpose","purse","push","put","puzzle","pyramid","quality","quantum","quarter","question","quick","quit","quiz","quote","rabbit","raccoon","race","rack","radar","radio","rail","rain","raise","rally","ramp","ranch","random","range","rapid","rare","rate","rather","raven","raw","razor","ready","real","reason","rebel","rebuild","recall","receive","recipe","record","recycle","reduce","reflect","reform","refuse","region","regret","regular","reject","relax","release","relief","rely","remain","remember","remind","remove","render","renew","rent","reopen","repair","repeat","replace","report","require","rescue","resemble","resist","resource","response","result","retire","retreat","return","reunion","reveal","review","reward","rhythm","rib","ribbon","rice","rich","ride","ridge","rifle","right","rigid","ring","riot","ripple","risk","ritual","rival","river","road","roast","robot","robust","rocket","romance","roof","rookie","room","rose","rotate","rough","round","route","royal","rubber","rude","rug","rule","run","runway","rural","sad","saddle","sadness","safe","sail","salad","salmon","salon","salt","salute","same","sample","sand","satisfy","satoshi","sauce","sausage","save","say","scale","scan","scare","scatter","scene","scheme","school","science","scissors","scorpion","scout","scrap","screen","script","scrub","sea","search","season","seat","second","secret","section","security","seed","seek","segment","select","sell","seminar","senior","sense","sentence","series","service","session","settle","setup","seven","shadow","shaft","shallow","share","shed","shell","sheriff","shield","shift","shine","ship","shiver","shock","shoe","shoot","shop","short","shoulder","shove","shrimp","shrug","shuffle","shy","sibling","sick","side","siege","sight","sign","silent","silk","silly","silver","similar","simple","since","sing","siren","sister","situate","six","size","skate","sketch","ski","skill","skin","skirt","skull","slab","slam","sleep","slender","slice","slide","slight","slim","slogan","slot","slow","slush","small","smart","smile","smoke","smooth","snack","snake","snap","sniff","snow","soap","soccer","social","sock","soda","soft","solar","soldier","solid","solution","solve","someone","song","soon","sorry","sort","soul","sound","soup","source","south","space","spare","spatial","spawn","speak","special","speed","spell","spend","sphere","spice","spider","spike","spin","spirit","split","spoil","sponsor","spoon","sport","spot","spray","spread","spring","spy","square","squeeze","squirrel","stable","stadium","staff","stage","stairs","stamp","stand","start","state","stay","steak","steel","stem","step","stereo","stick","still","sting","stock","stomach","stone","stool","story","stove","strategy","street","strike","strong","struggle","student","stuff","stumble","style","subject","submit","subway","success","such","sudden","suffer","sugar","suggest","suit","summer","sun","sunny","sunset","super","supply","supreme","sure","surface","surge","surprise","surround","survey","suspect","sustain","swallow","swamp","swap","swarm","swear","sweet","swift","swim","swing","switch","sword","symbol","symptom","syrup","system","table","tackle","tag","tail","talent","talk","tank","tape","target","task","taste","tattoo","taxi","teach","team","tell","ten","tenant","tennis","tent","term","test","text","thank","that","theme","then","theory","there","they","thing","this","thought","three","thrive","throw","thumb","thunder","ticket","tide","tiger","tilt","timber","time","tiny","tip","tired","tissue","title","toast","tobacco","today","toddler","toe","together","toilet","token","tomato","tomorrow","tone","tongue","tonight","tool","tooth","top","topic","topple","torch","tornado","tortoise","toss","total","tourist","toward","tower","town","toy","track","trade","traffic","tragic","train","transfer","trap","trash","travel","tray","treat","tree","trend","trial","tribe","trick","trigger","trim","trip","trophy","trouble","truck","true","truly","trumpet","trust","truth","try","tube","tuition","tumble","tuna","tunnel","turkey","turn","turtle","twelve","twenty","twice","twin","twist","two","type","typical","ugly","umbrella","unable","unaware","uncle","uncover","under","undo","unfair","unfold","unhappy","uniform","unique","unit","universe","unknown","unlock","until","unusual","unveil","update","upgrade","uphold","upon","upper","upset","urban","urge","usage","use","used","useful","useless","usual","utility","vacant","vacuum","vague","valid","valley","valve","van","vanish","vapor","various","vast","vault","vehicle","velvet","vendor","venture","venue","verb","verify","version","very","vessel","veteran","viable","vibrant","vicious","victory","video","view","village","vintage","violin","virtual","virus","visa","visit","visual","vital","vivid","vocal","voice","void","volcano","volume","vote","voyage","wage","wagon","wait","walk","wall","walnut","want","warfare","warm","warrior","wash","wasp","waste","water","wave","way","wealth","weapon","wear","weasel","weather","web","wedding","weekend","weird","welcome","west","wet","whale","what","wheat","wheel","when","where","whip","whisper","wide","width","wife","wild","will","win","window","wine","wing","wink","winner","winter","wire","wisdom","wise","wish","witness","wolf","woman","wonder","wood","wool","word","work","world","worry","worth","wrap","wreck","wrestle","wrist","write","wrong","yard","year","yellow","you","young","youth","zebra","zero","zone","zoo"];var $o=new TextEncoder().encode("calimero.mdma.account-link.v1\0"),Lo=new TextEncoder().encode("calimero.mdma.account-login.v1\0"),ue=256,Mn=ue/32,Ut=(ue+Mn)/11;async function _n(){let t=crypto.getRandomValues(new Uint8Array(ue/8));return qn(m(t),await Bn(t))}async function On(t){let e=Kn(t);return qn(m(await jn(e)),e.join(" "))}async function Nt(t){return p(t,"secret",32),{secret:t,publicKey:m(await ae(t)),accountId:await Ve(t)}}async function Gn(){let t=crypto.getRandomValues(new Uint8Array(ue/8)),e=await Bn(t);return{...await $n(t),phrase:e}}async function Hn(t){return $n(await jn(Kn(t)))}async function $n(t){let e=await ce(m(t),"rootSecret");return t.fill(0),{publicKey:e.publicKey,accountId:await _(e.publicKey),signer:e}}async function $(t){let e=typeof t=="string"?await ce(t,"rootSecret"):t;return Ln(e)}async function We(t,e){return Ln(await R(t,e,"rootSecret"))}async function Ln(t){return{signer:t,publicKey:t.publicKey,accountId:await _(t.publicKey)}}async function ve(t){if(!t.nonce)throw new Error("nonce is required to sign an account link");let n=await(await R(t.rootSecret,t.signer,"rootSecret")).sign(f($o,new TextEncoder().encode(t.nonce)));return Wn(n)}async function ze(t){if(!t.nonce)throw new Error("nonce is required to sign an account login");let n=await(await R(t.rootSecret,t.signer,"rootSecret")).sign(f(Lo,new TextEncoder().encode(t.nonce)));return Wn(n)}async function qn(t,e){return{...await Nt(t),phrase:e}}function Kn(t){let e=t.normalize("NFKD").toLowerCase().trim().split(/\s+/),n=e[0]===""?0:e.length;if(n!==Ut)throw new Error(`recovery phrase must be ${Ut} words, got ${n}`);return e}async function Bn(t){let e=Vn(t)+await Fn(t),n=[];for(let r=0;r<Ut;r+=1){let o=Number.parseInt(e.slice(r*11,r*11+11),2);n.push(Dt[o])}return n.join(" ")}async function jn(t){let e="";for(let r of t){let o=Dt.indexOf(r);if(o<0)throw new Error(`"${r}" is not a word in the recovery phrase list`);e+=o.toString(2).padStart(11,"0")}let n=new Uint8Array(ue/8);for(let r=0;r<n.length;r+=1)n[r]=Number.parseInt(e.slice(r*8,r*8+8),2);if(e.slice(ue)!==await Fn(n))throw new Error("recovery phrase checksum failed \u2014 check for a mistyped or transposed word");return n}async function Fn(t){let e=new Uint8Array(await crypto.subtle.digest("SHA-256",t));return Vn(e).slice(0,Mn)}function Vn(t){let e="";for(let n of t)e+=n.toString(2).padStart(8,"0");return e}function Wn(t){let e="";for(let n of t)e+=String.fromCharCode(n);return btoa(e)}var qo=new TextEncoder().encode("calimero.mdma.routing-read.v1\0");async function zn(t,e){p(e,"deviceSecret",32);let n=await se(e),r=f(qo,new TextEncoder().encode(t)),o=new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},n,r));return Ko(o)}async function Je(t,e){return{"X-Calimero-Credential":e.credential,"X-Calimero-Nonce":t.nonce,"X-Calimero-Signature":await zn(t.nonce,e.deviceSecret)}}function Ko(t){let e="";for(let n of t)e+=String.fromCharCode(n);return btoa(e)}var Bo="https://manager.cloud.calimero.network";function Mt(t,e){return typeof t.can_execute=="boolean"?t.can_execute:e}function _t(t){return typeof t.tee_role=="string"&&t.tee_role!==""?t.tee_role:null}function Ot(t){return t.find(e=>e.canExecute&&e.relayUrl!==null&&e.executorAccount!==null)??null}var jo="x-mdma-session-refresh",Fo="x-mdma-session-expires",O=class{constructor(e={}){this.session=null;this.baseUrl=(e.cloudBaseUrl||Bo).replace(/\/+$/,""),this.onSession=e.onSession;let n=e.fetch;this.fetchImpl=n?(r,o)=>n(r,o):(r,o)=>globalThis.fetch(r,o),this.timeoutMs=e.timeoutMs??1e4,this.routingCredential=e.routingCredential,e.sessionToken&&(this.session={sessionToken:e.sessionToken,expiresAt:0,user:{email:""}})}getSession(){return this.session}isSignedIn(){return this.session!==null}async signInWithGoogle(e){let n=await this.request("POST","/api/auth/google",{body:{id_token:e},anonymous:!0});return this.adoptSession(n)}async signInWithAccount(e){let{signer:n,publicKey:r}=await $(e),{nonce:o}=await this.getAccountLoginChallenge();return this.submitAccountLogin({rootPublicKey:r,nonce:o,signature:await ze({signer:n,nonce:o})})}async getAccountLoginChallenge(){let e=await this.request("GET","/api/auth/account/challenge",{anonymous:!0});return{nonce:e.nonce,expiresAtMs:e.expires_at_ms}}async submitAccountLogin(e){let n=await this.request("POST","/api/auth/account",{body:{root_public_key:e.rootPublicKey,nonce:e.nonce,signature:e.signature},anonymous:!0});return this.adoptSession(n)}async refreshSession(){let e=await this.request("POST","/api/auth/refresh");return this.adoptSession(e)}async signOut(){try{this.session&&await this.request("POST","/api/auth/logout",{parse:"none"})}finally{this.session=null,this.notifySession(null)}}async getMyNamespaces(){return(await this.request("GET","/api/cloud/me/namespaces")).map(n=>({namespaceId:String(n.namespace_id??n.group_id??""),groupId:String(n.group_id??n.namespace_id??""),haStatus:String(n.ha_status??"none"),haEnabledAt:n.ha_enabled_at??null,contexts:Array.isArray(n.contexts)?n.contexts:[],fleetReplicas:n.fleet_replicas}))}async getNamespaceRelays(e){return((await this.request("GET",`/api/cloud/me/namespaces/${encodeURIComponent(e)}/relays`)).relays??[]).map(r=>{let o=r.relay_url??null,i=r.executor_account??null,a=r.authorship_ready===!0;return{peerId:String(r.peer_id??""),relayUrl:o,executorAccount:i,nodeKey:r.node_key??r.node_public_key??null,status:String(r.status??""),authorshipReady:a,teeRole:_t(r),canExecute:Mt(r,a&&o!==null&&i!==null),lastSeenAt:r.last_seen_at??null,confirmedAt:r.confirmed_at??null}})}async findExecutingRelay(e){let n=await this.getNamespaceRelays(e);return Ot(n)}async getNamespaceRouting(e){let n=await this.request("GET",`/api/cloud/namespaces/${encodeURIComponent(e)}/admitters`,{anonymous:!0,headers:await this.routingProof(e)});return{namespaceId:String(n.namespace_id??e),nodes:(n.admitters??[]).map(r=>{let o=r.account??null,i=r.relay_url??null,a=r.fresh===!0,s=r.authorship_ready===!0;return{peerId:String(r.peer_id??""),account:o,relayUrl:i,admitUrl:r.admit_url??null,status:String(r.status??""),fresh:a,canAdmit:r.can_admit===!0,authorshipReady:s,teeRole:_t(r),canExecute:Mt(r,s&&i!==null&&o!==null&&a)}}),servable:n.servable===!0,writable:n.writable===!0}}async getRoutingChallenge(e){let n=await this.request("GET",`/api/cloud/namespaces/${encodeURIComponent(e)}/challenge`,{anonymous:!0});return{namespaceId:String(n.namespace_id??e),nonce:String(n.nonce??""),expiresAtMs:Number(n.expires_at_ms??0)}}async routingProof(e){if(!this.routingCredential)return;let n=await this.getRoutingChallenge(e);return Je(n,this.routingCredential)}async getAccountRelaysChallenge(e){let n=await this.request("GET",`/api/cloud/accounts/${encodeURIComponent(e)}/challenge`,{anonymous:!0});return{accountId:String(n.account_id??e),nonce:String(n.nonce??""),expiresAtMs:Number(n.expires_at_ms??0)}}async getAccountRelays(e){if(!this.routingCredential)throw new Error("getAccountRelays needs a routingCredential: construct the client with the device certificate and its signing secret, since this read is proven by the device, not by a session.");let n=await this.getAccountRelaysChallenge(e);return((await this.request("GET",`/api/cloud/accounts/${encodeURIComponent(e)}/relays`,{anonymous:!0,headers:await Je(n,this.routingCredential)})).relays??[]).map(o=>({peerId:String(o.peer_id??""),relayUrl:o.relay_url??null,fresh:o.fresh===!0}))}async findAdmitter(e,n){let{nodes:r}=await this.getNamespaceRouting(e),o=n&&n.length>0?new Set(n.map(i=>i.toLowerCase())):null;return r.find(i=>i.canAdmit&&(o===null||i.account!==null&&o.has(i.account.toLowerCase())))??null}async getMyMachines(){return((await this.request("GET","/api/cloud/me/machines")).machines??[]).map(n=>{let r=n.relay_url??null,o=n.executor_account??null,i=(Array.isArray(n.namespaces)?n.namespaces:[]).map(a=>{let s=a;return{namespaceId:String(s.namespace_id??""),status:String(s.status??""),authorshipReady:s.authorship_ready===!0,teeRole:_t(s),fresh:s.fresh===!0,confirmedAt:s.confirmed_at??null,lastSeenAt:s.last_seen_at??null}});return{peerId:String(n.peer_id??""),relayUrl:r,executorAccount:o,canExecute:Mt(n,r!==null&&o!==null&&i.some(a=>a.authorshipReady)),namespaces:i}})}async claimNamespace(e,n){await this.request("POST","/api/cloud/namespaces/claim",{body:{namespace_id:e,ownership_proof:n}})}async enableNamespaceHa(e,n={}){let r=n.admitterAddrs===void 0?{}:{admitter_addrs:[...n.admitterAddrs]};return this.request("POST",`/api/cloud/namespaces/${encodeURIComponent(e)}/enable-ha`,{body:r})}async disableNamespaceHa(e){return this.request("POST",`/api/cloud/namespaces/${encodeURIComponent(e)}/disable-ha`,{body:{}})}async getMyNode(){return(await this.request("GET","/api/cloud/me/node")).node??null}enableHA(e){let n=new URLSearchParams({group_id:e.groupId,context_id:e.contextId});e.redirectUrl&&n.set("redirect_url",e.redirectUrl),window.open(`${this.baseUrl}/enable-ha?${n.toString()}`)}disableHA(e){let n=new URLSearchParams({group_id:e.groupId,context_id:e.contextId});e.redirectUrl&&n.set("redirect_url",e.redirectUrl),window.open(`${this.baseUrl}/disable-ha?${n.toString()}`)}async linkAccount(e){let{signer:n,publicKey:r,accountId:o}=await $(e),{nonce:i}=await this.getAccountLinkChallenge();return this.submitAccountLink({accountId:o,rootPublicKey:r,nonce:i,signature:await ve({signer:n,nonce:i})})}async getAccountLinkChallenge(){let e=await this.request("GET","/api/cloud/me/accounts/challenge");return{nonce:e.nonce,expiresAtMs:e.expires_at_ms??null}}async submitAccountLink(e){let n=await this.request("POST","/api/cloud/me/accounts",{body:{account_id:e.accountId,root_public_key:e.rootPublicKey,nonce:e.nonce,signature:e.signature}});return{accountId:String(n.account_id??e.accountId),linkedAt:n.linked_at??null,alreadyLinked:n.already_linked===!0}}static accountLinkHandoff(e){let n=e.portalUrl.replace(/\/+$/,""),r=new URLSearchParams({"link-account":e.accountId,"callback-url":e.callbackUrl});return{url:`${n}/?${r.toString()}`,accountId:e.accountId}}static readAccountLinkCallback(e){let n=e??(typeof window>"u"?"":window.location.href);if(!n)return{};let r;try{r=new URL(n).hash}catch{return{}}let o=new URLSearchParams(r.replace(/^#/,"")),i=o.get("grant"),a=o.get("account"),s=o.get("error"),c={};return i&&(c.grant=i),a&&(c.accountId=a),s&&(c.error=s),c}async linkAccountWithGrant(e){let{signer:n,publicKey:r,accountId:o}=await We(e.rootSecret,e.signer),i=await this.request("POST","/api/cloud/accounts/link",{body:{grant:e.grant,root_public_key:r,signature:await ve({signer:n,nonce:e.grant})},anonymous:!0});return{accountId:String(i.account_id??o),linkedAt:i.linked_at??null,alreadyLinked:i.already_linked===!0}}async getMyAccounts(){let e=await this.request("GET","/api/cloud/me/accounts");return{accounts:(e.accounts??[]).map(n=>({accountId:String(n.account_id??""),linkedAt:n.linked_at??null,hasRecoveryEnvelope:n.has_recovery_envelope===!0})),limit:e.limit??null}}adoptSession(e){return this.session={sessionToken:e.session_token,expiresAt:e.expires_at,user:e.user},this.notifySession(this.session),this.session}async notifySession(e){try{await this.onSession?.(e)}catch{}}async request(e,n,r={}){if(!r.anonymous&&!this.session)throw new Error("Not signed in to Calimero Cloud: call signInWithGoogle() or construct the client with a sessionToken");let o={...r.headers,Accept:"application/json"};r.body!==void 0&&(o["Content-Type"]="application/json"),!r.anonymous&&this.session&&(o.Authorization=`Bearer ${this.session.sessionToken}`);let i=new AbortController,a=setTimeout(()=>i.abort(),this.timeoutMs),s;try{s=await this.fetchImpl(`${this.baseUrl}${n}`,{method:e,headers:o,body:r.body===void 0?void 0:JSON.stringify(r.body),signal:i.signal})}catch(c){throw new k(0,c instanceof Error?c.name:"NetworkError",`${this.baseUrl}${n}`,new Headers,c instanceof Error?c.message:String(c))}finally{clearTimeout(a)}if(this.adoptRollingRefresh(s),!s.ok){let c=await s.text().catch(()=>{});throw new k(s.status,s.statusText,`${this.baseUrl}${n}`,s.headers,c)}if(!(r.parse==="none"||s.status===204))return await s.json()}adoptRollingRefresh(e){let n=e.headers.get(jo);if(!n||!this.session)return;let r=e.headers.get(Fo),o=Number(r);this.session={sessionToken:n,expiresAt:Number.isFinite(o)&&o>0?o:this.session.expiresAt,user:this.session.user},this.notifySession(this.session)}};function Vo(t){let e=t&&typeof t=="object"?t.data??t:void 0;if(!e||typeof e!="object")return[];let n=e.localPeerId,r=e.externalAddrs;if(typeof n!="string"||!n||!Array.isArray(r))return[];let o=`/p2p/${n}`,i=[];for(let a of r){if(typeof a!="string")continue;let s=a.trim();if(!s.startsWith("/"))continue;let c=s.endsWith(o)?s:`${s}${o}`;i.includes(c)||i.push(c)}return i}function Wo(t){if(t)return typeof t=="function"?t:Le(t)}var zo="mero-js:token-refresh";function Jo(){let e=globalThis.navigator?.locks;return e&&typeof e.request=="function"?e:null}function Gt(t,e){try{let n=t.split(".");if(n.length===3){let r=n[1].replace(/-/g,"+").replace(/_/g,"/");for(;r.length%4;)r+="=";let o=JSON.parse(atob(r));if(typeof o.exp=="number")return o.exp*1e3}}catch{}return e}var de=class{constructor(e){this.tokenData=null;this.refreshPromise=null;this.rpcClient=null;this.sseClient=null;this.wsClient=null;this.wsWarned=!1;this.config={timeoutMs:1e4,...e},this.tokenStore=e.tokenStore??null,this.tokenStore&&(this.tokenData=this.tokenStore.getTokens());let n=typeof window<"u"&&"__TAURI_INTERNALS__"in window,r=Wo(this.config.requestProof);this.httpClient=re({baseUrl:this.config.baseUrl,fetch:this.config.fetch,getProof:r,getAuthToken:async()=>(await this.getValidToken())?.access_token||"",refreshToken:async()=>(await this.performTokenRefresh()).access_token,onTokenRefresh:async o=>{this.tokenData&&(this.tokenData.access_token=o,this.tokenStore?.setTokens(this.tokenData))},onAuthRevoked:async()=>{this.clearToken();try{await this.config.onAuthRevoked?.()}catch{}},timeoutMs:this.config.timeoutMs,credentials:this.config.requestCredentials??(n?"omit":void 0)}),this.authClient=fn(this.httpClient,{baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||"",timeoutMs:this.config.timeoutMs}),this.adminClient=Ge(this.httpClient,{baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||"",timeoutMs:this.config.timeoutMs})}get auth(){return this.authClient}get admin(){return this.adminClient}get rpc(){return this.rpcClient||(this.rpcClient=new xe({httpClient:this.httpClient})),this.rpcClient}get events(){return this.sseClient||(this.sseClient=new M({baseUrl:this.config.baseUrl,fetch:this.config.fetch,getAuthToken:async()=>(await this.getValidToken())?.access_token||""})),this.sseClient}get ephemeral(){return this.ephemeralClient||(this.ephemeralClient=new Re({httpClient:this.httpClient,sse:this.events})),this.ephemeralClient}get cloud(){return this.cloudClient||(this.cloudClient=new O(this.config.cloud??{})),this.cloudClient}get ws(){return this.wsWarned||(this.wsWarned=!0,console.warn("[mero-js] WsClient is experimental. Use mero.events (SSE) for production.")),this.wsClient||(this.wsClient=new B({baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||""})),this.wsClient}async authenticate(e){let n=e||this.config.credentials;if(!n)throw new Error("No credentials provided for authentication");try{let r={auth_method:"user_password",public_key:n.username,client_name:"mero-js-sdk",permissions:["admin"],timestamp:Math.floor(Date.now()/1e3),provider_data:{username:n.username,password:n.password}},o=await this.authClient.generateTokens(r),i=o.data.access_token;return this.tokenData={access_token:i,refresh_token:o.data.refresh_token,expires_at:Gt(i,Date.now()+36e5)},this.tokenStore?.setTokens(this.tokenData),this.tokenData}catch(r){throw new Error(`Authentication failed: ${r instanceof Error?r.message:"Unknown error"}`)}}async getValidToken(){return this.tokenData}async performTokenRefresh(){if(this.refreshPromise)return this.refreshPromise;let e=this.tokenData?.access_token,n=this.withRefreshLock(()=>this.performTokenRefreshLocked(e));this.refreshPromise=n;try{return await n}finally{this.refreshPromise===n&&(this.refreshPromise=null)}}withRefreshLock(e){let n=Jo();return n?n.request(zo,e):e()}async performTokenRefreshLocked(e){let n=this.tokenStore?.getTokens()??null;if(n?.refresh_token&&(this.tokenData=n,e&&n.access_token!==e))return n;if(!this.tokenData?.refresh_token)throw new Error("No refresh token available");try{let r=await this.authClient.refreshToken({access_token:this.tokenData.access_token,refresh_token:this.tokenData.refresh_token}),o=r.data.access_token;return this.tokenData={access_token:o,refresh_token:r.data.refresh_token,expires_at:Gt(o,Date.now()+36e5)},this.tokenStore?.setTokens(this.tokenData),this.tokenData}catch(r){throw new Error(`Token refresh failed: ${r instanceof Error?r.message:"Unknown error"}`)}}clearToken(){this.refreshPromise=null,this.tokenData=null,this.tokenStore?.clear()}isAuthenticated(){return this.tokenData!==null}setTokenData(e){let n=e.expires_at||Gt(e.access_token,Date.now()+36e5);this.tokenData={...e,expires_at:n},this.tokenStore?.setTokens(this.tokenData)}getTokenData(){return this.tokenData}close(){this.sseClient?.close(),this.wsClient?.close()}static parseAuthCallback(e){return St(e)}static buildAuthLoginUrl(e,n){return kt(e,n)}};function Qo(t){return new de(t)}var Ht=class{constructor(){this.tokens=null}getTokens(){return this.tokens}setTokens(e){this.tokens=e}clear(){this.tokens=null}},Yo="mero-tokens",$t=class{constructor(e=Yo){this.key=e}getTokens(){try{if(typeof localStorage>"u")return null;let e=localStorage.getItem(this.key);if(!e)return null;let n=JSON.parse(e);return n&&n.access_token&&n.refresh_token?{access_token:n.access_token,refresh_token:n.refresh_token,expires_at:typeof n.expires_at=="number"?n.expires_at:Date.now()+36e5}:null}catch{return null}}setTokens(e){try{if(typeof localStorage>"u")return;localStorage.setItem(this.key,JSON.stringify(e))}catch{}}clear(){try{if(typeof localStorage>"u")return;localStorage.removeItem(this.key)}catch{}}};var Xo=new TextEncoder().encode("calimero.warrant.v2"),Zo=new TextEncoder().encode("calimero.warrant.intent.v1"),Jn=64,ei="00".repeat(32);async function Lt(t,e){let n=new TextEncoder().encode(JSON.stringify(e));return v(Zo,[new TextEncoder().encode(t),n])}async function Qe(t){let e=p(t.context,"context",32),n=p(t.authorAccount,"authorAccount",32),r=p(t.executor,"executor",32),o=p(t.appVersion??ei,"appVersion",32),i=j(t.accountHeads,"accountHeads"),a=j(t.governanceFloor,"governanceFloor"),s=await R(t.deviceSecret,t.signer,"deviceSecret"),c=p(s.publicKey,"signer.publicKey",32),u=new TextEncoder().encode(t.method),d=await Lt(t.method,t.argsJson),l=x(t.nonce),g=x(t.notAfter),y=await v(Xo,[e,n,c,r,o,u,d,x(i.length),...i,x(a.length),...a,l,g]),A=Ce(await s.sign(y));return m(f(e,n,c,r,o,w(u.length),u,d,w(i.length),...i,w(a.length),...a,l,g,A))}function Ce(t){if(!(t instanceof Uint8Array)||t.length!==64){let e=t instanceof Uint8Array?`${t.length} bytes`:typeof t;throw new Error(`signer returned ${e}, expected a 64-byte Ed25519 signature`)}return t}function j(t,e){let n=t??[];if(n.length>Jn)throw new Error(`${e} cites ${n.length} heads, over the ${Jn} a node accepts`);return n.map((r,o)=>p(r,`${e}[${o}]`,32))}var ti=new TextEncoder().encode("calimero.context-creation-warrant.v1"),ni=new TextEncoder().encode("calimero.context-creation.init.v1"),Ye=256;async function qt(t){let e=new TextEncoder().encode(JSON.stringify(t));return v(ni,[e])}async function ri(t){return v(ti,[t.group,t.seed,t.authorAccount,t.deviceKey,t.executor,t.applicationId,new Uint8Array([t.serviceName===null?0:1]),t.serviceName??new Uint8Array(0),new Uint8Array([t.name===null?0:1]),t.name??new Uint8Array(0),t.initHash,x(t.accountHeads.length),...t.accountHeads,x(t.governanceFloor.length),...t.governanceFloor,x(t.nonce),x(t.notAfter)])}async function Xe(t){let e=p(t.group,"group",32),n=t.seed===void 0?crypto.getRandomValues(new Uint8Array(32)):p(t.seed,"seed",32),r=p(t.authorAccount,"authorAccount",32),o=p(t.executor,"executor",32),i=p(t.applicationId,"applicationId",32),a=Qn(t.serviceName,"serviceName"),s=Qn(t.name,"name"),c=j(t.accountHeads,"accountHeads"),u=j(t.governanceFloor,"governanceFloor"),d=await R(t.deviceSecret,t.signer,"deviceSecret"),l=p(d.publicKey,"signer.publicKey",32),g=await qt(t.initArgs),y=await ri({group:e,seed:n,authorAccount:r,deviceKey:l,executor:o,applicationId:i,serviceName:a,name:s,initHash:g,accountHeads:c,governanceFloor:u,nonce:t.nonce,notAfter:t.notAfter}),A=Ce(await d.sign(y));return{warrant:m(f(e,n,r,l,o,i,Yn(a),Yn(s),g,w(c.length),...c,w(u.length),...u,x(t.nonce),x(t.notAfter),A)),seed:m(n)}}function Xn(t){let e=t.trim();if(!/^[0-9a-fA-F]*$/.test(e)||e.length%2!==0)throw new Error("creation warrant must be an even number of hex characters");let n=new Uint8Array(e.length/2);for(let l=0;l<n.length;l+=1)n[l]=Number.parseInt(e.slice(l*2,l*2+2),16);let r=new DataView(n.buffer),o=0,i=(l,g)=>{if(o+l>n.length)throw new Error(`creation warrant ends inside ${g} (${n.length} bytes)`);let y=n.subarray(o,o+l);return o+=l,y},a=l=>r.getUint32(i(4,l).byteOffset,!0),s=l=>r.getBigUint64(i(8,l).byteOffset,!0),c=l=>{let g=i(1,l)[0];if(g===0)return null;if(g!==1)throw new Error(`${l} has option tag ${g}, expected 0 or 1`);let y=a(l);if(y>Ye)throw new Error(`${l} is ${y} bytes, over the ${Ye} a node accepts`);return new TextDecoder("utf-8",{fatal:!0}).decode(i(y,l))},u=l=>{let g=a(l);if(g>64)throw new Error(`${l} cites ${g} heads, over the 64 a node accepts`);return Array.from({length:g},()=>m(i(32,l)))},d={group:m(i(32,"group")),seed:m(i(32,"seed")),authorAccount:m(i(32,"authorAccount")),deviceKey:m(i(32,"deviceKey")),executor:m(i(32,"executor")),applicationId:m(i(32,"applicationId")),serviceName:c("serviceName"),name:c("name"),initHash:m(i(32,"initHash")),accountHeads:u("accountHeads"),governanceFloor:u("governanceFloor"),nonce:s("nonce"),notAfter:s("notAfter"),signature:m(i(64,"signature"))};if(o!==n.length)throw new Error(`creation warrant is ${n.length} bytes but its fields account for ${o}`);return d}function Qn(t,e){if(t===void 0)return null;let n=new TextEncoder().encode(t);if(n.length>Ye)throw new Error(`${e} is ${n.length} UTF-8 bytes, over the ${Ye} a node accepts`);return n}function Yn(t){return t===null?new Uint8Array([0]):f(new Uint8Array([1]),w(t.length),t)}var oi=new TextEncoder().encode("calimero.governance-warrant.v1"),ii=new TextEncoder().encode("calimero.governance-warrant.op.v1"),si={group:0,root:1};async function Kt(t){return v(ii,[new Uint8Array([Bt(t.kind)]),t.bytes])}async function ai(t){return v(oi,[t.scope,new Uint8Array([Bt(t.kind)]),t.authorAccount,t.deviceKey,t.executor,t.opHash,x(t.accountHeads.length),...t.accountHeads,x(t.governanceFloor.length),...t.governanceFloor,x(t.nonce),x(t.notAfter)])}async function Se(t){let e=p(t.scope,"scope",32),n=p(t.authorAccount,"authorAccount",32),r=p(t.executor,"executor",32),o=j(t.accountHeads,"accountHeads"),i=j(t.governanceFloor,"governanceFloor"),a=Bt(t.op.kind),s=await R(t.deviceSecret,t.signer,"deviceSecret"),c=p(s.publicKey,"signer.publicKey",32),u=await Kt(t.op),d=await ai({scope:e,kind:t.op.kind,authorAccount:n,deviceKey:c,executor:r,opHash:u,accountHeads:o,governanceFloor:i,nonce:t.nonce,notAfter:t.notAfter}),l=Ce(await s.sign(d));return m(f(e,new Uint8Array([a]),n,c,r,u,w(o.length),...o,w(i.length),...i,x(t.nonce),x(t.notAfter),l))}function Zn(t){let e=t.trim();if(!/^[0-9a-fA-F]*$/.test(e)||e.length%2!==0)throw new Error("governance warrant must be an even number of hex characters");let n=new Uint8Array(e.length/2);for(let l=0;l<n.length;l+=1)n[l]=Number.parseInt(e.slice(l*2,l*2+2),16);let r=new DataView(n.buffer),o=0,i=(l,g)=>{if(o+l>n.length)throw new Error(`governance warrant ends inside ${g} (${n.length} bytes)`);let y=n.subarray(o,o+l);return o+=l,y},a=l=>r.getUint32(i(4,l).byteOffset,!0),s=l=>r.getBigUint64(i(8,l).byteOffset,!0),c=l=>{let g=a(l);if(g>64)throw new Error(`${l} cites ${g} heads, over the 64 a node accepts`);return Array.from({length:g},()=>m(i(32,l)))},u=()=>{let l=i(1,"kind")[0];if(l===0)return"group";if(l===1)return"root";throw new Error(`governance warrant has kind ${l}, expected 0 (group) or 1 (root)`)},d={scope:m(i(32,"scope")),kind:u(),authorAccount:m(i(32,"authorAccount")),deviceKey:m(i(32,"deviceKey")),executor:m(i(32,"executor")),opHash:m(i(32,"opHash")),accountHeads:c("accountHeads"),governanceFloor:c("governanceFloor"),nonce:s("nonce"),notAfter:s("notAfter"),signature:m(i(64,"signature"))};if(o!==n.length)throw new Error(`governance warrant is ${n.length} bytes but its fields account for ${o}`);return d}function Bt(t){let e=si[t];if(e===void 0)throw new Error(`op kind must be 'group' or 'root', got ${String(t)}`);return e}var ci={Admin:0,Member:1,ReadOnly:2},ke={MemberAdded:1,MemberRemoved:2,MemberLeft:3,MemberRoleSet:4,DefaultCapabilitiesSet:6},et={GroupCreated:0,GroupReparented:1,GroupDeleted:2,NamespaceCreatedV2:9},li=new TextEncoder().encode("calimero.namespace.id.v1"),er=new Uint8Array(32),Ze=w(0);function tr(t){let e=ci[t];if(e===void 0)throw new Error(`role must be Admin, Member or ReadOnly, got ${String(t)}`);return new Uint8Array([e])}function G(t){return new Uint8Array([t])}function nr(t,e){return{kind:"group",bytes:f(G(ke.MemberAdded),p(t,"member",32),tr(e))}}function rr(t){return{kind:"group",bytes:f(G(ke.MemberRemoved),p(t,"member",32),er,Ze)}}function or(t){return{kind:"group",bytes:f(G(ke.MemberLeft),p(t,"member",32),er,Ze)}}function ir(t,e){return{kind:"group",bytes:f(G(ke.MemberRoleSet),p(t,"member",32),tr(e))}}function tt(t){if(!Number.isInteger(t)||t<0||t>4294967295)throw new Error(`capabilities must be a u32 bit mask, got ${String(t)}`);if(oe(t,T.CAN_AUTHOR_ON_BEHALF))throw new Error("capabilities may not include CAN_AUTHOR_ON_BEHALF (512): a relay never carries a change to it");return{kind:"group",bytes:f(G(ke.DefaultCapabilitiesSet),w(t))}}function sr(t){return{kind:"root",bytes:f(G(et.GroupCreated),p(t.groupId,"groupId",32),p(t.parentId,"parentId",32),G(t.restricted?1:0),p(t.admin,"admin",32))}}function ar(t,e){return{kind:"root",bytes:f(G(et.GroupReparented),p(t,"childGroupId",32),p(e,"newParentId",32))}}function cr(t){return{kind:"root",bytes:f(G(et.GroupDeleted),p(t,"rootGroupId",32),Ze,Ze)}}async function nt(t,e){return m(await v(li,[p(t,"founder",32),p(e,"salt",32)]))}function rt(t){let e=ie(t.credential,"credential");if(e.length===0)throw new Error("credential must be the founder's AccountProof<DeviceCert>, got nothing");return{kind:"root",bytes:f(G(et.NamespaceCreatedV2),p(t.founder,"founder",32),e,p(t.salt,"salt",32))}}var ot=300,X=class extends Error{constructor(n,r,o){super(`relay refused the intent (HTTP ${o}): ${n}`);this.reason=n;this.retryable=r;this.status=o;this.name="IntentRefusedError"}},ui=t=>new Promise(e=>setTimeout(e,t));function di(t){let e=t?.get?.("Retry-After");if(!e)return null;let n=Number.parseInt(e,10);if(Number.isFinite(n)&&n>=0)return n*1e3;let r=Date.parse(e);return Number.isFinite(r)?Math.max(0,r-Date.now()):null}var F=class{constructor(e){this.config=e,this.baseUrl=e.relayUrl.replace(/\/+$/,""),this.executorAccount=e.executorAccount;let n=e.fetch;this.fetchImpl=n?(r,o)=>n(r,o):(r,o)=>globalThis.fetch(r,o),this.timeoutMs=e.timeoutMs??1e4,this.rateLimitRetries=e.rateLimitRetries??3}get relayUrl(){return this.baseUrl}get authorAccount(){return this.config.authorAccount}get authorProof(){return this.config.authorProof}async authorSigner(){return R(this.config.deviceSecret,this.config.signer,"deviceSecret")}async describe(e){let n=await this.json("GET",`/admin-api/contexts/${encodeURIComponent(e)}/intents`);return this.executorAccount=n.data.executorAccount,n.data}async execute(e,n,r={}){let o=this.executorAccount??(await this.describe(e)).executorAccount,i=await this.authorSigner(),a=await this.config.nonces.next(),s=this.config.ttlSeconds??ot,c=await Qe({context:e,authorAccount:this.config.authorAccount,executor:o,method:n,argsJson:r,nonce:a,notAfter:BigInt(Math.floor(Date.now()/1e3))+BigInt(s),signer:i}),u=await this.json("POST",`/admin-api/contexts/${encodeURIComponent(e)}/intents`,{method:n,argsJson:r,warrant:c,authorProof:this.config.authorProof});return{rootHash:u.data.rootHash,returns:u.data.returns??null}}async describeCreation(e,n={}){let r=n.author?`?author=${encodeURIComponent(n.author)}`:"";return(await this.json("GET",`/admin-api/groups/${encodeURIComponent(e)}/context-intents${r}`)).data}async createContext(e){let n=await this.describeCreation(e.groupId,{author:this.config.authorAccount});if(!n.canCreateOnBehalf)throw new X(`the relay (${n.executorAccount}) has no standing to act for members of group ${n.groupId}; an admin must admit it as a relay or grant it CAN_AUTHOR_ON_BEHALF (checked before signing \u2014 no nonce was spent)`,!1,403);if(n.authorMayCreate===!1)throw new X(`the author (${this.config.authorAccount}) may not create contexts in group ${n.groupId}; it needs CAN_CREATE_CONTEXT or admin (checked before signing \u2014 no nonce was spent)`,!1,403);let r=this.checkedExecutor(n.executorAccount),o=e.initArgs??{},i=await this.authorSigner(),a=await this.config.nonces.next(),s=this.config.ttlSeconds??ot,{warrant:c}=await Xe({group:e.groupId,seed:e.seed,authorAccount:this.config.authorAccount,executor:r,applicationId:e.applicationId,serviceName:e.serviceName,name:e.name,initArgs:o,nonce:a,notAfter:BigInt(Math.floor(Date.now()/1e3))+BigInt(s),signer:i}),u=await this.json("POST",`/admin-api/groups/${encodeURIComponent(e.groupId)}/context-intents`,{warrant:c,authorProof:this.config.authorProof,initArgs:o});return{contextId:u.data.contextId,groupId:u.data.groupId,memberPublicKey:u.data.memberPublicKey}}async describeGovernance(e){return(await this.json("GET",`/admin-api/groups/${encodeURIComponent(e)}/governance-intents`)).data}async govern(e){let n=await this.describeGovernance(e.groupId);if(!n.canActOnBehalf)throw new X(`the relay (${n.executorAccount}) has no standing to act for members of group ${n.groupId}; an admin must admit it as a relay or grant it CAN_AUTHOR_ON_BEHALF (checked before signing, no nonce was spent)`,!1,403);let r=this.checkedExecutor(n.executorAccount),o=await this.authorSigner(),i=await this.config.nonces.next(),a=this.config.ttlSeconds??ot,s=await Se({scope:e.groupId,op:e.op,authorAccount:this.config.authorAccount,executor:r,nonce:i,notAfter:BigInt(Math.floor(Date.now()/1e3))+BigInt(a),signer:o});return{groupId:(await this.postGovernance(e.groupId,e.op,s)).groupId}}async foundNamespace(e={}){let n=e.executorAccount?this.checkedExecutor(e.executorAccount):this.executorAccount;if(!n)throw new Error("foundNamespace needs the relay's account: pass executorAccount or configure it (checked before signing, no nonce was spent)");let r=e.salt?m(p(e.salt,"salt",32)):m(crypto.getRandomValues(new Uint8Array(32))),o=await nt(this.config.authorAccount,r),i=rt({founder:this.config.authorAccount,credential:this.config.authorProof,salt:r}),a=e.defaultCapabilities===void 0?void 0:tt(e.defaultCapabilities),s=await this.authorSigner(),c=await this.config.nonces.next(),u=this.config.ttlSeconds??ot,d=await Se({scope:o,op:i,authorAccount:this.config.authorAccount,executor:n,nonce:c,notAfter:BigInt(Math.floor(Date.now()/1e3))+BigInt(u),signer:s}),l=await this.postGovernance(o,i,d),g={namespaceId:l.groupId,salt:r,teeEnabled:l.teeEnabled??!1,...l.teeError?{teeError:l.teeError}:{}};if(!a)return g;try{return await this.govern({groupId:g.namespaceId,op:a}),{...g,defaultCapabilitiesSet:!0}}catch(y){return{...g,defaultCapabilitiesSet:!1,defaultCapabilitiesError:y instanceof Error?y.message:String(y)}}}async postGovernance(e,n,r){return(await this.json("POST",`/admin-api/groups/${encodeURIComponent(e)}/governance-intents`,{warrant:r,authorProof:this.config.authorProof,op:m(n.bytes)})).data}checkedExecutor(e){let n=this.config.executorAccount;if(n&&n.toLowerCase()!==e.toLowerCase())throw new Error(`configured executorAccount ${n} is not the relay's account ${e}; a warrant naming it would be unspendable`);return this.executorAccount=e,e}async json(e,n,r){let o=250;for(let i=0;;i+=1)try{return await this.jsonOnce(e,n,r)}catch(a){if(!(a instanceof k&&a.status===429)||i>=this.rateLimitRetries)throw a;let c=di(a.headers);await ui(c??o),o*=2}}async jsonOnce(e,n,r){let o={Accept:"application/json"};r!==void 0&&(o["Content-Type"]="application/json");let i=new AbortController,a=setTimeout(()=>i.abort(),this.timeoutMs),s;try{s=await this.fetchImpl(`${this.baseUrl}${n}`,{method:e,headers:o,body:r===void 0?void 0:JSON.stringify(r),signal:i.signal})}catch(c){throw new k(0,c instanceof Error?c.name:"NetworkError",`${this.baseUrl}${n}`,new Headers,c instanceof Error?c.message:String(c))}finally{clearTimeout(a)}if(!s.ok){let c=await s.text().catch(()=>"");if(s.status===400||s.status===403){let u=pi(c);throw new X(u,/nonce/i.test(u),s.status)}throw new k(s.status,s.statusText,`${this.baseUrl}${n}`,s.headers,c)}return await s.json()}};function pi(t){if(!t)return"no reason given";try{let e=JSON.parse(t);for(let n of[e.error,e.message])if(typeof n=="string"&&n)return n}catch{}return t}var Z=class{constructor(e,n=null){this.relay=e;this.observer=n;this.kind="relay"}get canSubscribe(){return this.observer!==null}get events(){return this.observer}get client(){return this.relay}async execute(e){let{returns:n}=await this.executeWithMetadata(e);return n}async executeWithMetadata(e){let n=await this.relay.execute(e.contextId,e.method,e.argsJson??{});return{returns:n.returns,transport:"relay",rootHash:n.rootHash}}async migrateMyEntries(e){return this.execute({contextId:e,method:"migrate_my_entries"})}async countMyPending(e){return this.execute({contextId:e,method:"count_my_pending"})}};var gi=new TextEncoder().encode("calimero.auth.login.v1"),lr={webOrigin:0,codeSigningId:1,cli:2};function ur(t){let e=new TextEncoder;switch(t.kind){case"webOrigin":return e.encode(t.origin);case"codeSigningId":return e.encode(t.id);case"cli":return new Uint8Array(0)}}function mi(t){return f(Uint8Array.from([lr[t.kind]]),ur(t))}function hi(t){let e=Uint8Array.from([lr[t.kind]]);if(t.kind==="cli")return e;let n=ur(t);return f(e,w(n.length),n)}async function it(t){let e=p(t.node,"node",32),n=p(t.challenge,"challenge",32),r=p(t.sessionKey,"sessionKey",32),o=await R(t.deviceSecret,t.signer,"deviceSecret"),i=p(o.publicKey,"signer.publicKey",32),a=x(t.issuedAt),s=x(t.expiresAt),c=await v(gi,[e,mi(t.audience),n,r,i,a,s]),u=await o.sign(c);return m(f(e,hi(t.audience),n,r,i,a,s,u))}var fi=300;async function jt(){let t=m(crypto.getRandomValues(new Uint8Array(32)));return{publicKey:m(await ae(t)),secret:t}}async function st(t){let e=t.nodeUrl.replace(/\/+$/,""),n=t.timeoutMs??1e4,r=async(g,y)=>{let A=new AbortController,b=setTimeout(()=>A.abort(),n),I;try{let C={...y,signal:A.signal};I=t.fetch?await t.fetch(`${e}${g}`,C):await globalThis.fetch(`${e}${g}`,C)}catch(C){throw new k(0,C instanceof Error?C.name:"NetworkError",`${e}${g}`,new Headers,C instanceof Error?C.message:String(C))}finally{clearTimeout(b)}let S=await I.text().catch(()=>"");if(!I.ok)throw new k(I.status,I.statusText,`${e}${g}`,I.headers,S);return S?JSON.parse(S):{}},o=await r("/auth/challenge",{method:"GET",headers:{Accept:"application/json"}}),i=o.challenge??o.data?.challenge;if(!i)throw new Error("the node issued no challenge");let a=await jt(),s=Math.floor(Date.now()/1e3),c=await it({node:t.node,audience:t.audience,challenge:i,sessionKey:a.publicKey,issuedAt:s,expiresAt:s+(t.ttlSeconds??fi),signer:await R(t.deviceSecret,t.signer,"deviceSecret")}),u=await r("/auth/token",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({auth_method:"account_proof",public_key:a.publicKey,client_name:t.clientName??e,timestamp:s,provider_data:{challenge:i,login_statement:c,account_proof:t.accountProof}})}),d=u.access_token??u.data?.access_token,l=u.refresh_token??u.data?.refresh_token;if(!d)throw new Error("the node minted no session");return{accessToken:d,refreshToken:l??"",sessionKey:a.publicKey,sessionSecret:a.secret}}var yi=3e4;function at(){let t=globalThis.location?.origin;return t?{kind:"webOrigin",origin:t}:{kind:"cli"}}function bi(t){try{let e=t.split(".");if(e.length!==3)return null;let n=e[1].replace(/-/g,"+").replace(/_/g,"/");for(;n.length%4;)n+="=";let r=JSON.parse(atob(n));return typeof r.exp=="number"?r.exp*1e3:null}catch{return null}}var pe=class{constructor(e){this.session=null;this.sessionExpiresAt=null;this.pending=null;this.sseClient=null;this.wsClient=null;this.config=e}get nodeKey(){return this.config.nodeKey}async accessToken(){let e=Date.now();return this.session&&this.sessionExpiresAt!==null&&this.sessionExpiresAt-yi>e?this.session.accessToken:(this.pending||(this.pending=this.loginNow().finally(()=>{this.pending=null})),(await this.pending).accessToken)}async loginNow(){let e=await st({nodeUrl:this.config.nodeUrl,node:this.config.nodeKey,signer:await this.config.signer(),accountProof:this.config.accountProof,audience:this.config.audience,clientName:this.config.clientName,ttlSeconds:this.config.ttlSeconds,fetch:this.config.fetch,timeoutMs:this.config.timeoutMs});return this.session=e,this.sessionExpiresAt=bi(e.accessToken),e}get events(){return this.sseClient||(this.sseClient=new M({baseUrl:this.config.nodeUrl,getAuthToken:()=>this.accessToken()})),this.sseClient}get ws(){return this.wsClient||(this.wsClient=new B({baseUrl:this.config.nodeUrl,getAuthToken:()=>this.accessToken()})),this.wsClient}close(){this.sseClient?.close(),this.wsClient?.close()}};var L=t=>new TextEncoder().encode(t),wi=L("calimero.auth.request.v1"),Ai=L("calimero.auth.request.body.v1"),Ft="X-Calimero-Proof",xi=300;async function Vt(t){let{method:e,path:n,credential:r}=t;if(!e)throw new Error("signRequestProof needs the method the request will use");if(!n.startsWith("/"))throw new Error(`signRequestProof needs a path, got ${JSON.stringify(n)}`);if(n.includes("?"))throw new Error(`the path must carry no query string, got ${JSON.stringify(n)} \u2014 a query is excluded from the signature on purpose, because a proxy may rewrite one. Anything that must be bound belongs in the body.`);let o=t.body===void 0?new Uint8Array:typeof t.body=="string"?L(t.body):t.body,i=await v(Ai,[o]),a=Math.floor(t.now??Date.now()/1e3),s=a+(t.validForSeconds??xi),c=await v(wi,[L(e),L(n),i,x(a),x(s)]),u=await Ri(c,t);if(u.length!==64)throw new Error(`the signer returned ${u.length} bytes, not a 64-byte signature`);let d=f(w(L(e).length),L(e),w(L(n).length),L(n),i,x(a),x(s),u),l=vi(r,"credential");return m(f(l,new Uint8Array([0]),d))}async function Ri(t,e){if(e.signer)return e.signer.sign(t);if(!e.deviceSecret)throw new Error("signRequestProof needs either `deviceSecret` or `signer`");let n=await se(e.deviceSecret);return new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},n,t))}function vi(t,e){let n=t.trim();if(!/^[0-9a-fA-F]*$/.test(n)||n.length%2!==0)throw new Error(`${e} is not an even-length hex string`);return p(n,e,n.length/2)}function Wt(t){if(!t.credential)throw new Error("a proof authorizer needs the `credential` from signDeviceCert");if(!t.deviceSecret&&!t.signer)throw new Error("a proof authorizer needs either `deviceSecret` or `signer`");return async({method:e,path:n,body:r})=>{let o=await Vt({method:e,path:n,body:r,credential:t.credential,deviceSecret:t.deviceSecret,signer:t.signer,validForSeconds:t.validForSeconds});return{[Ft]:o}}}function Ci(t){return new URL(t).pathname}function zt(t,e){return new Error(`this client was constructed with the relay transport, which has no ${t}: ${e}. Construct a node client (createMeroClient({ baseUrl })) for that surface \u2014 nothing here will silently connect to a node you did not choose.`)}function dr(t){return new Error(`this relay-transport client cannot open ${t}: it was given no relay node key. A relay is an ordinary node and does serve /sse and /ws \u2014 but the login statement must be signed against the node's device signing key, learned out of band (never read from the node, and never derived from its peerId). Pass it as \`observe: { nodeKey }\`. For a cloud-hosted relay the cloud does not publish it yet \u2014 see mdma #312.`)}function Si(t,e){let n=e?.nodeKey;return n?new pe({nodeUrl:e?.nodeUrl??t.relayUrl,nodeKey:n,accountProof:e?.accountProof??t.authorProof,audience:e?.audience??at(),signer:e?.signer?async()=>e.signer:()=>t.authorSigner(),clientName:e?.clientName,ttlSeconds:e?.ttlSeconds,fetch:e?.fetch,timeoutMs:e?.timeoutMs}):null}var ee=class{constructor(e){this.relayObserver=null;this.relayAdmin=null;this.proofAuthorizer=null;this.relayUrl=null;this.proofEvents=null;if(e.transport==="relay"){this.transport="relay",this.nodeClient=null;let o=e.relay instanceof F?e.relay:new F(e.relay);if(this.relayObserver=Si(o,e.observe),this.rpcTransport=new Z(o,this.relayObserver),this.relayUrl=o.relayUrl,e.proof&&(this.proofAuthorizer=Wt(e.proof)),e.session){let i=e.session;this.relayAdmin=xn({baseUrl:o.relayUrl,getAuthToken:typeof i=="string"?async()=>i:i})}else if(this.proofAuthorizer){let i=this.proofAuthorizer;this.relayAdmin=Ge(we({fetch:(a,s)=>globalThis.fetch(a,s),baseUrl:o.relayUrl,authorizeRequest:i}),{baseUrl:o.relayUrl})}return}this.transport="node";let{transport:n,...r}=e;this.nodeClient=new de(r),this.rpcTransport=this.nodeClient.rpc}get rpc(){return this.rpcTransport}get canSubscribe(){return this.rpcTransport.canSubscribe||this.proofAuthorizer!==null}get node(){if(!this.nodeClient)throw zt("node connection","it holds a signing key and a relay URL, not a node");return this.nodeClient}get relay(){if(!(this.rpcTransport instanceof Z))throw new Error("this client was constructed with the node transport and has no relay");return this.rpcTransport.client}get admin(){if(this.nodeClient)return this.nodeClient.admin;if(this.relayAdmin)return this.relayAdmin;throw new Error("this relay-transport client has no admin surface because it was given neither a `proof` nor a `session`. A warrant authorises one intent and is not a credential for reading. The caller-scoped reads (getContexts, listNamespaces) want one of the other two: pass `proof: { credential, deviceSecret }` \u2014 the device cert you already hold, which needs no login and no node key \u2014 or a `session` minted with `login()`. Context STATE reads work through execute/query either way.")}get auth(){return this.node.auth}get events(){if(this.nodeClient)return this.nodeClient.events;if(this.relayObserver)return this.relayObserver.events;if(this.proofAuthorizer&&this.relayUrl)return this.proofEvents??(this.proofEvents=new M({baseUrl:this.relayUrl,authorize:this.proofAuthorizer})),this.proofEvents;throw dr("SSE events")}get ws(){if(this.nodeClient)return this.nodeClient.ws;if(this.relayObserver)return this.relayObserver.ws;throw this.proofAuthorizer?new Error("this client authenticates with a request proof, which cannot open a WebSocket from a browser: `WebSocket` cannot set the X-Calimero-Proof header, and core's guard reads the proof from a header only (the ?token= query parameter is the session equivalent and has no proof counterpart). Use `client.events` \u2014 SSE is fetch-based, carries the header, and is the recommended transport anyway."):dr("WebSocket events")}get ephemeral(){if(!this.nodeClient)throw zt("ephemeral presence","publishing resolves the author from an owned context identity on the node, which a delegated session is not known to have \u2014 read presence off `client.events` instead");return this.nodeClient.ephemeral}get cloud(){if(!this.nodeClient)throw zt("bundled cloud client","a relay client is built from a cloud connection rather than owning one \u2014 reach it through the `cloud` field that `connectCloud` returns, or construct a `CloudClient` directly");return this.nodeClient.cloud}close(){this.nodeClient?.close(),this.relayObserver?.close(),this.proofEvents?.close()}};function pr(t){return new ee(t)}function lt(t=1){let e=BigInt(t);if(e<1n)throw new Error("nonce sequence starts at 1");return{next(){let n=e;return e+=1n,Promise.resolve(n)},advanceTo(n){return n>e&&(e=n),Promise.resolve()}}}function Jt(t,e){let n=e??globalThis.localStorage;if(!n)throw new Error("no localStorage in this runtime: pass a storage implementation, or use createMemoryNonceSource for a process that owns its whole sequence");let r=()=>{let o=n.getItem(t);if(o===null||o==="")return 0n;try{let i=BigInt(o);return i>0n?i:0n}catch{return 0n}};return{next(){let o=r()+1n;return n.setItem(t,o.toString()),Promise.resolve(o)},advanceTo(o){let i=o>0n?o-1n:0n;return i>r()&&n.setItem(t,i.toString()),Promise.resolve()}}}function ki(t){return{getWarrantNonce:(e,n)=>t.client.getWarrantNonceAsAuthor(e,t.authorProof)}}var ct=class extends Error{constructor(n,r){super(`author device ${r} has spent every nonce in context ${n}; it must re-key to write again`);this.contextId=n;this.authorDeviceKey=r;this.name="WarrantNonceExhaustedError"}};function Ei(t){let e=Array.isArray(t.lookups)?t.lookups:[t.lookups];if(e.length===0)throw new Error("a recovering nonce source needs at least one node to ask");let n=t.local??lt(1),r=t.onLookupFailure??"throw",o=null,i=null,a=async()=>{let s=await Promise.allSettled(e.map(d=>d.getWarrantNonce(t.contextId,t.authorDeviceKey))),c=null,u=!1;for(let d of s){if(d.status!=="fulfilled")continue;let l=d.value;if(l.kind==="exhausted"){u=!0;continue}(c===null||l.nextNonce>c)&&(c=l.nextNonce)}if(c===null&&u)throw new ct(t.contextId,t.authorDeviceKey);if(c===null){let d=s.find(g=>g.status==="rejected"),l=d&&d.status==="rejected"?d.reason:void 0;if(r==="local"){o=0n;return}throw l instanceof Error?l:new Error(`no node could answer where the warrant-nonce sequence stands: ${String(l)}`)}o=c,await n.advanceTo?.(c)};return{async next(){o===null&&(i??(i=a().finally(()=>{i=null})),await i);let s=await n.next(),c=o!==null&&o>s?o:s;return o=c+1n,c},async advanceTo(s){(o===null||s>o)&&(o=s),await n.advanceTo?.(s)}}}var Ii="Noise_NK_25519_AESGCM_SHA256",Qt=32,Ti=16,Pi=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,110,4,34,4,32]),Xt=class t{constructor(e){this.k=null;this.n=0;this.ck=e,this.h=e}static async initialize(){let e=new TextEncoder().encode(Ii),n=new Uint8Array(32);return n.set(e),new t(n)}async mixHash(e){this.h=await Ui(f(this.h,e))}async mixKey(e){let[n,r]=await hr(this.ck,e);this.ck=n,this.k=await crypto.subtle.importKey("raw",r,"AES-GCM",!1,["encrypt","decrypt"]),this.n=0}async encryptAndHash(e){if(!this.k)throw new Error("Noise: no cipher key yet");let n=new Uint8Array(await crypto.subtle.encrypt({name:"AES-GCM",iv:mr(this.n),additionalData:this.h},this.k,e));return this.n+=1,await this.mixHash(n),n}async decryptAndHash(e){if(!this.k)throw new Error("Noise: no cipher key yet");let n=new Uint8Array(await crypto.subtle.decrypt({name:"AES-GCM",iv:mr(this.n),additionalData:this.h},this.k,e));return this.n+=1,await this.mixHash(e),n}split(){return hr(this.ck,new Uint8Array)}};async function fr(t,e,n){let r=await Xt.initialize();await r.mixHash(e),await r.mixHash(t);let o=await Di(n);return await r.mixHash(o.publicKey),await r.mixKey(await gr(o.privateKey,t)),{message1:f(o.publicKey,await r.encryptAndHash(new Uint8Array)),async finish(a){if(a.length<Qt+Ti)throw new Error("Noise: message 2 is too short");let s=a.slice(0,Qt);return await r.mixHash(s),await r.mixKey(await gr(o.privateKey,s)),{payload:await r.decryptAndHash(a.slice(Qt)),split:await r.split()}}}}async function Di(t){if(!t){let r;try{r=await crypto.subtle.generateKey({name:"X25519"},!0,["deriveBits"])}catch(i){throw new Error(`Sealed transport needs WebCrypto with X25519, which this runtime lacks (${i?.name??"no crypto.subtle"}). Current browsers and Node have it; in React Native, install react-native-quick-crypto as the global crypto.`)}let o=new Uint8Array(await crypto.subtle.exportKey("raw",r.publicKey));return{privateKey:r.privateKey,publicKey:o}}let e=await crypto.subtle.importKey("pkcs8",f(Pi,t),{name:"X25519"},!0,["deriveBits"]),n=await crypto.subtle.exportKey("jwk",e);return{privateKey:e,publicKey:Ni(n.x)}}async function gr(t,e){let n=await crypto.subtle.importKey("raw",e,{name:"X25519"},!1,[]);return new Uint8Array(await crypto.subtle.deriveBits({name:"X25519",public:n},t,256))}function mr(t){let e=new Uint8Array(12);return new DataView(e.buffer).setBigUint64(4,BigInt(t),!1),e}async function Ui(t){return new Uint8Array(await crypto.subtle.digest("SHA-256",t))}async function Yt(t,e){let n=await crypto.subtle.importKey("raw",t,{name:"HMAC",hash:"SHA-256"},!1,["sign"]);return new Uint8Array(await crypto.subtle.sign("HMAC",n,e))}async function hr(t,e){let n=await Yt(t,e),r=await Yt(n,new Uint8Array([1])),o=await Yt(n,f(r,new Uint8Array([2])));return[r,o]}function Ni(t){let e=t.replace(/-/g,"+").replace(/_/g,"/"),n=atob(e+"=".repeat((4-e.length%4)%4));return Uint8Array.from(n,r=>r.charCodeAt(0))}var Ar="/sealed/v2/handshake",xr="/sealed/v2",Ie="application/vnd.calimero.sealed",Zt=2,Mi=new TextEncoder().encode("calimero/sealed-http/v2"),Ee=16,_i=1+Ee+8,Oi=0,Gi=1,Hi=2,$i=1+64*1024+16,Li=1024,qi=6e4,Ki="calimero.tee-attest.transport-key.v1",Bi=[101,204,205,304],Rr=new TextEncoder,Te=class extends Error{constructor(){super("The node no longer holds the attested transport key; attest again for the current one");this.name="StaleTransportKeyError"}},ge=class extends Error{constructor(n,r,o,i){super(o);this.status=n;this.code=r;this.retryAfterMs=i;this.name="SealedTransportError"}};async function vr(t,e){let n=await crypto.subtle.digest("SHA-256",f(Rr.encode(Ki),t,e));return new Uint8Array(n)}async function Cr(t,e,n={}){if(n.applicationId===void 0!=(n.applicationHash===void 0))throw new Error("applicationId and applicationHash are given together or not at all");let r=m(crypto.getRandomValues(new Uint8Array(32))),o=await t.teeAttest({nonce:r,applicationId:n.applicationId,bindTransportKey:!0,...e.includeCollateral?{includeCollateral:!0}:{}});if(!o.transportPublicKey)throw new Error("The node did not report a transport key; it predates sealed transport");let i=p(o.transportPublicKey,"transportPublicKey",32),a=n.applicationHash?p(n.applicationHash,"applicationHash",32):new Uint8Array(32),s=m(await vr(a,i));if(!await e({quoteB64:o.quoteB64,nonce:r,reportDataSuffix:s,collateral:o.collateral}))throw new Error("The attestation did not verify, so its transport key is not trusted");return i}function Pe(t){let e=t.fetch??((o,i)=>fetch(o,i)),n=`${t.baseUrl.replace(/\/+$/,"")}/admin-api/tee/attest`,r={async teeAttest(o){let i=await e(n,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(o)});if(!i.ok)throw new Error(`The node refused to attest: HTTP ${i.status}`);let a=await i.json();if(!a.data)throw new Error("The attestation response is malformed");return a.data}};return Sr({baseUrl:t.baseUrl,transportPublicKey:()=>Cr(r,t.verify,{applicationId:t.applicationId,applicationHash:t.applicationHash}),fetch:e})}function Sr(t){let e=new URL(t.baseUrl),n=e.pathname.replace(/\/+$/,""),r=`${e.origin}${n}`,o=t.fetch??((l,g)=>fetch(l,g)),i=typeof t.transportPublicKey=="function"?t.transportPublicKey:void 0,a=i?Promise.resolve().then(i):Promise.resolve(t.transportPublicKey);a.catch(()=>{});let s,c=async()=>{try{return await br(o,r,await yr(a))}catch(l){if(!(l instanceof Te)||!i)throw l;return a=Promise.resolve().then(i),br(o,r,await yr(a))}},u=async()=>{let l=s??d(void 0),g=await l;if(Date.now()<g.renewAt)return[g,l];let y=d(l);return[await y,y]},d=l=>{if(s===l){let g=c();s=g,g.catch(()=>{s===g&&(s=void 0)})}return s};return async(l,g)=>{let y=new Request(l,g),A=new URL(y.url);if(A.origin!==e.origin||!A.pathname.startsWith(`${n}/`))throw new Error(`Refusing to send ${A.href} outside the sealed node at ${t.baseUrl}`);let b=[];y.headers.forEach((P,N)=>b.push([N,P]));let I={method:y.method,path:A.pathname.slice(n.length)+A.search,headers:b},S=new Uint8Array(await y.arrayBuffer()),C=async P=>{let{requestId:N,header:W,envelope:z}=await Fi(P,I,S),J=await o(`${r}${xr}`,{method:"POST",headers:{"content-type":Ie},body:z,signal:y.signal});if(J.headers.get("content-type")!==Ie)throw await Er(J);return Wi(J,P.responseKey,W,N)},[q,U]=await u();try{return await C(q)}catch(P){if(!(P instanceof ge)||P.code!=="unknown_session")throw P;return C(await d(U))}}}async function yr(t){let e=await t;if(e.length!==32)throw new Error("transportPublicKey must be 32 bytes");return e}async function br(t,e,n){try{return await wr(t,e,n)}catch(r){if(!(r instanceof ge)||r.code!=="busy")throw r;return await new Promise(o=>setTimeout(o,r.retryAfterMs??1e3)),wr(t,e,n)}}async function wr(t,e,n){let r=await fr(n,Mi),o=await t(`${e}${Ar}`,{method:"POST",headers:{"content-type":Ie},body:f(new Uint8Array([Zt]),n,r.message1)});if(o.headers.get("content-type")!==Ie)throw await Er(o);let i=await Ji(o,Li);return ji(r,i)}async function ji(t,e){if(e[0]!==Zt)throw new Error("The handshake reply is malformed");let n;try{n=await t.finish(e.slice(1))}catch{throw new Error("The handshake reply did not open: it did not come from the attested node")}let{payload:r,split:o}=n;if(r.length!==Ee+4)throw new Error("The handshake reply is malformed");let i=r.slice(0,Ee),a=new DataView(r.buffer,r.byteOffset).getUint32(Ee,!1),[s,c]=await Promise.all([crypto.subtle.importKey("raw",o[0],"AES-GCM",!1,["encrypt"]),crypto.subtle.importKey("raw",o[1],"AES-GCM",!1,["decrypt"])]);return o[0].fill(0),o[1].fill(0),{requestKey:s,responseKey:c,nextRequestId:1,renewAt:Date.now()+a*1e3-qi,header(u){let d=new Uint8Array(_i);return d[0]=Zt,d.set(i,1),new DataView(d.buffer).setBigUint64(1+Ee,BigInt(u),!1),d}}}async function Fi(t,e,n){let r=t.nextRequestId;t.nextRequestId+=1;let o=t.header(r),i=await crypto.subtle.encrypt({name:"AES-GCM",iv:kr(r,0),additionalData:o},t.requestKey,Vi(e,n));return{requestId:r,header:o,envelope:f(o,new Uint8Array(i))}}function kr(t,e){let n=new Uint8Array(12),r=new DataView(n.buffer);return r.setBigUint64(0,BigInt(t),!1),r.setUint32(8,e,!1),n}function Vi(t,e){let n=Rr.encode(JSON.stringify(t)),r=new Uint8Array(4);return new DataView(r.buffer).setUint32(0,n.length,!1),f(r,n,e)}async function Wi(t,e,n,r){if(!t.body)throw new Error("The sealed response has no body");let o=zi(t.body.getReader()),i=0,a=async()=>{let d=await o.next();if(!d)return null;let l;try{l=new Uint8Array(await crypto.subtle.decrypt({name:"AES-GCM",iv:kr(r,i),additionalData:n},e,d))}catch{throw new Error("A sealed response frame did not open: it was not sealed by the attested node")}return i+=1,{kind:l[0],data:l.slice(1)}},s=await a();if(!s||s.kind!==Oi)throw new Error("The sealed response is malformed");let c=JSON.parse(new TextDecoder().decode(s.data));if(Bi.includes(c.status))return await o.cancel(),new Response(null,{status:c.status,headers:c.headers});let u=new ReadableStream({async pull(d){try{let l=await a();l?l.kind===Gi?d.enqueue(l.data):l.kind===Hi?(d.close(),await o.cancel()):d.error(new Error("The sealed response is malformed")):d.error(new Error("The sealed response was cut short"))}catch(l){d.error(l)}},cancel(){return o.cancel()}});return new Response(u,{status:c.status,headers:c.headers})}function zi(t){let e=new Uint8Array,n=async r=>{for(;e.length<r;){let{done:o,value:i}=await t.read();if(o)return!1;e=f(e,i)}return!0};return{async next(){if(!await n(4))return null;let r=new DataView(e.buffer,e.byteOffset).getUint32(0,!1);if(r>$i)throw await t.cancel(),new Error("The sealed response is malformed: a frame is larger than the node sends");if(!await n(4+r))return null;let o=e.slice(4,4+r);return e=e.slice(4+r),o},cancel:()=>t.cancel()}}async function Ji(t,e){if(!t.body)return new Uint8Array;let n=t.body.getReader(),r=new Uint8Array;for(;;){let{done:o,value:i}=await n.read();if(o)return r;if(r=f(r,i),r.length>e)throw await n.cancel(),new Error("The handshake reply is malformed: it is too long")}}async function Er(t){let e,n=`Sealed request refused: HTTP ${t.status}`;try{let i=await t.json();e=i?.error?.code,i?.error?.message&&(n=`Sealed request refused: ${i.error.message}`)}catch{}if(e==="stale_transport_key")return new Te;let r=Number(t.headers.get("retry-after")),o=Number.isFinite(r)&&r>0?Math.min(r,5)*1e3:void 0;return new ge(t.status,e,n,o)}async function Ir(t){if(!t.sessionToken&&!t.googleIdToken)throw new Error("connectCloud needs either a sessionToken or a googleIdToken");let e=await R(t.deviceSecret,t.signer,"deviceSecret"),n=new O({cloudBaseUrl:t.cloudBaseUrl,sessionToken:t.sessionToken,onSession:t.onSession,fetch:t.fetch,timeoutMs:t.timeoutMs});!t.sessionToken&&t.googleIdToken&&await n.signInWithGoogle(t.googleIdToken);let r=await n.getMyNamespaces(),o=Yi(r,t.namespaceId),i=await n.getNamespaceRelays(o.namespaceId),a=Ot(i);if(!a)throw new Error(Xi(o,i));let s=new F({relayUrl:a.relayUrl,executorAccount:a.executorAccount,authorAccount:t.authorAccount,authorProof:t.authorProof,signer:e,nonces:t.nonces??Zi(e.publicKey),ttlSeconds:t.ttlSeconds,fetch:t.seal?Pe({baseUrl:a.relayUrl,verify:t.seal,fetch:t.fetch}):t.fetch,timeoutMs:t.timeoutMs});return{cloud:n,relay:s,namespaceId:o.namespaceId,namespace:o,relayInfo:a,execute:(c,u,d)=>s.execute(c,u,d),client:new ee({transport:"relay",relay:s,observe:{nodeKey:t.relayNodeKey??a.nodeKey,audience:t.observeAudience,fetch:t.fetch,timeoutMs:t.timeoutMs}})}}async function Qi(t){let{root:e,authorAccount:n,...r}=t,o=await R(r.deviceSecret,r.signer,"deviceSecret"),i=await $(e),s=await new O({cloudBaseUrl:t.cloudBaseUrl,onSession:t.onSession,fetch:t.fetch,timeoutMs:t.timeoutMs}).signInWithAccount(i.signer);return Ir({...r,deviceSecret:void 0,signer:o,sessionToken:s.sessionToken,authorAccount:n??i.accountId})}function Yi(t,e){if(e){let n=t.find(r=>r.namespaceId===e);if(!n)throw new Error(`this account owns no namespace ${e}; it owns: ${t.map(r=>r.namespaceId).join(", ")||"(none)"}`);return n}if(t.length===0)throw new Error("this account owns no namespaces in the cloud: claim one first, then enable HA on it so a relay is assigned");if(t.length>1)throw new Error(`this account owns ${t.length} namespaces \u2014 pass namespaceId to say which: ${t.map(n=>n.namespaceId).join(", ")}`);return t[0]}function Xi(t,e){if(e.length===0)return t.haStatus==="enabled"?`namespace ${t.namespaceId} has HA enabled but no relay has been assigned to it yet \u2014 retry shortly`:`namespace ${t.namespaceId} has no relays: enable HA on it in the cloud to have an attested node assigned`;let n=e.filter(o=>o.teeRole!==null&&o.teeRole!=="RelayTee");if(n.length===e.length)return`every node on namespace ${t.namespaceId} is a read-only TEE replica (ReadOnlyTee), which never relays delegated writes: an admin of the namespace must set its TEE admission policy with mode: 'relay' \u2014 AdminClient.setTeeAdmissionPolicy(namespaceId, { ..., mode: 'relay' }) \u2014 so fleet nodes are admitted as RelayTee`;let r=e.filter(o=>o.teeRole===null&&!o.authorshipReady);return r.length>0&&r.length+n.length===e.length?`every relay on namespace ${t.namespaceId} is waiting for the authorship grant: an admin of the namespace must grant CAN_AUTHOR_ON_BEHALF to ${r.map(o=>o.executorAccount??o.peerId).join(", ")||"the relay account"} \u2014 with AdminClient.grantAuthorship(namespaceId, account) for these relays, and AdminClient.openToDelegatedExecution(namespaceId) so relays assigned later need no further op`:`namespace ${t.namespaceId} has ${e.length} relay(s), but none is ready to relay yet (a URL, an executor account and a recent heartbeat) \u2014 retry shortly`}function Zi(t){let e=`mero-js:warrant-nonce:${t}`;try{return Jt(e)}catch{return lt(1)}}var es="https://cloud.calimero.network";function Pr(t){if(!/^[0-9a-f]{64}$/.test(t.accountId))throw new Error("accountId must be 64 lowercase hex characters");let e=new URL(t.cloudWebUrl??es);return e.searchParams.set("link-account",t.accountId),e.searchParams.set("callback-url",t.returnTo),e.toString()}function ts(t){throw window.location.assign(Pr(t)),new Error("redirecting to the cloud to authorise this link")}function ns(t=window.location){let e=new URLSearchParams(t.hash.replace(/^#/,"")),n=e.get("error");if(n)throw Tr(),new Error(n==="denied"?"the account link was declined at the cloud":`the cloud refused this link: ${n}`);let r=e.get("grant"),o=e.get("account");return!r||!o?null:(Tr(),{grant:r,account:o})}function Tr(){typeof history>"u"||!history.replaceState||history.replaceState(null,"",location.pathname+location.search)}async function rs(t){let e=await $(t.root);if(e.accountId!==t.account)throw new Error(`this grant is for account ${t.account}, but the root here derives ${e.accountId} \u2014 it was minted for a different account`);return new O({cloudBaseUrl:t.cloudBaseUrl,fetch:t.fetch}).linkAccountWithGrant({grant:t.grant,signer:e.signer})}var os="enrol-device",is="enrol-kem",ss="callback-url",as="state";function Nr(t){Ur(t.devicePublicKey,"devicePublicKey"),Ur(t.kemPublicKey,"kemPublicKey"),ps(t.returnTo),ds(t.returnTo);let e=new URL(t.walletUrl);return e.searchParams.set(os,t.devicePublicKey),e.searchParams.set(is,t.kemPublicKey),e.searchParams.set(ss,t.returnTo),t.state&&e.searchParams.set(as,t.state),e.toString()}function cs(t){throw window.location.assign(Nr(t)),new Error("redirecting to the wallet to approve this device")}function ls(t=window.location){let e=new URLSearchParams(t.hash.replace(/^#/,"")),n=e.get("error");if(n)throw Dr(),new Error(n==="denied"||n==="cancelled"?"the device was not approved at the wallet":`the wallet refused this enrolment: ${n}`);let r=e.get("credential"),o=e.get("account"),i=e.get("device");if(!r||!o||!i)return null;Dr();let a=e.get("state");return{credential:r,account:o,device:i,...a?{state:a}:{}}}function Dr(){typeof history>"u"||!history.replaceState||history.replaceState(null,"",location.pathname+location.search)}async function us(t){if(t.expectState!==void 0&&t.expectState!==t.state)throw new Error("this enrolment answers a request this app did not make \u2014 the state it carries is not the one sent");let e=await Fe(t.credential);if(e.signPublicKey!==te(t.devicePublicKey))throw new Error(`this credential certifies device key ${e.signPublicKey}, but this app holds ${te(t.devicePublicKey)} \u2014 it would sign with a key the certificate does not cover`);if(t.kemPublicKey!==void 0&&e.kemPublicKey!==te(t.kemPublicKey))throw new Error(`this credential names delivery key ${e.kemPublicKey}, not the one this app asked about \u2014 group keys would be sealed to somebody else`);if(e.account!==te(t.account))throw new Error(`the wallet reported account ${te(t.account)}, but the credential names ${e.account}`);if(e.device!==te(t.device))throw new Error(`the wallet reported device ${te(t.device)}, but the credential names ${e.device}`);return{credential:t.credential,account:e.account,device:e.device,certificate:e}}function Ur(t,e){if(!/^[0-9a-f]{64}$/.test(t))throw new Error(`${e} must be 64 lowercase hex characters`)}function te(t){return t.trim().toLowerCase()}function Mr(t,e){let n=e??(typeof window>"u"?void 0:window.location.origin);if(!n)return!1;try{return new URL(t).origin!==n}catch{return!1}}function ds(t){Mr(t)&&console.warn(`[calimero] enrolling a device but sending the credential to ${new URL(t).origin}, which is not this page's origin. Legitimate when deliberate; worth a second look otherwise.`)}function ps(t){let e;try{e=new URL(t)}catch{throw new Error(`returnTo must be an absolute URL, got ${t}`)}let n=e.hostname==="localhost"||e.hostname==="127.0.0.1"||e.hostname==="[::1]"||e.hostname==="::1";if(e.protocol!=="https:"&&!(e.protocol==="http:"&&n))throw new Error(`returnTo must be https:, or http: on localhost \u2014 got ${e.protocol}//${e.hostname}`)}var gs=/^[0-9a-f]{96}$/,ms=["mrtd","rtmr0","rtmr1","rtmr2","rtmr3"];function en(t){let e=me(t.allowedMrtd??[],"allowedMrtd"),n=(t.allowedMeasurements??[]).map((s,c)=>{let u=`allowedMeasurements[${c}]`;return ms.map(d=>me([s?.[d]??""],`${u}.${d}`)[0]).join()}),r=[me(t.allowedRtmr0??[],"allowedRtmr0"),me(t.allowedRtmr1??[],"allowedRtmr1"),me(t.allowedRtmr2??[],"allowedRtmr2"),me(t.allowedRtmr3??[],"allowedRtmr3")];if(t.allowedMeasurements!==void 0&&n.length===0)throw new Error("allowedMeasurements is empty, so no quote would ever be accepted");if(n.length===0){if(e.length===0)throw new Error("No image is trusted: give allowedMeasurements, or allowedMrtd with allowedRtmr1-3");if(r.slice(1).some(s=>s.length===0))throw new Error("allowedMrtd alone does not name an image: the MRTD measures the TD firmware, which images share, and the image is in RTMR1-3. Give allowedMeasurements, or allowedRtmr1-3 too")}let o=t.allowedTcbStatuses??["UpToDate"],i=t.now??Date.now;return Object.assign(async({quoteB64:s,nonce:c,reportDataSuffix:u,collateral:d})=>{let l=fs(s),g=d??await t.fetchCollateral?.(l);if(!g)throw new Error("The node sent no collateral for its quote, and no fetchCollateral was given to get it");let y;try{y=t.dcapVerify(l,g,Math.floor(i()/1e3))}catch(S){throw new Error(`The quote did not verify: ${S?.message??String(S)}`)}if(y.status==="Revoked"||!o.includes(y.status))throw new Error(`The platform's TCB status is ${y.status}, which is not accepted`);let A=hs(y.report),b=[A.mrTd,A.rtMr0,A.rtMr1,A.rtMr2,A.rtMr3].map(S=>m(S));if(n.length>0&&!n.includes(b.join()))throw new Error(`The measurements (MRTD ${b[0]}, RTMR0-3 ${b.slice(1).join(", ")}) are not an image this verifier trusts`);if(e.length>0&&!e.includes(b[0]))throw new Error(`MRTD ${b[0]} is not an image this verifier trusts`);if([A.rtMr0,A.rtMr1,A.rtMr2,A.rtMr3].forEach((S,C)=>{let q=r[C];if(q.length>0&&!q.includes(m(S)))throw new Error(`RTMR${C} ${m(S)} is not one this verifier trusts`)}),m(A.reportData)!==`${c}${u}`.toLowerCase())throw new Error("The quote does not commit to this nonce and binding");return!0},{includeCollateral:!0})}function me(t,e){return t.map(n=>{let r=n.trim().toLowerCase();if(!gs.test(r))throw new Error(`${e} holds ${JSON.stringify(n)}, which is not a 48-byte hex measurement`);return r})}function hs(t){let e=t.data;if(t.type==="td10"&&e)return e;if(t.type==="td15"&&e?.base)return e.base;throw new Error(`The quote is a ${t.type} quote, not a TDX one`)}function fs(t){let e=atob(t),n=new Uint8Array(e.length);for(let r=0;r<e.length;r+=1)n[r]=e.charCodeAt(r);return n}var ys=["UpToDate","SWHardeningNeeded","ConfigurationNeeded","ConfigurationAndSWHardeningNeeded","OutOfDate","OutOfDateConfigurationNeeded"];function tn(t,{profile:e}){if(t.length===0)throw new Error("No release given, so no image would be trusted");let n,r=t.map((o,i)=>{let a=o?.tag??`releases[${i}]`;if(o?.role!==void 0&&o.role!=="node")throw new Error(`${a} lists the measurements of a ${o.role}, not of a node image`);let s=o?.profiles?.[e];if(!s){let u=Object.keys(o?.profiles??{}).join(", ")||"none";throw new Error(`${a} has no profile ${JSON.stringify(e)} (it has: ${u})`)}let c=(s.allowed_tcb_statuses??["uptodate"]).map(u=>bs(u,a));return n=n===void 0?c:n.filter(u=>c.includes(u)),{mrtd:s.mrtd,rtmr0:s.rtmr0,rtmr1:s.rtmr1,rtmr2:s.rtmr2,rtmr3:s.rtmr3}});if(!n||n.length===0)throw new Error("The releases given accept no TCB status in common");return{allowedMeasurements:r,allowedTcbStatuses:n}}function bs(t,e){let n=ys.find(r=>r.toLowerCase()===String(t).toLowerCase());if(!n)throw new Error(`${e} accepts TCB status ${JSON.stringify(t)}, which this verifier does not know`);return n}var _r=[{uri:"https://fulcio.sigstore.dev",validFor:{start:"2021-03-07T03:20:29Z",end:"2022-12-31T23:59:59.999Z"},certChain:["MIIB+DCCAX6gAwIBAgITNVkDZoCiofPDsy7dfm6geLbuhzAKBggqhkjOPQQDAzAqMRUwEwYDVQQKEwxzaWdzdG9yZS5kZXYxETAPBgNVBAMTCHNpZ3N0b3JlMB4XDTIxMDMwNzAzMjAyOVoXDTMxMDIyMzAzMjAyOVowKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTB2MBAGByqGSM49AgEGBSuBBAAiA2IABLSyA7Ii5k+pNO8ZEWY0ylemWDowOkNa3kL+GZE5Z5GWehL9/A9bRNA3RbrsZ5i0JcastaRL7Sp5fp/jD5dxqc/UdTVnlvS16an+2Yfswe/QuLolRUCrcOE2+2iA5+tzd6NmMGQwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEwHQYDVR0OBBYEFMjFHQBBmiQpMlEk6w2uSu1KBtPsMB8GA1UdIwQYMBaAFMjFHQBBmiQpMlEk6w2uSu1KBtPsMAoGCCqGSM49BAMDA2gAMGUCMH8liWJfMui6vXXBhjDgY4MwslmN/TJxVe/83WrFomwmNf056y1X48F9c4m3a3ozXAIxAKjRay5/aj/jsKKGIkmQatjI8uupHr/+CxFvaJWmpYqNkLDGRU+9orzh5hI2RrcuaQ=="]},{uri:"https://fulcio.sigstore.dev",validFor:{start:"2022-04-13T20:06:15Z"},certChain:["MIICGjCCAaGgAwIBAgIUALnViVfnU0brJasmRkHrn/UnfaQwCgYIKoZIzj0EAwMwKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTAeFw0yMjA0MTMyMDA2MTVaFw0zMTEwMDUxMzU2NThaMDcxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjEeMBwGA1UEAxMVc2lnc3RvcmUtaW50ZXJtZWRpYXRlMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE8RVS/ysH+NOvuDZyPIZtilgUF9NlarYpAd9HP1vBBH1U5CV77LSS7s0ZiH4nE7Hv7ptS6LvvR/STk798LVgMzLlJ4HeIfF3tHSaexLcYpSASr1kS0N/RgBJz/9jWCiXno3sweTAOBgNVHQ8BAf8EBAMCAQYwEwYDVR0lBAwwCgYIKwYBBQUHAwMwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQU39Ppz1YkEZb5qNjpKFWixi4YZD8wHwYDVR0jBBgwFoAUWMAeX5FFpWapesyQoZMi0CrFxfowCgYIKoZIzj0EAwMDZwAwZAIwPCsQK4DYiZYDPIaDi5HFKnfxXx6ASSVmERfsynYBiX2X6SJRnZU84/9DZdnFvvxmAjBOt6QpBlc4J/0DxvkTCqpclvziL6BCCPnjdlIB3Pu3BxsPmygUY7Ii2zbdCdliiow=","MIIB9zCCAXygAwIBAgIUALZNAPFdxHPwjeDloDwyYChAO/4wCgYIKoZIzj0EAwMwKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTAeFw0yMTEwMDcxMzU2NTlaFw0zMTEwMDUxMzU2NThaMCoxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjERMA8GA1UEAxMIc2lnc3RvcmUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAT7XeFT4rb3PQGwS4IajtLk3/OlnpgangaBclYpsYBr5i+4ynB07ceb3LP0OIOZdxexX69c5iVuyJRQ+Hz05yi+UF3uBWAlHpiS5sh0+H2GHE7SXrk1EC5m1Tr19L9gg92jYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRYwB5fkUWlZql6zJChkyLQKsXF+jAfBgNVHSMEGDAWgBRYwB5fkUWlZql6zJChkyLQKsXF+jAKBggqhkjOPQQDAwNpADBmAjEAj1nHeXZp+13NWBNa+EDsDP8G1WWg1tCMWP/WHPqpaVo0jhsweNFZgSs0eE7wYI4qAjEA2WB9ot98sIkoF3vZYdd3/VtWB5b9TNMea7Ix/stJ5TfcLLeABLE4BNJOsQ4vnBHJ"]}],Or=[{baseUrl:"https://rekor.sigstore.dev",logId:"c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d",publicKey:"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE2G2Y+2tabdTV5BcGiBIx0a9fAFwrkBbmLSGtks4L3qX6yYY0zufBnhC8Ur/iy55GhWP/9A/bY2LhC30M9+RYtw==",validFor:{start:"2021-01-12T11:53:27Z"}}];var ws="1.2.840.10045.2.1",As={"1.2.840.10045.3.1.7":"P-256","1.3.132.0.34":"P-384"},xs={"P-256":32,"P-384":48},Rs={"1.2.840.10045.4.3.2":"SHA-256","1.2.840.10045.4.3.3":"SHA-384"};function Gr(t,e,n){if(e+2>n)throw new Error("it is truncated");let r=t[e];if((r&31)===31)throw new Error("it uses a tag this parser does not read");let o=t[e+1],i=e+2;if(o&128){let s=o&127;if(s===0||s>4||i+s>n)throw new Error("it has a length this parser does not read");o=0;for(let c=0;c<s;c+=1)o=o*256+t[i+c];i+=s}let a=i+o;if(a>n)throw new Error("it is truncated");return{tag:r,bytes:t,offset:e,start:i,end:a}}function fe(t){let e=Gr(t,0,t.length);if(e.end!==t.length)throw new Error("it has trailing bytes");return e}function D(t){let e=[];for(let n=t.start;n<t.end;){let r=Gr(t.bytes,n,t.end);e.push(r),n=r.end}return e}function E(t,e,n){if(!t||t.tag!==e)throw new Error(`${n} is not where it should be`);return t}function V(t){return t.bytes.slice(t.start,t.end)}function ut(t){return t.bytes.slice(t.offset,t.end)}function he(t){let e=V(E(t,6,"An object identifier"));if(e.length===0||e[e.length-1]&128)throw new Error("it has a malformed object identifier");let n=[],r=0;for(let a of e)r=r*128+(a&127),a&128||(n.push(r),r=0);let o=n.shift();return[...o<80?[Math.floor(o/40),o%40]:[2,o-80],...n].join(".")}function vs(t){let e=new TextDecoder().decode(V(t)),n=t.tag===23?/^(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})Z$/.exec(e):null,r=t.tag===24?/^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})Z$/.exec(e):null,o=n??r;if(!o)throw new Error(`it holds the time ${JSON.stringify(e)}, which is not one a certificate may hold`);let i=Number(o[1]);n&&(i+=i<50?2e3:1900);let[a,s,c,u,d]=o.slice(2).map(Number);return Date.UTC(i,a-1,s,c,u,d)}function nn(t){try{let[e,n,r,...o]=D(E(fe(t),48,"The certificate"));if(o.length>0)throw new Error("it has fields after its signature");let i=D(E(e,48,"The signed part")),a=i[0]?.tag===160?1:0,[s,c,u,d,l,g,...y]=i.slice(a);E(s,2,"The serial number");let A=he(D(E(n,48,"The signature algorithm"))[0]);if(he(D(E(c,48,"The signature algorithm"))[0])!==A)throw new Error("it names two different signature algorithms");let I=Rs[A];if(!I)throw new Error(`it is signed with ${A}, not ECDSA with SHA-256 or SHA-384`);let[S,C]=D(E(d,48,"The validity")).map(vs);if(C===void 0)throw new Error("its validity is incomplete");let[q,U]=D(E(g,48,"The public key"));E(U,3,"The public key");let[P,N]=D(E(q,48,"The key algorithm"));if(he(P)!==ws)throw new Error("its key is not an elliptic-curve key");let W=As[he(N)];if(!W)throw new Error("its key is on a curve other than P-256 or P-384");let z=new Map,J=y.find(ft=>ft.tag===163);if(J){let[ft]=D(J);for(let po of D(E(ft,48,"The extensions"))){let ne=D(E(po,48,"An extension"));if(ne.length===3)E(ne[1],1,"An extension's critical flag");else if(ne.length!==2)throw new Error("it has a malformed extension");let yt=he(ne[0]);if(z.has(yt))throw new Error(`it has extension ${yt} twice`);z.set(yt,V(E(ne[ne.length-1],4,"An extension value")))}}let mn=V(E(r,3,"The signature"));if(mn[0]!==0)throw new Error("its signature is not a whole number of bytes");return{der:t,tbs:ut(e),signatureHash:I,signature:mn.slice(1),issuer:ut(E(u,48,"The issuer")),subject:ut(E(l,48,"The subject")),notBefore:S,notAfter:C,spki:ut(g),curve:W,extensions:z}}catch(e){throw new Error(`The certificate is malformed: ${e.message}`)}}function Hr(t){return D(E(fe(t),48,"The list")).map(he)}function Cs(t,e){let n=xs[e],r=D(E(fe(t),48,"The signature"));if(r.length!==2)throw new Error("The signature is not an ECDSA signature");let o=new Uint8Array(n*2);return r.forEach((i,a)=>{let s=V(E(i,2,"The signature"));if(s.length===0||s[0]&128)throw new Error("The signature is not an ECDSA signature");for(;s.length>1&&s[0]===0;)s=s.subarray(1);if(s.length>n)throw new Error("The signature is not an ECDSA signature");o.set(s,a*n+n-s.length)}),o}async function dt(t,e,n,r,o){let i;try{i=Cs(r,e)}catch{return!1}let a=await crypto.subtle.importKey("spki",t,{name:"ECDSA",namedCurve:e},!1,["verify"]);return crypto.subtle.verify({name:"ECDSA",hash:n},a,i,o)}function H(t,e){let n=t.replace(/\s+/g,"");if(!/^[A-Za-z0-9+/]*={0,2}$/.test(n)||n.length%4!==0)throw new Error(`${e} is not base64`);let r=atob(n),o=new Uint8Array(r.length);for(let i=0;i<r.length;i+=1)o[i]=r.charCodeAt(i);return o}function rn(t,e){let n=[...t.matchAll(/-----BEGIN CERTIFICATE-----([^-]*)-----END CERTIFICATE-----/g)];if(n.length!==1||t.replace(n[0][0],"").trim()!=="")throw new Error(`${e} is not exactly one PEM certificate`);return H(n[0][1],e)}var Ss="2.5.29.17",ks="2.5.29.37",Es="1.3.6.1.5.5.7.3.3",Is="1.3.6.1.4.1.57264.1.8",Ts="1.3.6.1.4.1.57264.1.1",Ps=134,Ds=12,Us=48,Ns=new TextEncoder,ye=t=>new TextDecoder().decode(t);async function $r(t,e,n,r){let{base64Signature:o,cert:i,rekorBundle:a}=Gs(e),s=a.Payload;if(r!==void 0&&r.trim()!==o.trim())throw new Error("The detached signature is not the one in the bundle");let c=H(o,"The bundle signature"),u=rn(ye(H(i,"The bundle certificate")),"The bundle certificate"),d=nn(u),l=Or.find(C=>C.logId===s.logID.toLowerCase());if(!l)throw new Error(`The bundle names Rekor log ${s.logID}, which the Sigstore trust root does not know`);let g=Ns.encode(`{"body":${JSON.stringify(s.body)},"integratedTime":${s.integratedTime},"logID":${JSON.stringify(s.logID)},"logIndex":${s.logIndex}}`);if(!await dt(H(l.publicKey,"The Rekor key"),"P-256","SHA-256",H(a.SignedEntryTimestamp,"The signed entry timestamp"),g))throw new Error("Rekor's signed entry timestamp does not verify: the log entry, its time or its index was altered");let A=s.integratedTime*1e3;if(!Kr(A,l.validFor))throw new Error(`Rekor log ${l.baseUrl} was not in use at ${De(A)}, when the entry says it was logged`);let b=Hs(s.body),I=m(new Uint8Array(await crypto.subtle.digest("SHA-256",t)));if(b.hash!==I)throw new Error("The file's SHA-256 is not the one Rekor logged: the file is not the one signed");if(!on(H(b.signature,"The logged signature"),c))throw new Error("The bundle's signature is not the one Rekor logged");let S=rn(ye(H(b.publicKey,"The logged certificate")),"The logged certificate");if(!on(S,u))throw new Error("The bundle's certificate is not the one Rekor logged");if(d.curve!=="P-256"||!await dt(d.spki,"P-256","SHA-256",c,t))throw new Error("The signature over the file does not verify with the bundle's certificate");return await Ms(d,A),Os(d,n),{integratedTime:s.integratedTime}}async function Ms(t,e){if(!qr(t,e))throw new Error(`The signing certificate was valid ${De(t.notBefore)} to ${De(t.notAfter)}, not at ${De(e)} when Rekor logged it`);let n=[];for(let r of _r){let o=r.certChain.map(a=>nn(H(a,"A Fulcio certificate")));if(!await Lr(t,o[0]))continue;let i=await _s(o,r.validFor,e);if(!i)return;n.push(`${r.uri} (valid from ${r.validFor.start}): ${i}`)}throw new Error(n.length>0?`The signing certificate's CA is not trusted at ${De(e)}: ${n.join("; ")}`:"The signing certificate was not issued by a Fulcio CA in the Sigstore trust root")}async function _s(t,e,n){if(!Kr(n,e))return"the trust root says it was not issuing certificates then";for(let[r,o]of t.entries()){if(!qr(o,n))return`its certificate ${r} was not valid then`;let i=t[r+1]??o;if(!await Lr(o,i))return`its certificate ${r} is not signed by the next`}}async function Lr(t,e){return on(t.issuer,e.subject)?dt(e.spki,e.curve,t.signatureHash,t.signature,t.tbs):!1}function Os(t,e){let n=t.extensions.get(Ss);if(!n)throw new Error("The signing certificate names no identity");let r=D(E(fe(n),Us,"The subject alternative name")),o=r.filter(u=>u.tag===Ps).map(u=>ye(V(u)));if(o.length!==1||r.length!==1||o[0]!==e.identity)throw new Error(`The release was signed by ${JSON.stringify(o.length===1?o[0]:o)}, not by ${e.identity}`);let i=t.extensions.get(Is),a=t.extensions.get(Ts),s=i?ye(V(E(fe(i),Ds,"The OIDC issuer"))):a?ye(a):void 0;if(s!==e.issuer)throw new Error(`The signing certificate's OIDC issuer is ${s===void 0?"missing":JSON.stringify(s)}, not ${e.issuer}`);let c=t.extensions.get(ks);if(!c||!Hr(c).includes(Es))throw new Error("The signing certificate is not for code signing")}function Gs(t){let e=t;if(typeof e=="string")try{e=JSON.parse(e)}catch{throw new Error("The bundle is not JSON")}let n=e,r=n?.rekorBundle?.Payload;if(!(typeof n?.base64Signature=="string"&&typeof n.cert=="string"&&typeof n.rekorBundle?.SignedEntryTimestamp=="string"&&typeof r?.body=="string"&&typeof r.logID=="string"&&/^[0-9a-fA-F]{64}$/.test(r.logID)&&Number.isSafeInteger(r.integratedTime)&&r.integratedTime>=0&&Number.isSafeInteger(r.logIndex)&&r.logIndex>=0))throw new Error("The bundle is not a cosign bundle with a Rekor entry");return n}function Hs(t){let e;try{e=JSON.parse(ye(H(t,"The logged entry")))}catch{throw new Error("The logged entry is not JSON")}let n=e?.spec?.data?.hash,r=e?.spec?.signature;if(e?.kind!=="hashedrekord"||n?.algorithm!=="sha256"||typeof n.value!="string"||typeof r?.content!="string"||typeof r.publicKey?.content!="string")throw new Error("The logged entry is not a SHA-256 hashedrekord");return{hash:n.value.toLowerCase(),signature:r.content,publicKey:r.publicKey.content}}function qr(t,e){return t.notBefore<=e&&e<=t.notAfter}function Kr(t,e){return Date.parse(e.start)<=t&&(e.end===void 0||t<=Date.parse(e.end))}function De(t){return new Date(t).toISOString()}function on(t,e){return t.length===e.length&&t.every((n,r)=>n===e[r])}var sn=Object.freeze({identity:"https://github.com/calimero-network/mero-tee/.github/workflows/release-node-image-gcp.yaml@refs/heads/master",issuer:"https://token.actions.githubusercontent.com"}),$s=["mrtd","rtmr0","rtmr1","rtmr2","rtmr3"],jr="https://cloud.calimero.network";async function Fr(t,e,n={}){let r=typeof t=="string"?new TextEncoder().encode(t):t;await $r(r,e,{identity:n.identity??sn.identity,issuer:n.issuer??sn.issuer},n.signature);let o;try{o=JSON.parse(new TextDecoder().decode(r))}catch{throw new Error("The signed release is not JSON")}if(o?.role!=="node")throw new Error(`The signed release is a ${JSON.stringify(o?.role)} release, not a node one`);let i=Object.values(o.profiles??{}),a=s=>$s.every(c=>/^[0-9a-f]{96}$/i.test(String(s?.[c])));if(typeof o.tag!="string"||i.length===0||!i.every(a))throw new Error("The signed file is not a release's published-mrtds.json: it lists no measured profiles");if(n.expectedVersion!==void 0&&o.tag!==n.expectedVersion)throw new Error(`The signed release is ${o.tag}, not ${n.expectedVersion}`);return o}async function Vr(t,e={}){let n=await(e.fetch??fetch)(t,{headers:{accept:"application/json"}});if(!n.ok)throw new Error(`Fetching the node release from ${t} failed: HTTP ${n.status}`);let r;try{r=(await n.json())?.data}catch{throw new Error(`${t} did not answer with JSON`)}if(typeof r?.version!="string"||typeof r.publishedMrtds!="string"||typeof r.bundle!="string")throw new Error(`${t} did not answer with a signed node release`);return{version:r.version,publishedMrtds:r.publishedMrtds,bundle:r.bundle}}function Wr(t){let e=/^merotee-.+-(\d+)-(\d+)-(\d+)$/.exec(t);if(!e)throw new Error(`${JSON.stringify(t)} is not the image of a mero-tee node release`);return`${Number(e[1])}.${Number(e[2])}.${Number(e[3])}`}async function zr(t,e={}){let n=await Qr(t,e.fetch??fetch);if(n===void 0)throw new Error(`${Jr(t)} was refused unsealed: the node requires sealing and is too old to name its release before a session exists. Name the release it runs yourself (createSignedReleaseSealedFetch's \`releaseVersion\`), or upgrade the node`);return n}function Jr(t){return`${t.replace(/\/+$/,"")}/admin-api/tee/info`}async function Qr(t,e){let n=Jr(t),r=await e(n,{headers:{accept:"application/json"}});if(r.status===403&&await r.json().then(a=>a?.error?.code).catch(()=>{})==="sealed_required")return;if(!r.ok)throw new Error(`Fetching ${n} failed: HTTP ${r.status}`);let o;try{o=(await r.json())?.data?.osImage}catch{throw new Error(`${n} did not answer with JSON`)}if(typeof o!="string")throw new Error(`${n} did not name the node's image`);return Wr(o)}function Yr(t,e){return`${t.replace(/\/+$/,"")}/api/tee/node-releases/${Ue(e,"version")}`}async function Xr(t){let e=Ue(t.minReleaseVersion,"minReleaseVersion"),n=Ue(t.release?.version,"The release version"),r=await Fr(t.release.publishedMrtds,t.release.bundle,{expectedVersion:n,identity:t.identity,issuer:t.issuer});if(qs(n,e)<0)throw new Error(`Release ${n} is older than the minimum trusted, ${e}`);return tn([r],{profile:t.profile})}function Zr(t){return Ue(t.minReleaseVersion,"minReleaseVersion"),Object.assign(async n=>{let r=await Xr({release:await t.release(),profile:t.profile,minReleaseVersion:t.minReleaseVersion,identity:t.identity,issuer:t.issuer});return en({dcapVerify:t.dcapVerify,fetchCollateral:t.fetchCollateral,now:t.now,...r})(n)},{includeCollateral:!0})}function Ls(t){let{baseUrl:e,releaseSource:n,releaseVersion:r,applicationId:o,applicationHash:i,fetch:a,...s}=t;r!==void 0&&Ue(r,"releaseVersion");let c=a??((d,l)=>fetch(d,l));return Pe({baseUrl:e,verify:Zr({...s,release:async()=>{let d=r===void 0?await zr(e,{fetch:c}):await Qr(e,c)??r;return typeof n=="function"?n({baseUrl:e,version:d,fetch:c}):Vr(Yr(n??jr,d),{fetch:c})}}),applicationId:o,applicationHash:i,fetch:c})}var eo=/^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/;function Ue(t,e){let n=typeof t=="string"?eo.exec(t):null,r=n?.[4];if(!n||r!==void 0&&r.split(".").some(o=>o===""))throw new Error(`${e} is ${JSON.stringify(t)}, not a release version like 2.3.87`);return t}function qs(t,e){let[n,r]=Br(t),[o,i]=Br(e);for(let c=0;c<3;c+=1)if(n[c]!==o[c])return n[c]<o[c]?-1:1;if(r===void 0||i===void 0)return r===i?0:r===void 0?1:-1;let a=r.split("."),s=i.split(".");for(let c=0;c<Math.max(a.length,s.length);c+=1){let[u,d]=[a[c],s[c]];if(u===void 0||d===void 0)return u===void 0?-1:1;let[l,g]=[/^\d+$/.test(u),/^\d+$/.test(d)],y=l&&g?Math.sign(Number(u)-Number(d)):l!==g?l?-1:1:u<d?-1:u>d?1:0;if(y!==0)return y}return 0}function Br(t){let e=eo.exec(t);return[[Number(e[1]),Number(e[2]),Number(e[3])],e[4]]}var pt=1440*60,cn={Admin:0,Member:1,ReadOnly:2};function Ne(t){let e=t.admitters??[];return f(an(t.inviter_identity,"inviter_identity"),an(t.group_id,"group_id"),x(t.expiration_timestamp),an(t.secret_salt,"secret_salt"),new Uint8Array([t.invited_role]),w(e.length),...e.map((n,r)=>p(n,`admitters[${r}]`,32)))}async function ln(t){return new Uint8Array(await crypto.subtle.digest("SHA-256",Ne(t)))}function un(t){return[...new Set(t.filter(n=>n.role==="Admin").map(n=>n.identity.toLowerCase()))].sort()}async function to(t){let e=await R(t.deviceSecret,t.signer,"deviceSecret"),n=p(e.publicKey,"signer.publicKey",32),r=p(t.groupId,"groupId",32);p(t.inviterAccount,"inviterAccount",32);let o=[...t.admitters??[]].map(g=>g.trim().toLowerCase());if(o.length===0){if(!t.members)throw new Error("name the admitters, or pass the group members to default them to its admins: an invitation with no admitters is claimable by broadcast");if(o=un(t.members),o.length===0)throw new Error("the member list names no admin, so there is nobody to default the admitters to")}o.forEach((g,y)=>p(g,`admitters[${y}]`,32));let i=t.invitedRole??cn.Member;if(![0,1,2].includes(i))throw new Error(`invitedRole must be 0 (Admin), 1 (Member) or 2 (ReadOnly), got ${i}`);let a=t.now??Math.floor(Date.now()/1e3),s=Math.min(t.validForSecs??pt,pt);if(!Number.isInteger(s)||s<=0)throw new Error(`validForSecs must be a positive whole number, got ${t.validForSecs}`);let c=t.nonce??crypto.getRandomValues(new Uint8Array(32));if(c.length!==32)throw new Error(`nonce must be 32 bytes, got ${c.length}`);let u={inviter_identity:Array.from(n),group_id:Array.from(r),expiration_timestamp:a+s,secret_salt:Array.from(c),invited_role:i,admitters:o},d=await e.sign(await ln(u));if(d.length!==64)throw new Error(`signer returned ${d.length} bytes, expected a 64-byte Ed25519 signature`);let l={invitation:u,inviter_signature:m(d),inviter_account:t.inviterAccount.trim().toLowerCase()};return t.admitterAddrs?.length&&(l.admitter_addrs=[...t.admitterAddrs]),t.applicationId&&(l.application_id=Array.from(p(t.applicationId,"applicationId",32))),t.appKey&&(l.app_key=Array.from(p(t.appKey,"appKey",32))),l}function an(t,e){if(t.length!==32)throw new Error(`${e} must be 32 bytes, got ${t.length}`);return new Uint8Array(t)}var dn=16,Ks=new TextEncoder().encode("calimero.namespace.v1"),Bs=0,no={GroupCreated:0,GroupReparented:1,GroupDeleted:2,AdminChanged:3,PolicyUpdated:4,MemberJoined:5,KeyDelivery:6,MemberJoinedOpen:7,MemberJoinedAt:8,NamespaceCreatedV2:9,MemberJoinedViaTeeAttestation:10};function ro(t,e){if(t==null)return new Uint8Array([0]);if(t.length!==32)throw new Error(`${e} must be 32 bytes, got ${t.length}`);return f(new Uint8Array([1]),new Uint8Array(t))}function oo(t){let e=new TextEncoder().encode(t);return f(w(e.length),e)}function gt(t){let e=t.invitation,n=t.admitter_addrs??[];return f(Ne(e),oo(t.inviter_signature),t.inviter_account?f(new Uint8Array([1]),p(t.inviter_account,"inviter_account",32)):new Uint8Array([0]),w(n.length),...n.map(oo),ro(t.application_id,"application_id"),ro(t.app_key,"app_key"))}async function io(t){let e=t.parentOpHashes??[],n=p(t.credential,"credential",t.credential.length/2),r=BigInt(t.invitation.invitation.expiration_timestamp??0)!==0n,o=t.joinedAt??BigInt(Math.floor(Date.now()/1e3)),i=r?f(new Uint8Array([no.MemberJoinedAt]),p(t.member,"member",32),gt(t.invitation),x(o),n):f(new Uint8Array([no.MemberJoined]),p(t.member,"member",32),gt(t.invitation),n),a=f(new Uint8Array([Bs]),i),s=await R(t.deviceSecret,t.signer,"deviceSecret"),c=p(s.publicKey,"signer.publicKey",32),u=f(new Uint8Array([dn]),p(t.namespaceId,"namespaceId",32),w(e.length),...e.map((g,y)=>p(g,`parentOpHashes[${y}]`,32)),c,x(t.nonce),a),d=await s.sign(f(Ks,u)),l=new Uint8Array([0]);return m(f(u,d,l))}var so=[2428,2429,2528,2529],js="localhost",Fs=2e3;function ao(t){return`http://${js}:${t}`}function co(t,e){let n=t.endsWith("/")?t:`${t}/`;return new URL(e,n).toString()}async function lo(t,e={}){let{timeoutMs:n=Fs,signal:r}=e;if(r?.aborted)return!1;let o=new AbortController,i=()=>o.abort(),a=r;a&&a.addEventListener("abort",i,{once:!0});let s=setTimeout(()=>o.abort(),n);try{let c=co(t,"admin-api/health"),u=await fetch(c,{method:"GET",signal:o.signal});if(!u.ok)return!1;try{let d=await u.json(),l=d?.data?.status!==void 0?d?.data?.status:d?.status;return l===void 0?!0:typeof l=="string"&&l.toLowerCase()==="alive"}catch{return!0}}catch{return!1}finally{clearTimeout(s),a&&a.removeEventListener("abort",i)}}async function Vs(t={}){let{ports:e=so,timeoutMs:n,signal:r}=t;return(await Promise.all(e.map(async i=>{let a=ao(i);return await lo(a,{timeoutMs:n,signal:r})?a:null}))).filter(i=>i!==null)}var Ws=new TextEncoder().encode("calimero.tee-attest.key-binding.v1"),mt=new TextEncoder().encode("MOCK_TDX_QUOTE_V1"),zs=568;function Js(...t){let e=new Uint8Array(t.reduce((r,o)=>r+o.length,0)),n=0;for(let r of t)e.set(r,n),n+=r.length;return e}function pn(t,e){if(t.length!==e.length)return!1;let n=0;for(let r=0;r<t.length;r+=1)n|=t[r]^e[r];return n===0}function Qs(t){let e=atob(t),n=new Uint8Array(e.length);for(let r=0;r<e.length;r+=1)n[r]=e.charCodeAt(r);return n}function Ys(t,e){if(typeof t!="string"||!/^[0-9a-fA-F]{64}$/.test(t))throw new Error(`${e} must be 64 hex characters`);let n=new Uint8Array(32);for(let r=0;r<32;r+=1)n[r]=Number.parseInt(t.slice(r*2,r*2+2),16);return n}async function ht(t){let e=await crypto.subtle.digest("SHA-256",Js(Ws,new Uint8Array(32),t));return new Uint8Array(e)}function gn(t){let e=t.length>=mt.length&&pn(t.subarray(0,mt.length),mt),n=e?mt.length:zs;if(t.length<n+64)throw new Error(`the quote is too short to carry report data (${t.length} bytes)`);return{reportData:t.slice(n,n+64),mock:e}}async function uo(t){let e=crypto.getRandomValues(new Uint8Array(32)),n=`${t.relayUrl.replace(/\/+$/,"")}/admin-api/tee/attest`,r=JSON.stringify({nonce:m(e),bindNodeKey:!0,...t.verify?.includeCollateral?{includeCollateral:!0}:{}}),o={method:"POST",headers:{"Content-Type":"application/json"},body:r},i=t.fetch?await t.fetch(n,o):await globalThis.fetch(n,o);if(!i.ok){let g=await i.text().catch(()=>"");throw new Error(`the relay would not attest (HTTP ${i.status})${g?`: ${g}`:""}`)}let a=await i.json(),s=a.data??a;if(typeof s.quoteB64!="string")throw new Error("the relay returned no quote");let c=Ys(s.boundPublicKey,"boundPublicKey"),u=Qs(s.quoteB64),{reportData:d,mock:l}=gn(u);if(l){if(!t.allowMock)throw new Error("the relay answered with a MOCK quote, which proves nothing about the hardware")}else if(t.verify){if(!await t.verify({quoteB64:s.quoteB64,nonce:m(e),reportDataSuffix:m(await ht(c)),...s.collateral?{collateral:s.collateral}:{}}))throw new Error("the relay's quote did not verify: not a trusted image, or not bound to this request")}else if(t.verifyQuote)await t.verifyQuote(u);else throw new Error("a real TDX quote needs a verify (or verifyQuote) to check its signature and measurements");if(!pn(d.subarray(0,32),e))throw new Error("the quote does not carry our nonce: it was not made for this request");if(!pn(d.subarray(32,64),await ht(c)))throw new Error("the quote does not bind the key the relay named: refusing it");return{nodeKey:m(c),mock:l}}export{Y as AdminApiClient,Q as AuthApiClient,K as AuthRevokedError,T as CAPABILITIES,ya as CAPABILITY_PRESETS,O as CloudClient,so as DEFAULT_LOCAL_NODE_PORTS,jr as DEFAULT_RELEASE_MIRROR,Re as EphemeralClient,Ar as HANDSHAKE_PATH,k as HTTPError,cn as INVITED_ROLE,X as IntentRefusedError,$t as LocalStorageTokenStore,pt as MAX_INVITATION_VALIDITY_SECS,Ht as MemoryTokenStore,ee as MeroClient,de as MeroJs,sn as NODE_RELEASE_SIGNER,Ft as REQUEST_PROOF_HEADER,F as RelayClient,pe as RelayObserver,Z as RelayTransport,xe as RpcClient,qe as RpcError,Ie as SEALED_CONTENT_TYPE,xr as SEALED_PATH,dn as SIGNED_NAMESPACE_OP_SCHEMA_VERSION,ge as SealedTransportError,M as SseClient,Te as StaleTransportKeyError,ct as WarrantNonceExhaustedError,Oe as WarrantNonceRouteUnavailableError,be as WebHttpClient,B as WsClient,Ve as accountForRoot,_ as accountForRootPublicKey,On as accountRootFromPhrase,Nt as accountRootFromSecret,Hn as accountRootSignerFromPhrase,Vo as admitterAddrsFromNetworkStatus,ht as attestKeyBinding,uo as attestRelayNodeKey,ki as authorNonceLookup,ts as beginCloudLink,cs as beginDeviceEnrolment,kt as buildAuthLoginUrl,Mr as callbackIsForeign,$e as callerProof,ba as capMask,wa as capNames,vt as classifyError,Pr as cloudLinkUrl,Yr as cloudNodeReleaseUrl,bt as combineSignals,So as compareSemver,rs as completeCloudLink,us as completeDeviceEnrolment,Ir as connectCloud,Qi as connectCloudWithAccount,Gn as createAccountRootSigner,xn as createAdminApiClient,Ge as createAdminApiClientFromHttpClient,Pe as createAttestedSealedFetch,ha as createAuthApiClient,fn as createAuthApiClientFromHttpClient,Oa as createBrowserAdminApiClient,ga as createBrowserAuthApiClient,re as createBrowserHttpClient,we as createHttpClient,Jt as createLocalStorageNonceSource,lt as createMemoryNonceSource,pr as createMeroClient,Qo as createMeroJs,Ga as createNodeAdminApiClient,ma as createNodeAuthApiClient,Me as createNodeHttpClient,Wt as createProofAuthorizer,Le as createProofSigner,en as createQuoteVerifier,Ei as createRecoveringNonceSource,bo as createRetryableMethod,Sr as createSealedFetch,Ls as createSignedReleaseSealedFetch,Zr as createSignedReleaseVerifier,wt as createTimeoutSignal,At as createUniversalHttpClient,qt as creationInitHash,un as defaultAdmitters,at as defaultAudience,tt as defaultCapabilitiesSetOp,je as deviceCertPayload,Nr as deviceEnrolmentUrl,Pt as deviceScopePayload,Vs as discoverLocalNodes,Ne as encodeGroupInvitation,gt as encodeSignedInvitation,Cr as fetchAttestedTransportKey,Vr as fetchNodeRelease,zr as fetchNodeReleaseVersion,nt as foundedNamespaceId,_n as generateAccountRoot,jt as generateSessionKey,Kt as governanceOpHash,sr as groupCreatedOp,cr as groupDeletedOp,ln as groupInvitationHash,ar as groupReparentedOp,oe as hasCap,Da as hexEncodeUtf8,Lt as intentHash,Ro as isSettled,Be as jsonCodec,ao as localNodeUrl,st as login,nr as memberAddedOp,or as memberLeftOp,rr as memberRemovedOp,ir as memberRoleSetOp,Pn as mintDeviceId,rt as namespaceCreatedOp,co as nodeEndpoint,Wr as nodeReleaseVersionFromImage,St as parseAuthCallback,Xn as parseCreationWarrant,Tt as parseDeviceCredential,Zn as parseGovernanceWarrant,bn as parseWarrantNonce,lo as probeNodeHealth,ns as readCloudLinkCallback,ls as readEnrolmentCallback,yn as redeemInvitation,gn as reportDataOf,Et as requestBodyHash,$ as resolveRoot,We as resolveRootPair,Je as routingProofHeaders,Ca as shouldRetain,ve as signAccountLink,ze as signAccountLogin,Xe as signCreationWarrant,Un as signDeviceCert,Nn as signDeviceScope,Se as signGovernanceWarrant,to as signGroupInvitation,it as signLoginStatement,io as signMemberJoinOp,He as signRequest,Vt as signRequestProof,zn as signRoutingChallenge,Qe as signWarrant,Ci as signedPath,In as signerFromCryptoKey,ce as signerFromSecret,vr as transportKeyBinding,Xr as trustSignedRelease,tn as trustedMeasurementsFromReleases,Fe as verifyDeviceCredential,Fr as verifySignedNodeRelease,xt as withCap,_e as withRetry,Aa as withoutCap};
3
3
  //# sourceMappingURL=index.browser.mjs.map