@calimero-network/mero-js 23.2.0 → 23.4.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 xt(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 Rt(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 Yo=new Set(["token_reuse","token_revoked"]);function Xo(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=Xo(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:En(this.headers),bodyText:this.bodyText}}},V=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 En(t){let e={};return t.forEach((n,r)=>{e[r]=n}),e}function Zo(t){try{return new URL(t).pathname}catch{let e=t.indexOf("?");return e===-1?t:t.slice(0,e)}}var Re=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:En(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),d=await this.buildHeaders(n?.headers),p;d instanceof Headers?(p={},d.forEach((b,T)=>{p[T]=b})):p=d;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(p,await this.transport.authorizeRequest({method:l,path:new URL(a).pathname,body:b}))}let g={method:l,headers:p},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 x;if(r>0&&o!==void 0){let b=n?.timeoutMs||this.transport.timeoutMs;if(b){let T=Date.now()-s,S=Math.max(0,b-T);x=this.createAbortSignal({...n,timeoutMs:S})}else x=this.createAbortSignal(n)}else x=c;if(x&&(g.signal=x),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:Zo(a),body:g.body});b&&(p["X-Calimero-Proof"]=b)}try{let b=await this.transport.fetch(a,g);if(!b.ok){let T=await this.getBodyText(b),S=new k(b.status,b.statusText,a,b.headers,T),C=b.headers.get("x-auth-error");if((b.status===401||b.status===403)&&C&&Yo.has(C)){if(this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,this.transport.onAuthRevoked)try{await this.transport.onAuthRevoked()}catch{}throw new V(C,b.status,b.statusText,a,b.headers,T)}let F=n?.signal?.aborted===!0;if(b.status===401&&this.transport.refreshToken&&C==="token_expired"&&r<1&&!y&&!F)try{let M=this.refreshTokenPromise;M||(M=this.transport.refreshToken(),this.refreshTokenPromise=M);let D=await M;if(!D||D.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 _=this.onTokenRefreshPromise;_||(_=this.transport.onTokenRefresh(D),this.onTokenRefreshPromise=_),await _,this.refreshTokenPromise=null,this.onTokenRefreshPromise=null;let Z=n?.timeoutMs||this.transport.timeoutMs;if(Z&&o!==void 0){let ee=Date.now()-s;if(Z-ee<=0)throw S}return this.makeRequest(e,n,r+1,s)}catch(M){throw this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,M instanceof Error&&M.message.includes("onTokenRefresh")?M: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(Rt(r)),n.length>0?xt(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 ve(t){return new Re(t)}function ue(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 ve(e)}function $e(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 ve(r)}function vt(t){return typeof window<"u"?ue(t):$e(t)}function ei(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 ti(t){let n=250*Math.pow(2,t-1),r=(Math.random()-.5)*.4*n;return Math.max(0,n+r)}async function He(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,!ei(r,n-o))throw r;let a=ti(o),d=r.headers?.get?.("Retry-After");if(d){let p=parseInt(d,10);if(!isNaN(p))a=Math.max(a,p*1e3);else{let l=new Date(d);if(!isNaN(l.getTime())){let g=Math.max(0,l.getTime()-Date.now());a=Math.max(a,Math.min(g,6e4))}}}await new Promise(p=>setTimeout(p,a))}throw r||new Error("Retry failed without error")}function ni(t,e={}){return async(...n)=>He(()=>t(...n),e)}var ne=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 Ce=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 cc(t){let e=new Ce;return new ne(e)}function lc(t){let e=new Ce;return new ne(e)}function uc(t){let e=new Ce;return new ne(e)}function In(t,e){return new ne(t)}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},pc={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 gc(...t){let e=0;for(let n of t)if(typeof n=="number")e|=n;else if(Object.prototype.hasOwnProperty.call(P,n))e|=P[n];else throw new Error(`unknown capability: ${String(n)}`);return e>>>0}function mc(t){return Object.keys(P).filter(e=>re(t,P[e]))}function re(t,e){let n=e>>>0;return(t&n)>>>0===n}function Ct(t,e){return(t|e)>>>0}function hc(t,e){return(t&~e)>>>0}var ri={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 oi(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 ii(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 St(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 kt(t){let e=ii(t),n;return e!==void 0?n=oi(e):t instanceof TypeError?n="unreachable":n="unknown",{kind:n,status:e,retryable:ri[n],message:St(t)}}function si(t){return t.status!=="failed"||!t.retryable}function wc(t){return!si(t)}function ai(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 ci(t,e){let{kind:n,status:r}=kt(t),o=ai(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 Pn(t,e){let{namespaceId:n,invitation:r,teamName:o}=t,i=null;try{await e.join(n,r)}catch(p){i=p}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=St(i,"Could not join. Check the invitation."),{reason:c,retryable:d}=ci(i,s);return{status:"failed",namespaceId:n,message:s,reason:c,retryable:d}}var Le=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 Et(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 Tn(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:Et(t,n,"highWaterNonce"),windowWidth:Et(t,n,"windowWidth")??0n},o=Et(t,n,"nextNonce");return o===void 0?{...r,kind:"exhausted",seen:!0,highWaterNonce:r.highWaterNonce??0xffffffffffffffffn}:{...r,kind:"open",nextNonce:o}}function f(t){return t?.data}function li(t,e){let[n,r]=Dn(t),[o,i]=Dn(e),a=n.split("."),s=o.split("."),c=Math.max(a.length,s.length);for(let g=0;g<c;g++){let y=Un(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 d=r.split("."),p=i.split("."),l=Math.max(d.length,p.length);for(let g=0;g<l;g++){if(g>=d.length)return-1;if(g>=p.length)return 1;let y=Un(d[g],p[g]);if(y!==0)return y}return 0}function Dn(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 Un(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 ui(t,e,n){return He(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 oe=class{constructor(e){this.httpClient=e}async healthCheck(){return f(await this.httpClient.get("/admin-api/health"))}async readinessCheck(){return f(await this.httpClient.get("/admin-api/ready"))}async isAuthed(){return this.httpClient.get("/admin-api/is-authed")}async installApplication(e){return f(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 ui(r.toString(),"versions",n)).json();return(Array.isArray(i)?i:[]).map(a=>a.appVersion).filter(a=>typeof a=="string").sort((a,s)=>li(s,a))}async installDevApplication(e){return f(await this.httpClient.post("/admin-api/install-dev-application",e))}async uninstallApplication(e){return f(await this.httpClient.delete(`/admin-api/applications/${e}`))}async listApplications(){return f(await this.httpClient.get("/admin-api/applications"))}async getApplication(e){return f(await this.httpClient.get(`/admin-api/applications/${e}`))}async listApplicationVersions(e){return f(await this.httpClient.get(`/admin-api/applications/${e}/versions`))}async getApplicationAbi(e,n){let r=n?`?service_name=${encodeURIComponent(n)}`:"";return f(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 f(await this.httpClient.post("/admin-api/contexts",n))}async deleteContext(e){return f(await this.httpClient.delete(`/admin-api/contexts/${e}`))}async getContexts(){return f(await this.httpClient.get("/admin-api/contexts"))}async getContext(e){return f(await this.httpClient.get(`/admin-api/contexts/${e}`))}async getContextsForApplication(e){return f(await this.httpClient.get(`/admin-api/contexts/for-application/${e}`))}async generateContextIdentity(){return f(await this.httpClient.post("/admin-api/identity/context",{}))}async getContextIdentities(e){return f(await this.httpClient.get(`/admin-api/contexts/${e}/identities`))}async getContextIdentitiesOwned(e){return f(await this.httpClient.get(`/admin-api/contexts/${e}/identities-owned`))}async joinContext(e){return f(await this.httpClient.post(`/admin-api/contexts/${e}/join`,{}))}async getContextGroup(e){return f(await this.httpClient.get(`/admin-api/contexts/${e}/group`))}async getContextStorage(e){return f(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 f(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=f(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:f(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 f(await this.httpClient.post("/admin-api/alias/create/context",{alias:e.alias,contextId:e.contextId}))}async createApplicationAlias(e){return f(await this.httpClient.post("/admin-api/alias/create/application",{alias:e.alias,applicationId:e.applicationId}))}async lookupContextAlias(e){return f(await this.httpClient.post(`/admin-api/alias/lookup/context/${encodeURIComponent(e)}`,{}))}async lookupApplicationAlias(e){return f(await this.httpClient.post(`/admin-api/alias/lookup/application/${encodeURIComponent(e)}`,{}))}async deleteContextAlias(e){return f(await this.httpClient.post(`/admin-api/alias/delete/context/${encodeURIComponent(e)}`,{}))}async deleteApplicationAlias(e){return f(await this.httpClient.post(`/admin-api/alias/delete/application/${encodeURIComponent(e)}`,{}))}async listContextAliases(){return f(await this.httpClient.get("/admin-api/alias/list/context"))}async listApplicationAliases(){return f(await this.httpClient.get("/admin-api/alias/list/application"))}async createDeviceAlias(e){return f(await this.httpClient.post("/admin-api/alias/create/device",{alias:e.alias,deviceId:e.deviceId}))}async lookupDeviceAlias(e){return f(await this.httpClient.post(`/admin-api/alias/lookup/device/${encodeURIComponent(e)}`,{}))}async deleteDeviceAlias(e){return f(await this.httpClient.post(`/admin-api/alias/delete/device/${encodeURIComponent(e)}`,{}))}async listDeviceAliases(){return f(await this.httpClient.get("/admin-api/alias/list/device"))}async listNamespaces(){return f(await this.httpClient.get("/admin-api/namespaces"))}async getNamespace(e){return f(await this.httpClient.get(`/admin-api/namespaces/${e}`))}async getNodeIdentity(){return f(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 f(await this.httpClient.post(`/admin-api/contexts/${e}/intents`,n))}async queryContext(e,n){return f(await this.httpClient.post(`/admin-api/contexts/${e}/query`,n))}async getIntentRelay(e){return f(await this.httpClient.get(`/admin-api/contexts/${e}/intents`))}async listNamespacesForApplication(e){return f(await this.httpClient.get(`/admin-api/namespaces/for-application/${e}`))}async createNamespace(e){return f(await this.httpClient.post("/admin-api/namespaces",e))}async deleteNamespace(e){return f(await this.httpClient.request(`/admin-api/namespaces/${e}`,{method:"DELETE",body:"{}",headers:{"Content-Type":"application/json"}}))}async createNamespaceInvitation(e,n){return f(await this.httpClient.post(`/admin-api/namespaces/${e}/invite`,n??{}))}async admitJoin(e,n){return f(await this.httpClient.post(`/admin-api/namespaces/${e}/admit`,n,{timeoutMs:65e3}))}async joinNamespace(e,n){let r=f(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 Pn({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 f(await this.httpClient.post(`/admin-api/namespaces/${e}/groups`,n??{}))}async listNamespaceGroups(e){return f(await this.httpClient.get(`/admin-api/namespaces/${e}/groups`))}async initAccountPairing(e){return f(await this.httpClient.post("/admin-api/account/pair-init",e))}async completeAccountPairing(e){return f(await this.httpClient.post("/admin-api/account/pair-complete",e))}async relinkAccountDevice(e,n){return f(await this.httpClient.post(`/admin-api/account/devices/${e}/relink`,n??{}))}async rescopeAccountDevice(e,n){return f(await this.httpClient.put(`/admin-api/account/devices/${encodeURIComponent(e)}/scope`,n))}async signWithAccountRoot(e){return f(await this.httpClient.post("/admin-api/account/sign-with-root",e))}async labelAccountDevice(e,n){return f(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 f(await this.httpClient.post(`/admin-api/namespaces/${e}/account/revoke`,n))}async linkAccountDevice(e,n){return f(await this.httpClient.post(`/admin-api/namespaces/${e}/account/link-device`,n))}async getGroupInfo(e){return f(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 f(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 Le(r,i):i}return Tn(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 Le(r,i):i}return Tn(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 f(await this.httpClient.post(`/admin-api/groups/${e}/accounts/${n}/seal`,r))}async listGroupContexts(e){return f(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 f(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(re(n,P.CAN_AUTHOR_ON_BEHALF))return{changed:!1,defaultCapabilities:n};let r=Ct(n,P.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(re(r,P.CAN_AUTHOR_ON_BEHALF))return{changed:!1,capabilities:r};let o=Ct(r,P.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,n={}){let r=`/admin-api/groups/${e}/settings/tee-authoring-policy`;if(n.rootProof===void 0){await this.httpClient.delete(r);return}await this.httpClient.request(r,{method:"DELETE",body:JSON.stringify({rootProof:n.rootProof}),headers:{"Content-Type":"application/json"}})}async transferOwnership(e,n){await this.httpClient.post(`/admin-api/groups/${e}/transfer-ownership`,n)}async changeNamespaceAdmin(e,n){await this.httpClient.post(`/admin-api/namespaces/${e}/admin`,n)}async ownerDeleteGroup(e,n={}){await this.httpClient.post(`/admin-api/groups/${e}/owner-delete`,n)}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 f(await this.httpClient.post(`/admin-api/groups/${e}/sync`,{}))}async upgradeGroup(e,n){return f(await this.httpClient.post(`/admin-api/groups/${e}/upgrade`,n))}async getGroupUpgradeStatus(e){return f(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 f(await this.httpClient.get(`/admin-api/groups/${n}/cascade-status`))}async retryGroupUpgrade(e){return f(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 f(await this.httpClient.post(`/admin-api/groups/${e}/invite`,n??{}))}async joinGroup(e){return f(await this.httpClient.post("/admin-api/groups/join",e))}async joinSubgroupInheritance(e){return f(await this.httpClient.post(`/admin-api/groups/${e}/join-via-inheritance`,{}))}async getTeeInfo(){return f(await this.httpClient.get("/admin-api/tee/info"))}async teeAttest(e){return f(await this.httpClient.post("/admin-api/tee/attest",e))}async teeVerifyQuote(e){return f(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 f(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 kc(t){return Array.from(new TextEncoder().encode(t),e=>e.toString(16).padStart(2,"0")).join("")}function Dc(t){return new oe(ue(t))}function Uc(t){return new oe($e(t))}function On(t){return new oe(vt(t))}function qe(t,e){return new oe(t)}function It(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 Pt(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 Nn=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 h(t){return Array.from(t,e=>e.toString(16).padStart(2,"0")).join("")}function u(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 G(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 A(t){let e=new Uint8Array(8);return new DataView(e.buffer).setBigUint64(0,BigInt(t),!0),e}function m(...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 R(t,e){let n=[A(t.length),t];for(let r of e)n.push(A(r.length),r);return new Uint8Array(await crypto.subtle.digest("SHA-256",m(...n)))}async function W(t){let e=u(t,"deviceSecret",32),n=m(Nn,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 Mn(t,e,n){let r=await crypto.subtle.importKey("raw",u(t,"publicKey",32),{name:"Ed25519"},!1,["verify"]);return crypto.subtle.verify({name:"Ed25519"},r,e,n)}async function J(t){let e=u(t,"deviceSecret",32),n=m(Nn,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 di=new TextEncoder().encode("calimero.auth.request.v1"),pi=new TextEncoder().encode("calimero.auth.request.body.v1");function _n(t){let e=new TextEncoder().encode(t);return m(w(e.length),e)}async function Tt(t=new Uint8Array(0)){let e=typeof t=="string"?new TextEncoder().encode(t):t;return R(pi,[e])}async function Ke(t){let e=await W(t.signerSecret),n=await Tt(t.body),r=A(t.issuedAt),o=A(t.expiresAt),i=new TextEncoder,a=await R(di,[i.encode(t.method),i.encode(t.path),n,r,o]),s=new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},e,a));return h(m(_n(t.method),_n(t.path),n,r,o,s))}function Be(t){let e=G(t.credential,"credential"),n=G(t.request,"request signature"),r=t.session===void 0?new Uint8Array([0]):m(new Uint8Array([1]),G(t.session,"session statement"));return h(m(e,r,n))}function gi(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 je(t){let e=t.ttlSeconds??120,n=t.now??(()=>Math.floor(Date.now()/1e3));return async r=>{let o=n();return Be({credential:t.credential,session:t.session,request:await Ke({method:r.method,path:r.path,body:gi(r.body),issuedAt:o,expiresAt:o+e,signerSecret:t.signerSecret})})}}var Fe=class extends Error{constructor(e,n,r,o){super(n),this.name="RpcError",this.code=e,this.data=r,this.type=o}};async function Dt(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 Fe(o.code??-1,o.message??o.type??"RPC error",o.data,o.type)}return r.result}var Se=class{constructor(e){this.kind="node";this.canSubscribe=!0;this.httpClient=e.httpClient}async execute(e){let n=await Dt(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 mi=new Set(["MigrationStarted","MigrationProgress","CascadeProgress","MigrationCompleted"]);function Gn(t){return t.type!==void 0&&mi.has(t.type)}var hi=new Set(["token_reuse","token_revoked"]),fi=new Set([401,403]);function $n(t){let e=t.headers.get("x-auth-error");return!e||!fi.has(t.status)?null:hi.has(e)?e:null}var $=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=>{Gn(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=$n(n),o=await n.text().catch(()=>{});throw r?new V(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 V)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 d=c.slice(5).trim();d&&this.handleMessage(d)}}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=$n(a),c=await a.text().catch(()=>{});this.emit("error",s?new V(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 Ve=class Ve{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),Ve.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()}};Ve.MAX_BACKOFF_MS=3e4;var z=Ve;function We(){return{encode(t){return Array.from(new TextEncoder().encode(JSON.stringify(t)))},decode(t){return JSON.parse(new TextDecoder().decode(new Uint8Array(t)))}}}var ke=class{constructor(e){this.httpClient=e.httpClient,this.sse=e.sse}async set(e,n,r=We()){await Dt(this.httpClient,"set_ephemeral",{contextId:e,state:r.encode(n)})}subscribe(e,n,r=We()){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,d={author:s.author,state:c||s.state===void 0?void 0:r.decode(s.state),removed:c};s.ageMs!==void 0&&(d.ageMs=s.ageMs),n(d)};return this.sse.on("event",o),this.sse.connect().catch(()=>{}),this.sse.subscribe([e]).catch(()=>{}),()=>{this.sse.off("event",o)}}};var yi=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,112,4,34,4,32]);function Hn(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 de(t,e="secret"){let n=u(t,e,32),r=m(yi,n),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 Hn(a)}return qn(o,i)}async function Ln(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")u(e,"publicKey",32),n=e.trim().toLowerCase();else try{n=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 qn(t,n)}function qn(t,e){return{publicKey:e,async sign(n){try{return new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},t,n))}catch(r){throw Hn(r)}}}}async function v(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 de(t,n);throw new Error(`${n} or signer is required`)}var bi=new TextEncoder().encode("calimero.device.cert.v1"),wi=new TextEncoder().encode("calimero.account.genesis.v1"),Ai=new TextEncoder().encode("calimero.device.id.v1"),pe=2,xi=237;async function Kn(t,e){if(e.length!==16)throw new Error(`nonce must be 16 bytes, got ${e.length}`);let n=u(t,"account",32);return h(await R(Ai,[n,e]))}async function Je(t){return R(bi,[u(t.account,"account",32),u(t.device,"device",32),u(t.signPublicKey,"signPublicKey",32),u(t.kemPublicKey,"kemPublicKey",32),w(t.keyEpoch),w(t.deviceEpoch)])}function Bn(t){return m(new Uint8Array([pe]),t.rootPublicKey,w(0),u(t.account,"account",32),u(t.device,"device",32),u(t.signPublicKey,"signPublicKey",32),u(t.kemPublicKey,"kemPublicKey",32),w(t.keyEpoch),w(t.deviceEpoch),t.signature)}async function jn(t){let e=await v(t.rootSecret,t.signer,"rootSecret"),n=u(e.publicKey,"signer.publicKey",32),r=await H(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=Bn({rootPublicKey:n,account:r,device:t.device,signPublicKey:t.signPublicKey,kemPublicKey:t.kemPublicKey,keyEpoch:o,deviceEpoch:t.deviceEpoch,signature:a});return h(s)}function Ut(t){let e=u(t,"credential",xi);if(e[0]!==pe)throw new Error(`this credential has account genesis version ${e[0]}, not ${pe} \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)=>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:n.getUint32(165,!0),deviceEpoch:n.getUint32(169,!0),signature:o(173,64)}}async function ze(t){let e=Ut(t),n=await H(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 Mn(e.rootPublicKey,u(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 Qe(t){return H(h(await J(t)))}async function H(t){return h(await R(wi,[m(new Uint8Array([pe]),u(t,"rootPublicKey",32))]))}var Ri=new TextEncoder().encode("calimero.device.scope.v1");async function Ot(t){return R(Ri,[u(t.account,"account",32),u(t.device,"device",32),w(t.scopeEpoch),w(t.keyEpoch),...t.applications.map((e,n)=>u(e,`applications[${n}]`,32))])}async function Fn(t){let e=await v(t.rootSecret,t.signer,"rootSecret"),n=u(e.publicKey,"signer.publicKey",32),r=await H(h(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 Ot({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 h(m(new Uint8Array([pe]),n,w(0),u(r,"account",32),u(t.device,"device",32),w(o.length),...o.map((d,p)=>u(d,`applications[${p}]`,32)),w(i),w(a),c))}var Nt=["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 vi=new TextEncoder().encode("calimero.mdma.account-link.v1\0"),Ci=new TextEncoder().encode("calimero.mdma.account-login.v1\0"),ge=256,Vn=ge/32,Mt=(ge+Vn)/11;async function Wn(){let t=crypto.getRandomValues(new Uint8Array(ge/8));return Zn(h(t),await tr(t))}async function Jn(t){let e=er(t);return Zn(h(await nr(e)),e.join(" "))}async function _t(t){return u(t,"secret",32),{secret:t,publicKey:h(await J(t)),accountId:await Qe(t)}}async function zn(){let t=crypto.getRandomValues(new Uint8Array(ge/8)),e=await tr(t);return{...await Yn(t),phrase:e}}async function Qn(t){return Yn(await nr(er(t)))}async function Yn(t){let e=await de(h(t),"rootSecret");return t.fill(0),{publicKey:e.publicKey,accountId:await H(e.publicKey),signer:e}}async function K(t){let e=typeof t=="string"?await de(t,"rootSecret"):t;return Xn(e)}async function Ye(t,e){return Xn(await v(t,e,"rootSecret"))}async function Xn(t){return{signer:t,publicKey:t.publicKey,accountId:await H(t.publicKey)}}async function Ee(t){if(!t.nonce)throw new Error("nonce is required to sign an account link");let n=await(await v(t.rootSecret,t.signer,"rootSecret")).sign(m(vi,new TextEncoder().encode(t.nonce)));return ir(n)}async function Xe(t){if(!t.nonce)throw new Error("nonce is required to sign an account login");let n=await(await v(t.rootSecret,t.signer,"rootSecret")).sign(m(Ci,new TextEncoder().encode(t.nonce)));return ir(n)}async function Zn(t,e){return{...await _t(t),phrase:e}}function er(t){let e=t.normalize("NFKD").toLowerCase().trim().split(/\s+/),n=e[0]===""?0:e.length;if(n!==Mt)throw new Error(`recovery phrase must be ${Mt} words, got ${n}`);return e}async function tr(t){let e=or(t)+await rr(t),n=[];for(let r=0;r<Mt;r+=1){let o=Number.parseInt(e.slice(r*11,r*11+11),2);n.push(Nt[o])}return n.join(" ")}async function nr(t){let e="";for(let r of t){let o=Nt.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(ge/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(ge)!==await rr(n))throw new Error("recovery phrase checksum failed \u2014 check for a mistyped or transposed word");return n}async function rr(t){let e=new Uint8Array(await crypto.subtle.digest("SHA-256",t));return or(e).slice(0,Vn)}function or(t){let e="";for(let n of t)e+=n.toString(2).padStart(8,"0");return e}function ir(t){let e="";for(let n of t)e+=String.fromCharCode(n);return btoa(e)}var Si=new TextEncoder().encode("calimero.mdma.routing-read.v1\0");async function sr(t,e){u(e,"deviceSecret",32);let n=await W(e),r=m(Si,new TextEncoder().encode(t)),o=new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},n,r));return ki(o)}async function Ze(t,e){return{"X-Calimero-Credential":e.credential,"X-Calimero-Nonce":t.nonce,"X-Calimero-Signature":await sr(t.nonce,e.deviceSecret)}}function ki(t){let e="";for(let n of t)e+=String.fromCharCode(n);return btoa(e)}var Ei="https://manager.cloud.calimero.network";function Gt(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 Ht(t){return t.find(e=>e.canExecute&&e.relayUrl!==null&&e.executorAccount!==null)??null}var Ii="x-mdma-session-refresh",Pi="x-mdma-session-expires",L=class{constructor(e={}){this.session=null;this.baseUrl=(e.cloudBaseUrl||Ei).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 K(e),{nonce:o}=await this.getAccountLoginChallenge();return this.submitAccountLogin({rootPublicKey:r,nonce:o,signature:await Xe({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:Gt(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 Ht(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:Gt(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 Ze(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 Ze(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:Gt(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 enableFoundedNamespaceHa(e,n){return this.request("POST",`/api/cloud/me/namespaces/${encodeURIComponent(e)}/enable-ha`,{body:{groups:[],ownership_proof:n}})}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 K(e),{nonce:i}=await this.getAccountLinkChallenge();return this.submitAccountLink({accountId:o,rootPublicKey:r,nonce:i,signature:await Ee({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 Ye(e.rootSecret,e.signer),i=await this.request("POST","/api/cloud/accounts/link",{body:{grant:e.grant,root_public_key:r,signature:await Ee({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(Ii);if(!n||!this.session)return;let r=e.headers.get(Pi),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 Ti(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 Di(t){if(t)return typeof t=="function"?t:je(t)}var Ui="mero-js:token-refresh";function Oi(){let e=globalThis.navigator?.locks;return e&&typeof e.request=="function"?e:null}function Lt(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 me=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=Di(this.config.requestProof);this.httpClient=ue({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=In(this.httpClient,{baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||"",timeoutMs:this.config.timeoutMs}),this.adminClient=qe(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 Se({httpClient:this.httpClient})),this.rpcClient}get events(){return this.sseClient||(this.sseClient=new $({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 ke({httpClient:this.httpClient,sse:this.events})),this.ephemeralClient}get cloud(){return this.cloudClient||(this.cloudClient=new L(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 z({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:Lt(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=Oi();return n?n.request(Ui,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:Lt(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||Lt(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 It(e)}static buildAuthLoginUrl(e,n){return Pt(e,n)}};function Ni(t){return new me(t)}var qt=class{constructor(){this.tokens=null}getTokens(){return this.tokens}setTokens(e){this.tokens=e}clear(){this.tokens=null}},Mi="mero-tokens",Kt=class{constructor(e=Mi){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 _i=new TextEncoder().encode("calimero.warrant.v2"),Gi=new TextEncoder().encode("calimero.warrant.intent.v1"),ar=64,$i="00".repeat(32);async function Bt(t,e){let n=new TextEncoder().encode(JSON.stringify(e));return R(Gi,[new TextEncoder().encode(t),n])}async function et(t){let e=u(t.context,"context",32),n=u(t.authorAccount,"authorAccount",32),r=u(t.executor,"executor",32),o=u(t.appVersion??$i,"appVersion",32),i=Q(t.accountHeads,"accountHeads"),a=Q(t.governanceFloor,"governanceFloor"),s=await v(t.deviceSecret,t.signer,"deviceSecret"),c=u(s.publicKey,"signer.publicKey",32),d=new TextEncoder().encode(t.method),p=await Bt(t.method,t.argsJson),l=A(t.nonce),g=A(t.notAfter),y=await R(_i,[e,n,c,r,o,d,p,A(i.length),...i,A(a.length),...a,l,g]),x=Ie(await s.sign(y));return h(m(e,n,c,r,o,w(d.length),d,p,w(i.length),...i,w(a.length),...a,l,g,x))}function Ie(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 Q(t,e){let n=t??[];if(n.length>ar)throw new Error(`${e} cites ${n.length} heads, over the ${ar} a node accepts`);return n.map((r,o)=>u(r,`${e}[${o}]`,32))}var Hi=new TextEncoder().encode("calimero.context-creation-warrant.v1"),Li=new TextEncoder().encode("calimero.context-creation.init.v1"),tt=256;async function jt(t){let e=new TextEncoder().encode(JSON.stringify(t));return R(Li,[e])}async function qi(t){return R(Hi,[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,A(t.accountHeads.length),...t.accountHeads,A(t.governanceFloor.length),...t.governanceFloor,A(t.nonce),A(t.notAfter)])}async function nt(t){let e=u(t.group,"group",32),n=t.seed===void 0?crypto.getRandomValues(new Uint8Array(32)):u(t.seed,"seed",32),r=u(t.authorAccount,"authorAccount",32),o=u(t.executor,"executor",32),i=u(t.applicationId,"applicationId",32),a=cr(t.serviceName,"serviceName"),s=cr(t.name,"name"),c=Q(t.accountHeads,"accountHeads"),d=Q(t.governanceFloor,"governanceFloor"),p=await v(t.deviceSecret,t.signer,"deviceSecret"),l=u(p.publicKey,"signer.publicKey",32),g=await jt(t.initArgs),y=await qi({group:e,seed:n,authorAccount:r,deviceKey:l,executor:o,applicationId:i,serviceName:a,name:s,initHash:g,accountHeads:c,governanceFloor:d,nonce:t.nonce,notAfter:t.notAfter}),x=Ie(await p.sign(y));return{warrant:h(m(e,n,r,l,o,i,lr(a),lr(s),g,w(c.length),...c,w(d.length),...d,A(t.nonce),A(t.notAfter),x)),seed:h(n)}}function ur(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>tt)throw new Error(`${l} is ${y} bytes, over the ${tt} a node accepts`);return new TextDecoder("utf-8",{fatal:!0}).decode(i(y,l))},d=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},()=>h(i(32,l)))},p={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:d("accountHeads"),governanceFloor:d("governanceFloor"),nonce:s("nonce"),notAfter:s("notAfter"),signature:h(i(64,"signature"))};if(o!==n.length)throw new Error(`creation warrant is ${n.length} bytes but its fields account for ${o}`);return p}function cr(t,e){if(t===void 0)return null;let n=new TextEncoder().encode(t);if(n.length>tt)throw new Error(`${e} is ${n.length} UTF-8 bytes, over the ${tt} a node accepts`);return n}function lr(t){return t===null?new Uint8Array([0]):m(new Uint8Array([1]),w(t.length),t)}var Ki=new TextEncoder().encode("calimero.governance-warrant.v1"),Bi=new TextEncoder().encode("calimero.governance-warrant.op.v1"),ji={group:0,root:1};async function Ft(t){return R(Bi,[new Uint8Array([Vt(t.kind)]),t.bytes])}async function Fi(t){return R(Ki,[t.scope,new Uint8Array([Vt(t.kind)]),t.authorAccount,t.deviceKey,t.executor,t.opHash,A(t.accountHeads.length),...t.accountHeads,A(t.governanceFloor.length),...t.governanceFloor,A(t.nonce),A(t.notAfter)])}async function Pe(t){let e=u(t.scope,"scope",32),n=u(t.authorAccount,"authorAccount",32),r=u(t.executor,"executor",32),o=Q(t.accountHeads,"accountHeads"),i=Q(t.governanceFloor,"governanceFloor"),a=Vt(t.op.kind),s=await v(t.deviceSecret,t.signer,"deviceSecret"),c=u(s.publicKey,"signer.publicKey",32),d=await Ft(t.op),p=await Fi({scope:e,kind:t.op.kind,authorAccount:n,deviceKey:c,executor:r,opHash:d,accountHeads:o,governanceFloor:i,nonce:t.nonce,notAfter:t.notAfter}),l=Ie(await s.sign(p));return h(m(e,new Uint8Array([a]),n,c,r,d,w(o.length),...o,w(i.length),...i,A(t.nonce),A(t.notAfter),l))}function dr(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},()=>h(i(32,l)))},d=()=>{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)`)},p={scope:h(i(32,"scope")),kind:d(),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!==n.length)throw new Error(`governance warrant is ${n.length} bytes but its fields account for ${o}`);return p}function Vt(t){let e=ji[t];if(e===void 0)throw new Error(`op kind must be 'group' or 'root', got ${String(t)}`);return e}var Vi={Admin:0,Member:1,ReadOnly:2},N={MemberAdded:1,MemberRemoved:2,MemberLeft:3,MemberRoleSet:4,MemberCapabilitySet:5,DefaultCapabilitiesSet:6,ContextDetached:9,SubgroupVisibilitySet:10,GroupMetadataSet:11,MemberMetadataSet:12,ContextMetadataSet:13,ContextCapabilityGranted:16,ContextCapabilityRevoked:17},Te={GroupCreated:0,GroupReparented:1,GroupDeleted:2,MemberJoinedOpen:7,NamespaceCreatedV2:9},Wi=new TextEncoder().encode("calimero.namespace.id.v1"),pr=new Uint8Array(32),rt=w(0);function gr(t){let e=Vi[t];if(e===void 0)throw new Error(`role must be Admin, Member or ReadOnly, got ${String(t)}`);return new Uint8Array([e])}function E(t){return new Uint8Array([t])}function mr(t,e){return{kind:"group",bytes:m(E(N.MemberAdded),u(t,"member",32),gr(e))}}function hr(t){return{kind:"group",bytes:m(E(N.MemberRemoved),u(t,"member",32),pr,rt)}}function fr(t){return{kind:"group",bytes:m(E(N.MemberLeft),u(t,"member",32),pr,rt)}}function yr(t,e){return{kind:"group",bytes:m(E(N.MemberRoleSet),u(t,"member",32),gr(e))}}var Ji=new TextEncoder().encode("calimero.subgroup.id.v1");async function Jt(t,e,n,r){return h(await R(Ji,[u(t,"admin",32),u(e,"parentId",32),new Uint8Array([n?1:0]),u(r,"salt",32)]))}function ot(t){if(!Number.isInteger(t)||t<0||t>4294967295)throw new Error(`capabilities must be a u32 bit mask, got ${String(t)}`);if(re(t,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:m(E(N.DefaultCapabilitiesSet),w(t))}}function zt(t){return{kind:"root",bytes:m(E(Te.GroupCreated),u(t.groupId,"groupId",32),u(t.parentId,"parentId",32),E(t.restricted?1:0),u(t.admin,"admin",32),u(t.salt,"salt",32))}}async function br(t){let e=t.salt??h(crypto.getRandomValues(new Uint8Array(32))),n=await Jt(t.admin,t.parentId,t.restricted,e);return{groupId:n,salt:e,op:zt({...t,groupId:n,salt:e})}}function wr(t,e){return{kind:"root",bytes:m(E(Te.GroupReparented),u(t,"childGroupId",32),u(e,"newParentId",32))}}function Ar(t){return{kind:"root",bytes:m(E(Te.GroupDeleted),u(t,"rootGroupId",32),rt,rt)}}async function it(t,e){return h(await R(Wi,[u(t,"founder",32),u(e,"salt",32)]))}function st(t){let e=G(t.credential,"credential");if(e.length===0)throw new Error("credential must be the founder's AccountProof<DeviceCert>, got nothing");return{kind:"root",bytes:m(E(Te.NamespaceCreatedV2),u(t.founder,"founder",32),e,u(t.salt,"salt",32))}}function Wt(t){let e=new TextEncoder().encode(t);return m(w(e.length),e)}function Qt(t){return t===void 0?E(0):m(E(1),Wt(t))}function Yt(t={}){let e=new TextEncoder,n=Object.entries(t).map(([r,o])=>[e.encode(r),o,r]).sort(([r],[o])=>{for(let i=0;i<Math.min(r.length,o.length);i++)if(r[i]!==o[i])return r[i]-o[i];return r.length-o.length});return m(w(n.length),...n.flatMap(([,r,o])=>[Wt(o),Wt(r)]))}function zi(t,e){if(!Number.isInteger(t)||t<0||t>4294967295)throw new Error(`${e} must be a u32 bit mask, got ${String(t)}`);if(re(t,P.CAN_AUTHOR_ON_BEHALF))throw new Error(`${e} may not include CAN_AUTHOR_ON_BEHALF (512): a relay never carries a change to it`);return t}function xr(t,e){return{kind:"group",bytes:m(E(N.MemberCapabilitySet),u(t,"member",32),w(zi(e,"capabilities")))}}function Rr(t){return{kind:"group",bytes:m(E(N.ContextDetached),u(t,"contextId",32))}}function vr(t){if(t!=="open"&&t!=="restricted")throw new Error(`mode must be open or restricted, got ${String(t)}`);return{kind:"group",bytes:m(E(N.SubgroupVisibilitySet),E(t==="open"?0:1))}}function Cr(t={}){return{kind:"group",bytes:m(E(N.GroupMetadataSet),Qt(t.name),Yt(t.data))}}function Sr(t,e={}){return{kind:"group",bytes:m(E(N.MemberMetadataSet),u(t,"member",32),Qt(e.name),Yt(e.data))}}function kr(t,e={}){return{kind:"group",bytes:m(E(N.ContextMetadataSet),u(t,"contextId",32),Qt(e.name),Yt(e.data))}}function Er(t){if(!Number.isInteger(t)||t<1||t>255)throw new Error(`capability must be a non-zero u8, got ${String(t)}`);return E(t)}function Ir(t,e,n){return{kind:"group",bytes:m(E(N.ContextCapabilityGranted),u(t,"contextId",32),u(e,"member",32),Er(n))}}function Pr(t,e,n){return{kind:"group",bytes:m(E(N.ContextCapabilityRevoked),u(t,"contextId",32),u(e,"member",32),Er(n))}}function Tr(t){return{kind:"root",bytes:m(E(Te.MemberJoinedOpen),u(t.member,"member",32),u(t.groupId,"groupId",32),G(t.credential,"credential"))}}var at=300,ie=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"}},Qi=t=>new Promise(e=>setTimeout(e,t));function Yi(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 Y=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 v(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??at,c=await et({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}),d=await this.json("POST",`/admin-api/contexts/${encodeURIComponent(e)}/intents`,{method:n,argsJson:r,warrant:c,authorProof:this.config.authorProof});return{rootHash:d.data.rootHash,returns:d.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 ie(`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 ie(`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??at,{warrant:c}=await nt({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}),d=await this.json("POST",`/admin-api/groups/${encodeURIComponent(e.groupId)}/context-intents`,{warrant:c,authorProof:this.config.authorProof,initArgs:o});return{contextId:d.data.contextId,groupId:d.data.groupId,memberPublicKey:d.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 ie(`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??at,s=await Pe({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?h(u(e.salt,"salt",32)):h(crypto.getRandomValues(new Uint8Array(32))),o=await it(this.config.authorAccount,r),i=st({founder:this.config.authorAccount,credential:this.config.authorProof,salt:r}),a=e.defaultCapabilities===void 0?void 0:ot(e.defaultCapabilities),s=await this.authorSigner(),c=await this.config.nonces.next(),d=this.config.ttlSeconds??at,p=await Pe({scope:o,op:i,authorAccount:this.config.authorAccount,executor:n,nonce:c,notAfter:BigInt(Math.floor(Date.now()/1e3))+BigInt(d),signer:s}),l=await this.postGovernance(o,i,p),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:h(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=Yi(a.headers);await Qi(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 d=Xi(c);throw new ie(d,/nonce/i.test(d),s.status)}throw new k(s.status,s.statusText,`${this.baseUrl}${n}`,s.headers,c)}return await s.json()}};function Xi(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 se=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 Zi=new TextEncoder().encode("calimero.auth.login.v1"),Dr={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 es(t){return m(Uint8Array.from([Dr[t.kind]]),Ur(t))}function ts(t){let e=Uint8Array.from([Dr[t.kind]]);if(t.kind==="cli")return e;let n=Ur(t);return m(e,w(n.length),n)}async function ct(t){let e=u(t.node,"node",32),n=u(t.challenge,"challenge",32),r=u(t.sessionKey,"sessionKey",32),o=await v(t.deviceSecret,t.signer,"deviceSecret"),i=u(o.publicKey,"signer.publicKey",32),a=A(t.issuedAt),s=A(t.expiresAt),c=await R(Zi,[e,es(t.audience),n,r,i,a,s]),d=await o.sign(c);return h(m(e,ts(t.audience),n,r,i,a,s,d))}var ns=300;async function Xt(){let t=h(crypto.getRandomValues(new Uint8Array(32)));return{publicKey:h(await J(t)),secret:t}}async function lt(t){let e=t.nodeUrl.replace(/\/+$/,""),n=t.timeoutMs??1e4,r=async(g,y)=>{let x=new AbortController,b=setTimeout(()=>x.abort(),n),T;try{let C={...y,signal:x.signal};T=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 T.text().catch(()=>"");if(!T.ok)throw new k(T.status,T.statusText,`${e}${g}`,T.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 Xt(),s=Math.floor(Date.now()/1e3),c=await ct({node:t.node,audience:t.audience,challenge:i,sessionKey:a.publicKey,issuedAt:s,expiresAt:s+(t.ttlSeconds??ns),signer:await v(t.deviceSecret,t.signer,"deviceSecret")}),d=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}})}),p=d.access_token??d.data?.access_token,l=d.refresh_token??d.data?.refresh_token;if(!p)throw new Error("the node minted no session");return{accessToken:p,refreshToken:l??"",sessionKey:a.publicKey,sessionSecret:a.secret}}var rs=3e4;function ut(){let t=globalThis.location?.origin;return t?{kind:"webOrigin",origin:t}:{kind:"cli"}}function os(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 he=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-rs>e?this.session.accessToken:(this.pending||(this.pending=this.loginNow().finally(()=>{this.pending=null})),(await this.pending).accessToken)}async loginNow(){let e=await lt({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=os(e.accessToken),e}get events(){return this.sseClient||(this.sseClient=new $({baseUrl:this.config.nodeUrl,getAuthToken:()=>this.accessToken()})),this.sseClient}get ws(){return this.wsClient||(this.wsClient=new z({baseUrl:this.config.nodeUrl,getAuthToken:()=>this.accessToken()})),this.wsClient}close(){this.sseClient?.close(),this.wsClient?.close()}};var B=t=>new TextEncoder().encode(t),is=B("calimero.auth.request.v1"),ss=B("calimero.auth.request.body.v1"),Zt="X-Calimero-Proof",as=300;async function en(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"?B(t.body):t.body,i=await R(ss,[o]),a=Math.floor(t.now??Date.now()/1e3),s=a+(t.validForSeconds??as),c=await R(is,[B(e),B(n),i,A(a),A(s)]),d=await cs(c,t);if(d.length!==64)throw new Error(`the signer returned ${d.length} bytes, not a 64-byte signature`);let p=m(w(B(e).length),B(e),w(B(n).length),B(n),i,A(a),A(s),d),l=ls(r,"credential");return h(m(l,new Uint8Array([0]),p))}async function cs(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 W(e.deviceSecret);return new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},n,t))}function ls(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 u(n,e,n.length/2)}function tn(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 en({method:e,path:n,body:r,credential:t.credential,deviceSecret:t.deviceSecret,signer:t.signer,validForSeconds:t.validForSeconds});return{[Zt]:o}}}function us(t){return new URL(t).pathname}function nn(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 Or(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 ds(t,e){let n=e?.nodeKey;return n?new he({nodeUrl:e?.nodeUrl??t.relayUrl,nodeKey:n,accountProof:e?.accountProof??t.authorProof,audience:e?.audience??ut(),signer:e?.signer?async()=>e.signer:()=>t.authorSigner(),clientName:e?.clientName,ttlSeconds:e?.ttlSeconds,fetch:e?.fetch,timeoutMs:e?.timeoutMs}):null}var ae=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 Y?e.relay:new Y(e.relay);if(this.relayObserver=ds(o,e.observe),this.rpcTransport=new se(o,this.relayObserver),this.relayUrl=o.relayUrl,e.proof&&(this.proofAuthorizer=tn(e.proof)),e.session){let i=e.session;this.relayAdmin=On({baseUrl:o.relayUrl,getAuthToken:typeof i=="string"?async()=>i:i})}else if(this.proofAuthorizer){let i=this.proofAuthorizer;this.relayAdmin=qe(ve({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 me(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 nn("node connection","it holds a signing key and a relay URL, not a node");return this.nodeClient}get relay(){if(!(this.rpcTransport instanceof se))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 $({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 nn("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 nn("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 Nr(t){return new ae(t)}function pt(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 rn(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 ps(t){return{getWarrantNonce:(e,n)=>t.client.getWarrantNonceAsAuthor(e,t.authorProof)}}var dt=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 gs(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??pt(1),r=t.onLookupFailure??"throw",o=null,i=null,a=async()=>{let s=await Promise.allSettled(e.map(p=>p.getWarrantNonce(t.contextId,t.authorDeviceKey))),c=null,d=!1;for(let p of s){if(p.status!=="fulfilled")continue;let l=p.value;if(l.kind==="exhausted"){d=!0;continue}(c===null||l.nextNonce>c)&&(c=l.nextNonce)}if(c===null&&d)throw new dt(t.contextId,t.authorDeviceKey);if(c===null){let p=s.find(g=>g.status==="rejected"),l=p&&p.status==="rejected"?p.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 ms="Noise_NK_25519_AESGCM_SHA256",on=32,hs=16,fs=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,110,4,34,4,32]),an=class t{constructor(e){this.k=null;this.n=0;this.ck=e,this.h=e}static async initialize(){let e=new TextEncoder().encode(ms),n=new Uint8Array(32);return n.set(e),new t(n)}async mixHash(e){this.h=await bs(m(this.h,e))}async mixKey(e){let[n,r]=await Gr(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:_r(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:_r(this.n),additionalData:this.h},this.k,e));return this.n+=1,await this.mixHash(e),n}split(){return Gr(this.ck,new Uint8Array)}};async function $r(t,e,n){let r=await an.initialize();await r.mixHash(e),await r.mixHash(t);let o=await ys(n);return await r.mixHash(o.publicKey),await r.mixKey(await Mr(o.privateKey,t)),{message1:m(o.publicKey,await r.encryptAndHash(new Uint8Array)),async finish(a){if(a.length<on+hs)throw new Error("Noise: message 2 is too short");let s=a.slice(0,on);return await r.mixHash(s),await r.mixKey(await Mr(o.privateKey,s)),{payload:await r.decryptAndHash(a.slice(on)),split:await r.split()}}}}async function ys(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",m(fs,t),{name:"X25519"},!0,["deriveBits"]),n=await crypto.subtle.exportKey("jwk",e);return{privateKey:e,publicKey:ws(n.x)}}async function Mr(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 _r(t){let e=new Uint8Array(12);return new DataView(e.buffer).setBigUint64(4,BigInt(t),!1),e}async function bs(t){return new Uint8Array(await crypto.subtle.digest("SHA-256",t))}async function sn(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 Gr(t,e){let n=await sn(t,e),r=await sn(n,new Uint8Array([1])),o=await sn(n,m(r,new Uint8Array([2])));return[r,o]}function ws(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 Kr="/sealed/v2/handshake",Br="/sealed/v2",Ue="application/vnd.calimero.sealed",cn=2,As=new TextEncoder().encode("calimero/sealed-http/v2"),De=16,xs=1+De+8,Rs=0,vs=1,Cs=2,Ss=1+64*1024+16,ks=1024,Es=6e4,Is="calimero.tee-attest.transport-key.v1",Ps=[101,204,205,304],jr=new TextEncoder,Oe=class extends Error{constructor(){super("The node no longer holds the attested transport key; attest again for the current one");this.name="StaleTransportKeyError"}},fe=class extends Error{constructor(n,r,o,i){super(o);this.status=n;this.code=r;this.retryAfterMs=i;this.name="SealedTransportError"}};async function Fr(t,e){let n=await crypto.subtle.digest("SHA-256",m(jr.encode(Is),t,e));return new Uint8Array(n)}async function Vr(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=h(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=u(o.transportPublicKey,"transportPublicKey",32),a=n.applicationHash?u(n.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 Ne(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 Wr({baseUrl:t.baseUrl,transportPublicKey:()=>Vr(r,t.verify,{applicationId:t.applicationId,applicationHash:t.applicationHash}),fetch:e})}function Wr(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 Lr(o,r,await Hr(a))}catch(l){if(!(l instanceof Oe)||!i)throw l;return a=Promise.resolve().then(i),Lr(o,r,await Hr(a))}},d=async()=>{let l=s??p(void 0),g=await l;if(Date.now()<g.renewAt)return[g,l];let y=p(l);return[await y,y]},p=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),x=new URL(y.url);if(x.origin!==e.origin||!x.pathname.startsWith(`${n}/`))throw new Error(`Refusing to send ${x.href} outside the sealed node at ${t.baseUrl}`);let b=[];y.headers.forEach((D,_)=>b.push([_,D]));let T={method:y.method,path:x.pathname.slice(n.length)+x.search,headers:b},S=new Uint8Array(await y.arrayBuffer()),C=async D=>{let{requestId:_,header:Z,envelope:ee}=await Ds(D,T,S),te=await o(`${r}${Br}`,{method:"POST",headers:{"content-type":Ue},body:ee,signal:y.signal});if(te.headers.get("content-type")!==Ue)throw await zr(te);return Os(te,D.responseKey,Z,_)},[F,M]=await d();try{return await C(F)}catch(D){if(!(D instanceof fe)||D.code!=="unknown_session")throw D;return C(await p(M))}}}async function Hr(t){let e=await t;if(e.length!==32)throw new Error("transportPublicKey must be 32 bytes");return e}async function Lr(t,e,n){try{return await qr(t,e,n)}catch(r){if(!(r instanceof fe)||r.code!=="busy")throw r;return await new Promise(o=>setTimeout(o,r.retryAfterMs??1e3)),qr(t,e,n)}}async function qr(t,e,n){let r=await $r(n,As),o=await t(`${e}${Kr}`,{method:"POST",headers:{"content-type":Ue},body:m(new Uint8Array([cn]),n,r.message1)});if(o.headers.get("content-type")!==Ue)throw await zr(o);let i=await Ms(o,ks);return Ts(r,i)}async function Ts(t,e){if(e[0]!==cn)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!==De+4)throw new Error("The handshake reply is malformed");let i=r.slice(0,De),a=new DataView(r.buffer,r.byteOffset).getUint32(De,!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-Es,header(d){let p=new Uint8Array(xs);return p[0]=cn,p.set(i,1),new DataView(p.buffer).setBigUint64(1+De,BigInt(d),!1),p}}}async function Ds(t,e,n){let r=t.nextRequestId;t.nextRequestId+=1;let o=t.header(r),i=await crypto.subtle.encrypt({name:"AES-GCM",iv:Jr(r,0),additionalData:o},t.requestKey,Us(e,n));return{requestId:r,header:o,envelope:m(o,new Uint8Array(i))}}function Jr(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 Us(t,e){let n=jr.encode(JSON.stringify(t)),r=new Uint8Array(4);return new DataView(r.buffer).setUint32(0,n.length,!1),m(r,n,e)}async function Os(t,e,n,r){if(!t.body)throw new Error("The sealed response has no body");let o=Ns(t.body.getReader()),i=0,a=async()=>{let p=await o.next();if(!p)return null;let l;try{l=new Uint8Array(await crypto.subtle.decrypt({name:"AES-GCM",iv:Jr(r,i),additionalData:n},e,p))}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!==Rs)throw new Error("The sealed response is malformed");let c=JSON.parse(new TextDecoder().decode(s.data));if(Ps.includes(c.status))return await o.cancel(),new Response(null,{status:c.status,headers:c.headers});let d=new ReadableStream({async pull(p){try{let l=await a();l?l.kind===vs?p.enqueue(l.data):l.kind===Cs?(p.close(),await o.cancel()):p.error(new Error("The sealed response is malformed")):p.error(new Error("The sealed response was cut short"))}catch(l){p.error(l)}},cancel(){return o.cancel()}});return new Response(d,{status:c.status,headers:c.headers})}function Ns(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=m(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>Ss)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 Ms(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=m(r,i),r.length>e)throw await n.cancel(),new Error("The handshake reply is malformed: it is too long")}}async function zr(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 Oe;let r=Number(t.headers.get("retry-after")),o=Number.isFinite(r)&&r>0?Math.min(r,5)*1e3:void 0;return new fe(t.status,e,n,o)}async function Qr(t){if(!t.sessionToken&&!t.googleIdToken)throw new Error("connectCloud needs either a sessionToken or a googleIdToken");let e=await v(t.deviceSecret,t.signer,"deviceSecret"),n=new L({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=Gs(r,t.namespaceId),i=await n.getNamespaceRelays(o.namespaceId),a=Ht(i);if(!a)throw new Error($s(o,i));let s=new Y({relayUrl:a.relayUrl,executorAccount:a.executorAccount,authorAccount:t.authorAccount,authorProof:t.authorProof,signer:e,nonces:t.nonces??Hs(e.publicKey),ttlSeconds:t.ttlSeconds,fetch:t.seal?Ne({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,d,p)=>s.execute(c,d,p),client:new ae({transport:"relay",relay:s,observe:{nodeKey:t.relayNodeKey??a.nodeKey,audience:t.observeAudience,fetch:t.fetch,timeoutMs:t.timeoutMs}})}}async function _s(t){let{root:e,authorAccount:n,...r}=t,o=await v(r.deviceSecret,r.signer,"deviceSecret"),i=await K(e),s=await new L({cloudBaseUrl:t.cloudBaseUrl,onSession:t.onSession,fetch:t.fetch,timeoutMs:t.timeoutMs}).signInWithAccount(i.signer);return Qr({...r,deviceSecret:void 0,signer:o,sessionToken:s.sessionToken,authorAccount:n??i.accountId})}function Gs(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 $s(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 Hs(t){let e=`mero-js:warrant-nonce:${t}`;try{return rn(e)}catch{return pt(1)}}var Ls="https://cloud.calimero.network";function Xr(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??Ls);return e.searchParams.set("link-account",t.accountId),e.searchParams.set("callback-url",t.returnTo),e.toString()}function qs(t){throw window.location.assign(Xr(t)),new Error("redirecting to the cloud to authorise this link")}function Ks(t=window.location){let e=new URLSearchParams(t.hash.replace(/^#/,"")),n=e.get("error");if(n)throw Yr(),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:(Yr(),{grant:r,account:o})}function Yr(){typeof history>"u"||!history.replaceState||history.replaceState(null,"",location.pathname+location.search)}async function Bs(t){let e=await K(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 L({cloudBaseUrl:t.cloudBaseUrl,fetch:t.fetch}).linkAccountWithGrant({grant:t.grant,signer:e.signer})}var js="enrol-device",Fs="enrol-kem",Vs="callback-url",Ws="state";function to(t){eo(t.devicePublicKey,"devicePublicKey"),eo(t.kemPublicKey,"kemPublicKey"),Xs(t.returnTo),Ys(t.returnTo);let e=new URL(t.walletUrl);return e.searchParams.set(js,t.devicePublicKey),e.searchParams.set(Fs,t.kemPublicKey),e.searchParams.set(Vs,t.returnTo),t.state&&e.searchParams.set(Ws,t.state),e.toString()}function Js(t){throw window.location.assign(to(t)),new Error("redirecting to the wallet to approve this device")}function zs(t=window.location){let e=new URLSearchParams(t.hash.replace(/^#/,"")),n=e.get("error");if(n)throw Zr(),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;Zr();let a=e.get("state");return{credential:r,account:o,device:i,...a?{state:a}:{}}}function Zr(){typeof history>"u"||!history.replaceState||history.replaceState(null,"",location.pathname+location.search)}async function Qs(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 ze(t.credential);if(e.signPublicKey!==ce(t.devicePublicKey))throw new Error(`this credential certifies device key ${e.signPublicKey}, but this app holds ${ce(t.devicePublicKey)} \u2014 it would sign with a key the certificate does not cover`);if(t.kemPublicKey!==void 0&&e.kemPublicKey!==ce(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!==ce(t.account))throw new Error(`the wallet reported account ${ce(t.account)}, but the credential names ${e.account}`);if(e.device!==ce(t.device))throw new Error(`the wallet reported device ${ce(t.device)}, but the credential names ${e.device}`);return{credential:t.credential,account:e.account,device:e.device,certificate:e}}function eo(t,e){if(!/^[0-9a-f]{64}$/.test(t))throw new Error(`${e} must be 64 lowercase hex characters`)}function ce(t){return t.trim().toLowerCase()}function no(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 Ys(t){no(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 Xs(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 Zs=new TextEncoder().encode("calimero.mdma.account-ownership-claim.v1\0"),ea=6e4,ro=5*6e4;function oo(t){let e="";for(let n of t)e+=String.fromCharCode(n);return btoa(e)}var ln=(t,e)=>{if(!/^[0-9a-fA-F]{64}$/.test(t))throw new Error(`${e} must be 64 hex characters`);return t.toLowerCase()};async function ta(t){let e=t.ttlMs??ea;if(!(e>0&&e<=ro))throw new Error(`ttlMs must be in (0, ${ro}]`);if(!t.subject)throw new Error("subject must be the cloud login email");let n=await v(t.deviceSecret,t.signer,"deviceSecret"),r=(t.now??Date.now)(),o=Array.from(crypto.getRandomValues(new Uint8Array(16)),s=>s.toString(16).padStart(2,"0")).join(""),i=new TextEncoder().encode(JSON.stringify({v:1,audience:"mdma:enable-ha-namespace",group_id:ln(t.namespaceId,"namespaceId"),account_id:ln(t.accountId,"accountId"),salt:ln(t.salt,"salt"),subject:t.subject,nonce:o,issued_at_ms:r,expires_at_ms:r+e})),a=await n.sign(m(Zs,i));return{kind:"account",credential:t.credential,signed_payload:oo(i),signature:oo(a)}}var na=/^[0-9a-f]{96}$/,ra=["mrtd","rtmr0","rtmr1","rtmr2","rtmr3"];function un(t){let e=ye(t.allowedMrtd??[],"allowedMrtd"),n=(t.allowedMeasurements??[]).map((s,c)=>{let d=`allowedMeasurements[${c}]`;return ra.map(p=>ye([s?.[p]??""],`${d}.${p}`)[0]).join()}),r=[ye(t.allowedRtmr0??[],"allowedRtmr0"),ye(t.allowedRtmr1??[],"allowedRtmr1"),ye(t.allowedRtmr2??[],"allowedRtmr2"),ye(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:d,collateral:p})=>{let l=ia(s),g=p??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 x=oa(y.report),b=[x.mrTd,x.rtMr0,x.rtMr1,x.rtMr2,x.rtMr3].map(S=>h(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([x.rtMr0,x.rtMr1,x.rtMr2,x.rtMr3].forEach((S,C)=>{let F=r[C];if(F.length>0&&!F.includes(h(S)))throw new Error(`RTMR${C} ${h(S)} is not one this verifier trusts`)}),h(x.reportData)!==`${c}${d}`.toLowerCase())throw new Error("The quote does not commit to this nonce and binding");return!0},{includeCollateral:!0})}function ye(t,e){return t.map(n=>{let r=n.trim().toLowerCase();if(!na.test(r))throw new Error(`${e} holds ${JSON.stringify(n)}, which is not a 48-byte hex measurement`);return r})}function oa(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 ia(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 sa=["UpToDate","SWHardeningNeeded","ConfigurationNeeded","ConfigurationAndSWHardeningNeeded","OutOfDate","OutOfDateConfigurationNeeded"];function dn(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 d=Object.keys(o?.profiles??{}).join(", ")||"none";throw new Error(`${a} has no profile ${JSON.stringify(e)} (it has: ${d})`)}let c=(s.allowed_tcb_statuses??["uptodate"]).map(d=>aa(d,a));return n=n===void 0?c:n.filter(d=>c.includes(d)),{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 aa(t,e){let n=sa.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 io=[{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"]}],so=[{baseUrl:"https://rekor.sigstore.dev",logId:"c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d",publicKey:"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE2G2Y+2tabdTV5BcGiBIx0a9fAFwrkBbmLSGtks4L3qX6yYY0zufBnhC8Ur/iy55GhWP/9A/bY2LhC30M9+RYtw==",validFor:{start:"2021-01-12T11:53:27Z"}}];var ca="1.2.840.10045.2.1",la={"1.2.840.10045.3.1.7":"P-256","1.3.132.0.34":"P-384"},ua={"P-256":32,"P-384":48},da={"1.2.840.10045.4.3.2":"SHA-256","1.2.840.10045.4.3.3":"SHA-384"};function ao(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 we(t){let e=ao(t,0,t.length);if(e.end!==t.length)throw new Error("it has trailing bytes");return e}function U(t){let e=[];for(let n=t.start;n<t.end;){let r=ao(t.bytes,n,t.end);e.push(r),n=r.end}return e}function I(t,e,n){if(!t||t.tag!==e)throw new Error(`${n} is not where it should be`);return t}function X(t){return t.bytes.slice(t.start,t.end)}function gt(t){return t.bytes.slice(t.offset,t.end)}function be(t){let e=X(I(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 pa(t){let e=new TextDecoder().decode(X(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,d,p]=o.slice(2).map(Number);return Date.UTC(i,a-1,s,c,d,p)}function pn(t){try{let[e,n,r,...o]=U(I(we(t),48,"The certificate"));if(o.length>0)throw new Error("it has fields after its signature");let i=U(I(e,48,"The signed part")),a=i[0]?.tag===160?1:0,[s,c,d,p,l,g,...y]=i.slice(a);I(s,2,"The serial number");let x=be(U(I(n,48,"The signature algorithm"))[0]);if(be(U(I(c,48,"The signature algorithm"))[0])!==x)throw new Error("it names two different signature algorithms");let T=da[x];if(!T)throw new Error(`it is signed with ${x}, not ECDSA with SHA-256 or SHA-384`);let[S,C]=U(I(p,48,"The validity")).map(pa);if(C===void 0)throw new Error("its validity is incomplete");let[F,M]=U(I(g,48,"The public key"));I(M,3,"The public key");let[D,_]=U(I(F,48,"The key algorithm"));if(be(D)!==ca)throw new Error("its key is not an elliptic-curve key");let Z=la[be(_)];if(!Z)throw new Error("its key is on a curve other than P-256 or P-384");let ee=new Map,te=y.find(wt=>wt.tag===163);if(te){let[wt]=U(te);for(let Qo of U(I(wt,48,"The extensions"))){let le=U(I(Qo,48,"An extension"));if(le.length===3)I(le[1],1,"An extension's critical flag");else if(le.length!==2)throw new Error("it has a malformed extension");let At=be(le[0]);if(ee.has(At))throw new Error(`it has extension ${At} twice`);ee.set(At,X(I(le[le.length-1],4,"An extension value")))}}let kn=X(I(r,3,"The signature"));if(kn[0]!==0)throw new Error("its signature is not a whole number of bytes");return{der:t,tbs:gt(e),signatureHash:T,signature:kn.slice(1),issuer:gt(I(d,48,"The issuer")),subject:gt(I(l,48,"The subject")),notBefore:S,notAfter:C,spki:gt(g),curve:Z,extensions:ee}}catch(e){throw new Error(`The certificate is malformed: ${e.message}`)}}function co(t){return U(I(we(t),48,"The list")).map(be)}function ga(t,e){let n=ua[e],r=U(I(we(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=X(I(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 mt(t,e,n,r,o){let i;try{i=ga(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 q(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 gn(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 q(n[0][1],e)}var ma="2.5.29.17",ha="2.5.29.37",fa="1.3.6.1.5.5.7.3.3",ya="1.3.6.1.4.1.57264.1.8",ba="1.3.6.1.4.1.57264.1.1",wa=134,Aa=12,xa=48,Ra=new TextEncoder,Ae=t=>new TextDecoder().decode(t);async function lo(t,e,n,r){let{base64Signature:o,cert:i,rekorBundle:a}=ka(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=q(o,"The bundle signature"),d=gn(Ae(q(i,"The bundle certificate")),"The bundle certificate"),p=pn(d),l=so.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=Ra.encode(`{"body":${JSON.stringify(s.body)},"integratedTime":${s.integratedTime},"logID":${JSON.stringify(s.logID)},"logIndex":${s.logIndex}}`);if(!await mt(q(l.publicKey,"The Rekor key"),"P-256","SHA-256",q(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 x=s.integratedTime*1e3;if(!go(x,l.validFor))throw new Error(`Rekor log ${l.baseUrl} was not in use at ${Me(x)}, when the entry says it was logged`);let b=Ea(s.body),T=h(new Uint8Array(await crypto.subtle.digest("SHA-256",t)));if(b.hash!==T)throw new Error("The file's SHA-256 is not the one Rekor logged: the file is not the one signed");if(!mn(q(b.signature,"The logged signature"),c))throw new Error("The bundle's signature is not the one Rekor logged");let S=gn(Ae(q(b.publicKey,"The logged certificate")),"The logged certificate");if(!mn(S,d))throw new Error("The bundle's certificate is not the one Rekor logged");if(p.curve!=="P-256"||!await mt(p.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 va(p,x),Sa(p,n),{integratedTime:s.integratedTime}}async function va(t,e){if(!po(t,e))throw new Error(`The signing certificate was valid ${Me(t.notBefore)} to ${Me(t.notAfter)}, not at ${Me(e)} when Rekor logged it`);let n=[];for(let r of io){let o=r.certChain.map(a=>pn(q(a,"A Fulcio certificate")));if(!await uo(t,o[0]))continue;let i=await Ca(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 ${Me(e)}: ${n.join("; ")}`:"The signing certificate was not issued by a Fulcio CA in the Sigstore trust root")}async function Ca(t,e,n){if(!go(n,e))return"the trust root says it was not issuing certificates then";for(let[r,o]of t.entries()){if(!po(o,n))return`its certificate ${r} was not valid then`;let i=t[r+1]??o;if(!await uo(o,i))return`its certificate ${r} is not signed by the next`}}async function uo(t,e){return mn(t.issuer,e.subject)?mt(e.spki,e.curve,t.signatureHash,t.signature,t.tbs):!1}function Sa(t,e){let n=t.extensions.get(ma);if(!n)throw new Error("The signing certificate names no identity");let r=U(I(we(n),xa,"The subject alternative name")),o=r.filter(d=>d.tag===wa).map(d=>Ae(X(d)));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(ya),a=t.extensions.get(ba),s=i?Ae(X(I(we(i),Aa,"The OIDC issuer"))):a?Ae(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(ha);if(!c||!co(c).includes(fa))throw new Error("The signing certificate is not for code signing")}function ka(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 Ea(t){let e;try{e=JSON.parse(Ae(q(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 po(t,e){return t.notBefore<=e&&e<=t.notAfter}function go(t,e){return Date.parse(e.start)<=t&&(e.end===void 0||t<=Date.parse(e.end))}function Me(t){return new Date(t).toISOString()}function mn(t,e){return t.length===e.length&&t.every((n,r)=>n===e[r])}var hn=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"}),Ia=["mrtd","rtmr0","rtmr1","rtmr2","rtmr3"],ho="https://cloud.calimero.network";async function fo(t,e,n={}){let r=typeof t=="string"?new TextEncoder().encode(t):t;await lo(r,e,{identity:n.identity??hn.identity,issuer:n.issuer??hn.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=>Ia.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 yo(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 bo(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 wo(t,e={}){let n=await xo(t,e.fetch??fetch);if(n===void 0)throw new Error(`${Ao(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 Ao(t){return`${t.replace(/\/+$/,"")}/admin-api/tee/info`}async function xo(t,e){let n=Ao(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 bo(o)}function Ro(t,e){return`${t.replace(/\/+$/,"")}/api/tee/node-releases/${_e(e,"version")}`}async function vo(t){let e=_e(t.minReleaseVersion,"minReleaseVersion"),n=_e(t.release?.version,"The release version"),r=await fo(t.release.publishedMrtds,t.release.bundle,{expectedVersion:n,identity:t.identity,issuer:t.issuer});if(Ta(n,e)<0)throw new Error(`Release ${n} is older than the minimum trusted, ${e}`);return dn([r],{profile:t.profile})}function Co(t){return _e(t.minReleaseVersion,"minReleaseVersion"),Object.assign(async n=>{let r=await vo({release:await t.release(),profile:t.profile,minReleaseVersion:t.minReleaseVersion,identity:t.identity,issuer:t.issuer});return un({dcapVerify:t.dcapVerify,fetchCollateral:t.fetchCollateral,now:t.now,...r})(n)},{includeCollateral:!0})}function Pa(t){let{baseUrl:e,releaseSource:n,releaseVersion:r,applicationId:o,applicationHash:i,fetch:a,...s}=t;r!==void 0&&_e(r,"releaseVersion");let c=a??((p,l)=>fetch(p,l));return Ne({baseUrl:e,verify:Co({...s,release:async()=>{let p=r===void 0?await wo(e,{fetch:c}):await xo(e,c)??r;return typeof n=="function"?n({baseUrl:e,version:p,fetch:c}):yo(Ro(n??ho,p),{fetch:c})}}),applicationId:o,applicationHash:i,fetch:c})}var So=/^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/;function _e(t,e){let n=typeof t=="string"?So.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 Ta(t,e){let[n,r]=mo(t),[o,i]=mo(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[d,p]=[a[c],s[c]];if(d===void 0||p===void 0)return d===void 0?-1:1;let[l,g]=[/^\d+$/.test(d),/^\d+$/.test(p)],y=l&&g?Math.sign(Number(d)-Number(p)):l!==g?l?-1:1:d<p?-1:d>p?1:0;if(y!==0)return y}return 0}function mo(t){let e=So.exec(t);return[[Number(e[1]),Number(e[2]),Number(e[3])],e[4]]}var ht=1440*60,yn={Admin:0,Member:1,ReadOnly:2};function Ge(t){let e=t.admitters??[];return m(fn(t.inviter_identity,"inviter_identity"),fn(t.group_id,"group_id"),A(t.expiration_timestamp),fn(t.secret_salt,"secret_salt"),new Uint8Array([t.invited_role]),w(e.length),...e.map((n,r)=>u(n,`admitters[${r}]`,32)))}async function bn(t){return new Uint8Array(await crypto.subtle.digest("SHA-256",Ge(t)))}function wn(t){return[...new Set(t.filter(n=>n.role==="Admin").map(n=>n.identity.toLowerCase()))].sort()}async function ko(t){let e=await v(t.deviceSecret,t.signer,"deviceSecret"),n=u(e.publicKey,"signer.publicKey",32),r=u(t.groupId,"groupId",32);u(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=wn(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)=>u(g,`admitters[${y}]`,32));let i=t.invitedRole??yn.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??ht,ht);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 d={inviter_identity:Array.from(n),group_id:Array.from(r),expiration_timestamp:a+s,secret_salt:Array.from(c),invited_role:i,admitters:o},p=await e.sign(await bn(d));if(p.length!==64)throw new Error(`signer returned ${p.length} bytes, expected a 64-byte Ed25519 signature`);let l={invitation:d,inviter_signature:h(p),inviter_account:t.inviterAccount.trim().toLowerCase()};return t.admitterAddrs?.length&&(l.admitter_addrs=[...t.admitterAddrs]),t.applicationId&&(l.application_id=Array.from(u(t.applicationId,"applicationId",32))),t.appKey&&(l.app_key=Array.from(u(t.appKey,"appKey",32))),l}function fn(t,e){if(t.length!==32)throw new Error(`${e} must be 32 bytes, got ${t.length}`);return new Uint8Array(t)}var An=20,Da=new TextEncoder().encode("calimero.namespace.v1"),Ua=0,Eo={GroupCreated:0,GroupReparented:1,GroupDeleted:2,AdminChanged:3,PolicyUpdated:4,MemberJoined:5,KeyDelivery:6,MemberJoinedOpen:7,MemberJoinedAt:8,NamespaceCreatedV2:9,MemberJoinedViaTeeAttestation:10};function Io(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 m(new Uint8Array([1]),new Uint8Array(t))}function Po(t){let e=new TextEncoder().encode(t);return m(w(e.length),e)}function ft(t){let e=t.invitation,n=t.admitter_addrs??[];return m(Ge(e),Po(t.inviter_signature),t.inviter_account?m(new Uint8Array([1]),u(t.inviter_account,"inviter_account",32)):new Uint8Array([0]),w(n.length),...n.map(Po),Io(t.application_id,"application_id"),Io(t.app_key,"app_key"))}async function To(t){let e=t.parentOpHashes??[],n=u(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?m(new Uint8Array([Eo.MemberJoinedAt]),u(t.member,"member",32),ft(t.invitation),A(o),n):m(new Uint8Array([Eo.MemberJoined]),u(t.member,"member",32),ft(t.invitation),n),a=m(new Uint8Array([Ua]),i),s=await v(t.deviceSecret,t.signer,"deviceSecret"),c=u(s.publicKey,"signer.publicKey",32),d=m(new Uint8Array([An]),u(t.namespaceId,"namespaceId",32),w(e.length),...e.map((g,y)=>u(g,`parentOpHashes[${y}]`,32)),c,A(t.nonce),a),p=await s.sign(m(Da,d)),l=new Uint8Array([0]);return h(m(d,p,l))}var Oa=new TextEncoder().encode("calimero.account.owner-op.v1"),Na=new TextEncoder().encode("calimero.account.owner-op.body.v1"),Ma=new TextEncoder().encode("calimero.account.genesis.v1"),_a=2,xn={transferOwnership:0,adminChanged:1,groupDelete:2,teeAdmissionPolicy:3,teeAuthoringPolicy:4,teeReleaseAdmissionPolicy:5},xe={GroupDelete:14,TransferOwnership:21,TeeAuthoringPolicySet:33,TeeAdmissionPolicySetV2:37,TeeReleaseAdmissionPolicySetV2:38,RootGuarded:42},Uo={AdminChanged:3,RootGuarded:12},Ga={replica:0,relay:1},$a=new TextEncoder;function O(t){return new Uint8Array([t])}function Oo(t){let e=$a.encode(t);return m(w(e.length),e)}function j(t){return m(w(t.length),...t.map(Oo))}function No(t){return O(t?1:0)}function Mo(t){let e=Ga[t??"replica"];if(e===void 0)throw new Error(`mode must be replica or relay, got ${String(t)}`);return O(e)}function _o(t){return{kind:"transferOwnership",plane:"group",bytes:m(O(xe.TransferOwnership),u(t,"newOwner",32))}}function Go(){return{kind:"groupDelete",plane:"group",bytes:O(xe.GroupDelete)}}function $o(t){return{kind:"adminChanged",plane:"root",bytes:m(O(Uo.AdminChanged),u(t,"newAdmin",32))}}function Ho(t){return{kind:"teeAuthoringPolicy",plane:"group",bytes:m(O(xe.TeeAuthoringPolicySet),j(t))}}function Lo(t){return{kind:"teeAdmissionPolicy",plane:"group",bytes:m(O(xe.TeeAdmissionPolicySetV2),j(t.allowedMrtd),j(t.allowedRtmr0),j(t.allowedRtmr1),j(t.allowedRtmr2),j(t.allowedRtmr3),j(t.allowedTcbStatuses),No(t.acceptMock),Mo(t.mode))}}function qo(t){let e=t.minReleaseVersion===void 0?O(0):m(O(1),Oo(t.minReleaseVersion));return{kind:"teeReleaseAdmissionPolicy",plane:"group",bytes:m(O(xe.TeeReleaseAdmissionPolicySetV2),j(t.allowedProfiles),e,j(t.allowedTcbStatuses),No(t.acceptMock),Mo(t.mode))}}async function Rn(t){return R(Na,[t])}async function vn(t){return R(Oa,[u(t.account,"account",32),u(t.namespaceId,"namespaceId",32),u(t.groupId,"groupId",32),O(Ko(t.kind)),t.opDigest,A(t.counter),w(t.keyEpoch)])}function Ko(t){let e=xn[t];if(e===void 0)throw new Error(`unknown owner-op kind ${String(t)}`);return e}var Do=132;async function Bo(t){let e=await J(t.rootSecret),n=m(O(_a),e),r=h(await R(Ma,[n])),o=t.keyEpoch??0,i=(t.chain??[]).map((p,l)=>{let g=G(p,`chain[${l}]`);if(g.length!==Do)throw new Error(`chain[${l}] must be a ${Do}-byte RootKeyHandoff, got ${g.length}`);return g});if(o>i.length)throw new Error(`keyEpoch ${o} needs ${o} handoffs in chain, got ${i.length}`);let a=await Rn(t.op.bytes),s=await vn({account:r,namespaceId:t.namespaceId,groupId:t.groupId,kind:t.op.kind,opDigest:a,counter:t.counter,keyEpoch:o}),c=await W(t.rootSecret),d=new Uint8Array(await crypto.subtle.sign("Ed25519",c,s));return h(m(n,w(i.length),...i,u(r,"account",32),u(t.namespaceId,"namespaceId",32),u(t.groupId,"groupId",32),O(Ko(t.op.kind)),a,A(t.counter),w(o),d))}function jo(t,e){let n=t.plane==="group"?xe.RootGuarded:Uo.RootGuarded;return m(O(n),t.bytes,G(e,"rootProof"))}var Fo=[2428,2429,2528,2529],Ha="localhost",La=2e3;function Vo(t){return`http://${Ha}:${t}`}function Wo(t,e){let n=t.endsWith("/")?t:`${t}/`;return new URL(e,n).toString()}async function Jo(t,e={}){let{timeoutMs:n=La,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=Wo(t,"admin-api/health"),d=await fetch(c,{method:"GET",signal:o.signal});if(!d.ok)return!1;try{let p=await d.json(),l=p?.data?.status!==void 0?p?.data?.status:p?.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 qa(t={}){let{ports:e=Fo,timeoutMs:n,signal:r}=t;return(await Promise.all(e.map(async i=>{let a=Vo(i);return await Jo(a,{timeoutMs:n,signal:r})?a:null}))).filter(i=>i!==null)}var Ka=new TextEncoder().encode("calimero.tee-attest.key-binding.v1"),yt=new TextEncoder().encode("MOCK_TDX_QUOTE_V1"),Ba=568;function ja(...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 Cn(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 Fa(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 Va(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 bt(t){let e=await crypto.subtle.digest("SHA-256",ja(Ka,new Uint8Array(32),t));return new Uint8Array(e)}function Sn(t){let e=t.length>=yt.length&&Cn(t.subarray(0,yt.length),yt),n=e?yt.length:Ba;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 zo(t){let e=crypto.getRandomValues(new Uint8Array(32)),n=`${t.relayUrl.replace(/\/+$/,"")}/admin-api/tee/attest`,r=JSON.stringify({nonce:h(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=Va(s.boundPublicKey,"boundPublicKey"),d=Fa(s.quoteB64),{reportData:p,mock:l}=Sn(d);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:h(e),reportDataSuffix:h(await bt(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(d);else throw new Error("a real TDX quote needs a verify (or verifyQuote) to check its signature and measurements");if(!Cn(p.subarray(0,32),e))throw new Error("the quote does not carry our nonce: it was not made for this request");if(!Cn(p.subarray(32,64),await bt(c)))throw new Error("the quote does not bind the key the relay named: refusing it");return{nodeKey:h(c),mock:l}}export{oe as AdminApiClient,ne as AuthApiClient,V as AuthRevokedError,P as CAPABILITIES,pc as CAPABILITY_PRESETS,L as CloudClient,Fo as DEFAULT_LOCAL_NODE_PORTS,ho as DEFAULT_RELEASE_MIRROR,ke as EphemeralClient,Kr as HANDSHAKE_PATH,k as HTTPError,yn as INVITED_ROLE,ie as IntentRefusedError,Kt as LocalStorageTokenStore,ht as MAX_INVITATION_VALIDITY_SECS,qt as MemoryTokenStore,ae as MeroClient,me as MeroJs,hn as NODE_RELEASE_SIGNER,xn as OWNER_OP_KIND,Zt as REQUEST_PROOF_HEADER,Y as RelayClient,he as RelayObserver,se as RelayTransport,Se as RpcClient,Fe as RpcError,Ue as SEALED_CONTENT_TYPE,Br as SEALED_PATH,An as SIGNED_NAMESPACE_OP_SCHEMA_VERSION,fe as SealedTransportError,$ as SseClient,Oe as StaleTransportKeyError,dt as WarrantNonceExhaustedError,Le as WarrantNonceRouteUnavailableError,Re as WebHttpClient,z as WsClient,Qe as accountForRoot,H as accountForRootPublicKey,Jn as accountRootFromPhrase,_t as accountRootFromSecret,Qn as accountRootSignerFromPhrase,$o as adminChangedOp,Ti as admitterAddrsFromNetworkStatus,bt as attestKeyBinding,zo as attestRelayNodeKey,ps as authorNonceLookup,qs as beginCloudLink,Js as beginDeviceEnrolment,Pt as buildAuthLoginUrl,no as callbackIsForeign,Be as callerProof,gc as capMask,mc as capNames,kt as classifyError,Xr as cloudLinkUrl,Ro as cloudNodeReleaseUrl,xt as combineSignals,li as compareSemver,Bs as completeCloudLink,Qs as completeDeviceEnrolment,Qr as connectCloud,_s as connectCloudWithAccount,Ir as contextCapabilityGrantedOp,Pr as contextCapabilityRevokedOp,Rr as contextDetachedOp,kr as contextMetadataSetOp,zn as createAccountRootSigner,On as createAdminApiClient,qe as createAdminApiClientFromHttpClient,Ne as createAttestedSealedFetch,uc as createAuthApiClient,In as createAuthApiClientFromHttpClient,Dc as createBrowserAdminApiClient,cc as createBrowserAuthApiClient,ue as createBrowserHttpClient,ve as createHttpClient,rn as createLocalStorageNonceSource,pt as createMemoryNonceSource,Nr as createMeroClient,Ni as createMeroJs,Uc as createNodeAdminApiClient,lc as createNodeAuthApiClient,$e as createNodeHttpClient,tn as createProofAuthorizer,je as createProofSigner,un as createQuoteVerifier,gs as createRecoveringNonceSource,ni as createRetryableMethod,Wr as createSealedFetch,Pa as createSignedReleaseSealedFetch,Co as createSignedReleaseVerifier,Rt as createTimeoutSignal,vt as createUniversalHttpClient,Jt as createdSubgroupId,jt as creationInitHash,wn as defaultAdmitters,ut as defaultAudience,ot as defaultCapabilitiesSetOp,Je as deviceCertPayload,to as deviceEnrolmentUrl,Ot as deviceScopePayload,qa as discoverLocalNodes,Ge as encodeGroupInvitation,ft as encodeSignedInvitation,Vr as fetchAttestedTransportKey,yo as fetchNodeRelease,wo as fetchNodeReleaseVersion,it as foundedNamespaceId,Wn as generateAccountRoot,Xt as generateSessionKey,Ft as governanceOpHash,zt as groupCreatedOp,Go as groupDeleteOp,Ar as groupDeletedOp,bn as groupInvitationHash,Cr as groupMetadataSetOp,wr as groupReparentedOp,re as hasCap,kc as hexEncodeUtf8,Bt as intentHash,si as isSettled,We as jsonCodec,Vo as localNodeUrl,lt as login,mr as memberAddedOp,xr as memberCapabilitySetOp,Tr as memberJoinedOpenOp,fr as memberLeftOp,Sr as memberMetadataSetOp,hr as memberRemovedOp,yr as memberRoleSetOp,Kn as mintDeviceId,st as namespaceCreatedOp,Wo as nodeEndpoint,bo as nodeReleaseVersionFromImage,Rn as ownerOpDigest,vn as ownerOpSigningPayload,It as parseAuthCallback,ur as parseCreationWarrant,Ut as parseDeviceCredential,dr as parseGovernanceWarrant,Tn as parseWarrantNonce,Jo as probeNodeHealth,Ks as readCloudLinkCallback,zs as readEnrolmentCallback,Pn as redeemInvitation,Sn as reportDataOf,Tt as requestBodyHash,K as resolveRoot,Ye as resolveRootPair,jo as rootGuardedOpBytes,Ze as routingProofHeaders,wc as shouldRetain,Ee as signAccountLink,Xe as signAccountLogin,ta as signAccountOwnershipClaim,nt as signCreationWarrant,jn as signDeviceCert,Fn as signDeviceScope,Pe as signGovernanceWarrant,ko as signGroupInvitation,ct as signLoginStatement,To as signMemberJoinOp,Bo as signOwnerOpProof,Ke as signRequest,en as signRequestProof,sr as signRoutingChallenge,et as signWarrant,us as signedPath,Ln as signerFromCryptoKey,de as signerFromSecret,br as subgroupCreation,vr as subgroupVisibilitySetOp,Lo as teeAdmissionPolicyOp,Ho as teeAuthoringPolicyOp,qo as teeReleaseAdmissionPolicyOp,_o as transferOwnershipOp,Fr as transportKeyBinding,vo as trustSignedRelease,dn as trustedMeasurementsFromReleases,ze as verifyDeviceCredential,fo as verifySignedNodeRelease,Ct as withCap,He as withRetry,hc as withoutCap};
1
+ function Ct(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 St(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 oi=new Set(["token_reuse","token_revoked"]);function ii(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 I=class extends Error{constructor(n,r,o,i,a){let s=ii(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:Dn(this.headers),bodyText:this.bodyText}}},V=class extends I{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 Dn(t){let e={};return t.forEach((n,r)=>{e[r]=n}),e}function si(t){try{return new URL(t).pathname}catch{let e=t.indexOf("?");return e===-1?t:t.slice(0,e)}}var ve=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:Dn(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),d=await this.buildHeaders(n?.headers),p;d instanceof Headers?(p={},d.forEach((y,v)=>{p[v]=y})):p=d;let l=n?.method||"GET";if(this.transport.authorizeRequest){let y=n?.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(p,await this.transport.authorizeRequest({method:l,path:new URL(a).pathname,body:y}))}let m={method:l,headers:p},b=n?.body instanceof ReadableStream||typeof n?.body=="object"&&n?.body!==null&&"getReader"in n.body&&!(n.body instanceof Blob);(n?.body!==void 0&&!b||n?.body!==void 0&&b&&r===0)&&(m.body=n.body);let A;if(r>0&&o!==void 0){let y=n?.timeoutMs||this.transport.timeoutMs;if(y){let v=Date.now()-s,E=Math.max(0,y-v);A=this.createAbortSignal({...n,timeoutMs:E})}else A=this.createAbortSignal(n)}else A=c;if(A&&(m.signal=A),this.transport.credentials!==void 0&&(m.credentials=this.transport.credentials),n?.mode!==void 0&&(m.mode=n.mode),n?.cache!==void 0&&(m.cache=n.cache),n?.redirect!==void 0&&(m.redirect=n.redirect),n?.referrer!==void 0&&(m.referrer=n.referrer),n?.referrerPolicy!==void 0&&(m.referrerPolicy=n.referrerPolicy),n?.integrity!==void 0&&(m.integrity=n.integrity),n?.keepalive!==void 0&&(m.keepalive=n.keepalive),this.transport.getProof){let y=await this.transport.getProof({method:m.method??"GET",path:si(a),body:m.body});y&&(p["X-Calimero-Proof"]=y)}try{let y=await this.transport.fetch(a,m);if(!y.ok){let v=await this.getBodyText(y),E=new I(y.status,y.statusText,a,y.headers,v),S=y.headers.get("x-auth-error");if((y.status===401||y.status===403)&&S&&oi.has(S)){if(this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,this.transport.onAuthRevoked)try{await this.transport.onAuthRevoked()}catch{}throw new V(S,y.status,y.statusText,a,y.headers,v)}let F=n?.signal?.aborted===!0;if(y.status===401&&this.transport.refreshToken&&S==="token_expired"&&r<1&&!b&&!F)try{let M=this.refreshTokenPromise;M||(M=this.transport.refreshToken(),this.refreshTokenPromise=M);let D=await M;if(!D||D.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 _=this.onTokenRefreshPromise;_||(_=this.transport.onTokenRefresh(D),this.onTokenRefreshPromise=_),await _,this.refreshTokenPromise=null,this.onTokenRefreshPromise=null;let ee=n?.timeoutMs||this.transport.timeoutMs;if(ee&&o!==void 0){let te=Date.now()-s;if(ee-te<=0)throw E}return this.makeRequest(e,n,r+1,s)}catch(M){throw this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,M instanceof Error&&M.message.includes("onTokenRefresh")?M:E}throw E}return this.parseResponse(y,n?.parse)}catch(y){throw y instanceof I||y instanceof Error&&y.message.includes("onTokenRefresh")?y:new I(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 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(St(r)),n.length>0?Ct(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 Ce(t){return new ve(t)}function de(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 Ce(e)}function qe(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 Ce(r)}function kt(t){return typeof window<"u"?de(t):qe(t)}function ai(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 ci(t){let n=250*Math.pow(2,t-1),r=(Math.random()-.5)*.4*n;return Math.max(0,n+r)}async function Le(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,!ai(r,n-o))throw r;let a=ci(o),d=r.headers?.get?.("Retry-After");if(d){let p=parseInt(d,10);if(!isNaN(p))a=Math.max(a,p*1e3);else{let l=new Date(d);if(!isNaN(l.getTime())){let m=Math.max(0,l.getTime()-Date.now());a=Math.max(a,Math.min(m,6e4))}}}await new Promise(p=>setTimeout(p,a))}throw r||new Error("Retry failed without error")}function li(t,e={}){return async(...n)=>Le(()=>t(...n),e)}var re=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 Se=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 fc(t){let e=new Se;return new re(e)}function yc(t){let e=new Se;return new re(e)}function bc(t){let e=new Se;return new re(e)}function Un(t,e){return new re(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},Ac={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 xc(...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 Rc(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 Et(t,e){return(t|e)>>>0}function vc(t,e){return(t&~e)>>>0}var ui={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 di(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 pi(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 It(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 Pt(t){let e=pi(t),n;return e!==void 0?n=di(e):t instanceof TypeError?n="unreachable":n="unknown",{kind:n,status:e,retryable:ui[n],message:It(t)}}function gi(t){return t.status!=="failed"||!t.retryable}function Ec(t){return!gi(t)}function mi(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 hi(t,e){let{kind:n,status:r}=Pt(t),o=mi(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 On(t,e){let{namespaceId:n,invitation:r,teamName:o}=t,i=null;try{await e.join(n,r)}catch(p){i=p}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=It(i,"Could not join. Check the invitation."),{reason:c,retryable:d}=hi(i,s);return{status:"failed",namespaceId:n,message:s,reason:c,retryable:d}}var Ke=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 Tt(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 Nn(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:Tt(t,n,"highWaterNonce"),windowWidth:Tt(t,n,"windowWidth")??0n},o=Tt(t,n,"nextNonce");return o===void 0?{...r,kind:"exhausted",seen:!0,highWaterNonce:r.highWaterNonce??0xffffffffffffffffn}:{...r,kind:"open",nextNonce:o}}function f(t){return t?.data}function fi(t,e){let[n,r]=Mn(t),[o,i]=Mn(e),a=n.split("."),s=o.split("."),c=Math.max(a.length,s.length);for(let m=0;m<c;m++){let b=_n(a[m]??"0",s[m]??"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 d=r.split("."),p=i.split("."),l=Math.max(d.length,p.length);for(let m=0;m<l;m++){if(m>=d.length)return-1;if(m>=p.length)return 1;let b=_n(d[m],p[m]);if(b!==0)return b}return 0}function Mn(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 _n(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 yi(t,e,n){return Le(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 ie=class{constructor(e){this.httpClient=e}async healthCheck(){return f(await this.httpClient.get("/admin-api/health"))}async readinessCheck(){return f(await this.httpClient.get("/admin-api/ready"))}async isAuthed(){return this.httpClient.get("/admin-api/is-authed")}async installApplication(e){return f(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 yi(r.toString(),"versions",n)).json();return(Array.isArray(i)?i:[]).map(a=>a.appVersion).filter(a=>typeof a=="string").sort((a,s)=>fi(s,a))}async installDevApplication(e){return f(await this.httpClient.post("/admin-api/install-dev-application",e))}async uninstallApplication(e){return f(await this.httpClient.delete(`/admin-api/applications/${e}`))}async listApplications(){return f(await this.httpClient.get("/admin-api/applications"))}async getApplication(e){return f(await this.httpClient.get(`/admin-api/applications/${e}`))}async listApplicationVersions(e){return f(await this.httpClient.get(`/admin-api/applications/${e}/versions`))}async getApplicationAbi(e,n){let r=n?`?service_name=${encodeURIComponent(n)}`:"";return f(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 f(await this.httpClient.post("/admin-api/contexts",n))}async deleteContext(e){return f(await this.httpClient.delete(`/admin-api/contexts/${e}`))}async getContexts(){return f(await this.httpClient.get("/admin-api/contexts"))}async getContext(e){return f(await this.httpClient.get(`/admin-api/contexts/${e}`))}async getContextsForApplication(e){return f(await this.httpClient.get(`/admin-api/contexts/for-application/${e}`))}async generateContextIdentity(){return f(await this.httpClient.post("/admin-api/identity/context",{}))}async getContextIdentities(e){return f(await this.httpClient.get(`/admin-api/contexts/${e}/identities`))}async getContextIdentitiesOwned(e){return f(await this.httpClient.get(`/admin-api/contexts/${e}/identities-owned`))}async joinContext(e){return f(await this.httpClient.post(`/admin-api/contexts/${e}/join`,{}))}async getContextGroup(e){return f(await this.httpClient.get(`/admin-api/contexts/${e}/group`))}async getContextStorage(e){return f(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 f(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=f(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:f(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 f(await this.httpClient.post("/admin-api/alias/create/context",{alias:e.alias,contextId:e.contextId}))}async createApplicationAlias(e){return f(await this.httpClient.post("/admin-api/alias/create/application",{alias:e.alias,applicationId:e.applicationId}))}async lookupContextAlias(e){return f(await this.httpClient.post(`/admin-api/alias/lookup/context/${encodeURIComponent(e)}`,{}))}async lookupApplicationAlias(e){return f(await this.httpClient.post(`/admin-api/alias/lookup/application/${encodeURIComponent(e)}`,{}))}async deleteContextAlias(e){return f(await this.httpClient.post(`/admin-api/alias/delete/context/${encodeURIComponent(e)}`,{}))}async deleteApplicationAlias(e){return f(await this.httpClient.post(`/admin-api/alias/delete/application/${encodeURIComponent(e)}`,{}))}async listContextAliases(){return f(await this.httpClient.get("/admin-api/alias/list/context"))}async listApplicationAliases(){return f(await this.httpClient.get("/admin-api/alias/list/application"))}async createDeviceAlias(e){return f(await this.httpClient.post("/admin-api/alias/create/device",{alias:e.alias,deviceId:e.deviceId}))}async lookupDeviceAlias(e){return f(await this.httpClient.post(`/admin-api/alias/lookup/device/${encodeURIComponent(e)}`,{}))}async deleteDeviceAlias(e){return f(await this.httpClient.post(`/admin-api/alias/delete/device/${encodeURIComponent(e)}`,{}))}async listDeviceAliases(){return f(await this.httpClient.get("/admin-api/alias/list/device"))}async listNamespaces(){return f(await this.httpClient.get("/admin-api/namespaces"))}async getNamespace(e){return f(await this.httpClient.get(`/admin-api/namespaces/${e}`))}async getNodeIdentity(){return f(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 f(await this.httpClient.post(`/admin-api/contexts/${e}/intents`,n))}async queryContext(e,n){return f(await this.httpClient.post(`/admin-api/contexts/${e}/query`,n))}async getIntentRelay(e){return f(await this.httpClient.get(`/admin-api/contexts/${e}/intents`))}async listNamespacesForApplication(e){return f(await this.httpClient.get(`/admin-api/namespaces/for-application/${e}`))}async createNamespace(e){return f(await this.httpClient.post("/admin-api/namespaces",e))}async deleteNamespace(e){return f(await this.httpClient.request(`/admin-api/namespaces/${e}`,{method:"DELETE",body:"{}",headers:{"Content-Type":"application/json"}}))}async createNamespaceInvitation(e,n){return f(await this.httpClient.post(`/admin-api/namespaces/${e}/invite`,n??{}))}async admitJoin(e,n){return f(await this.httpClient.post(`/admin-api/namespaces/${e}/admit`,n,{timeoutMs:65e3}))}async joinNamespace(e,n){let r=f(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 On({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 f(await this.httpClient.post(`/admin-api/namespaces/${e}/groups`,n??{}))}async listNamespaceGroups(e){return f(await this.httpClient.get(`/admin-api/namespaces/${e}/groups`))}async initAccountPairing(e){return f(await this.httpClient.post("/admin-api/account/pair-init",e))}async completeAccountPairing(e){return f(await this.httpClient.post("/admin-api/account/pair-complete",e))}async relinkAccountDevice(e,n){return f(await this.httpClient.post(`/admin-api/account/devices/${e}/relink`,n??{}))}async rescopeAccountDevice(e,n){return f(await this.httpClient.put(`/admin-api/account/devices/${encodeURIComponent(e)}/scope`,n))}async signWithAccountRoot(e){return f(await this.httpClient.post("/admin-api/account/sign-with-root",e))}async labelAccountDevice(e,n){return f(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 f(await this.httpClient.post(`/admin-api/namespaces/${e}/account/revoke`,n))}async linkAccountDevice(e,n){return f(await this.httpClient.post(`/admin-api/namespaces/${e}/account/link-device`,n))}async getGroupInfo(e){return f(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 f(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 I&&i.status===404?new Ke(r,i):i}return Nn(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 I&&i.status===404?new Ke(r,i):i}return Nn(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 f(await this.httpClient.post(`/admin-api/groups/${e}/accounts/${n}/seal`,r))}async listGroupContexts(e){return f(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 f(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=Et(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=Et(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,n={}){let r=`/admin-api/groups/${e}/settings/tee-authoring-policy`;if(n.rootProof===void 0){await this.httpClient.delete(r);return}await this.httpClient.request(r,{method:"DELETE",body:JSON.stringify({rootProof:n.rootProof}),headers:{"Content-Type":"application/json"}})}async transferOwnership(e,n){await this.httpClient.post(`/admin-api/groups/${e}/transfer-ownership`,n)}async changeNamespaceAdmin(e,n){await this.httpClient.post(`/admin-api/namespaces/${e}/admin`,n)}async ownerDeleteGroup(e,n={}){await this.httpClient.post(`/admin-api/groups/${e}/owner-delete`,n)}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 f(await this.httpClient.post(`/admin-api/groups/${e}/sync`,{}))}async upgradeGroup(e,n){return f(await this.httpClient.post(`/admin-api/groups/${e}/upgrade`,n))}async getGroupUpgradeStatus(e){return f(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 f(await this.httpClient.get(`/admin-api/groups/${n}/cascade-status`))}async retryGroupUpgrade(e){return f(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 f(await this.httpClient.post(`/admin-api/groups/${e}/invite`,n??{}))}async joinGroup(e){return f(await this.httpClient.post("/admin-api/groups/join",e))}async joinSubgroupInheritance(e){return f(await this.httpClient.post(`/admin-api/groups/${e}/join-via-inheritance`,{}))}async getTeeInfo(){return f(await this.httpClient.get("/admin-api/tee/info"))}async teeAttest(e){return f(await this.httpClient.post("/admin-api/tee/attest",e))}async teeVerifyQuote(e){return f(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 f(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 Nc(t){return Array.from(new TextEncoder().encode(t),e=>e.toString(16).padStart(2,"0")).join("")}function Hc(t){return new ie(de(t))}function qc(t){return new ie(qe(t))}function Gn(t){return new ie(kt(t))}function Be(t,e){return new ie(t)}function Dt(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 Ut(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 $n=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 h(t){return Array.from(t,e=>e.toString(16).padStart(2,"0")).join("")}function u(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 G(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 g(...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 R(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",g(...n)))}async function W(t){let e=u(t,"deviceSecret",32),n=g($n,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 Hn(t,e,n){let r=await crypto.subtle.importKey("raw",u(t,"publicKey",32),{name:"Ed25519"},!1,["verify"]);return crypto.subtle.verify({name:"Ed25519"},r,e,n)}async function J(t){let e=u(t,"deviceSecret",32),n=g($n,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 bi=new TextEncoder().encode("calimero.auth.request.v1"),wi=new TextEncoder().encode("calimero.auth.request.body.v1");function qn(t){let e=new TextEncoder().encode(t);return g(w(e.length),e)}async function Ot(t=new Uint8Array(0)){let e=typeof t=="string"?new TextEncoder().encode(t):t;return R(wi,[e])}async function je(t){let e=await W(t.signerSecret),n=await Ot(t.body),r=x(t.issuedAt),o=x(t.expiresAt),i=new TextEncoder,a=await R(bi,[i.encode(t.method),i.encode(t.path),n,r,o]),s=new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},e,a));return h(g(qn(t.method),qn(t.path),n,r,o,s))}function Fe(t){let e=G(t.credential,"credential"),n=G(t.request,"request signature"),r=t.session===void 0?new Uint8Array([0]):g(new Uint8Array([1]),G(t.session,"session statement"));return h(g(e,r,n))}function Ai(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 Ve(t){let e=t.ttlSeconds??120,n=t.now??(()=>Math.floor(Date.now()/1e3));return async r=>{let o=n();return Fe({credential:t.credential,session:t.session,request:await je({method:r.method,path:r.path,body:Ai(r.body),issuedAt:o,expiresAt:o+e,signerSecret:t.signerSecret})})}}var We=class extends Error{constructor(e,n,r,o){super(n),this.name="RpcError",this.code=e,this.data=r,this.type=o}};async function Nt(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 We(o.code??-1,o.message??o.type??"RPC error",o.data,o.type)}return r.result}var ke=class{constructor(e){this.kind="node";this.canSubscribe=!0;this.httpClient=e.httpClient}async execute(e){let n=await Nt(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 xi=new Set(["MigrationStarted","MigrationProgress","CascadeProgress","MigrationCompleted"]);function Ln(t){return t.type!==void 0&&xi.has(t.type)}var Ri=new Set(["token_reuse","token_revoked"]),vi=new Set([401,403]);function Kn(t){let e=t.headers.get("x-auth-error");return!e||!vi.has(t.status)?null:Ri.has(e)?e:null}var $=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=>{Ln(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 V(r,n.status,n.statusText,e,n.headers,o):new I(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 V)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 d=c.slice(5).trim();d&&this.handleMessage(d)}}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 V(s,a.status,a.statusText,`${this.baseUrl}/sse/subscription`,a.headers,c):new I(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 Je=class Je{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),Je.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()}};Je.MAX_BACKOFF_MS=3e4;var z=Je;function Q(){return{encode(t){return Array.from(new TextEncoder().encode(JSON.stringify(t)))},decode(t){return JSON.parse(new TextDecoder().decode(new Uint8Array(t)))}}}var Ee=class{constructor(e){this.httpClient=e.httpClient,this.sse=e.sse}async set(e,n,r=Q()){await Nt(this.httpClient,"set_ephemeral",{contextId:e,state:r.encode(n)})}subscribe(e,n,r=Q()){return ze(this.sse,e,n,r)}};function ze(t,e,n,r=Q()){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,d={author:s.author,state:c||s.state===void 0?void 0:r.decode(s.state),removed:c};s.ageMs!==void 0&&(d.ageMs=s.ageMs),s.account!==void 0&&(d.account=s.account),n(d)};return t.on("event",o),t.connect().catch(()=>{}),t.subscribe([e]).catch(()=>{}),()=>{t.off("event",o)}}var Ci=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,112,4,34,4,32]);function Bn(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 pe(t,e="secret"){let n=u(t,e,32),r=g(Ci,n),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 Bn(a)}return Fn(o,i)}async function jn(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")u(e,"publicKey",32),n=e.trim().toLowerCase();else try{n=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 Fn(t,n)}function Fn(t,e){return{publicKey:e,async sign(n){try{return new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},t,n))}catch(r){throw Bn(r)}}}}async function C(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 pe(t,n);throw new Error(`${n} or signer is required`)}var Si=new TextEncoder().encode("calimero.device.cert.v1"),ki=new TextEncoder().encode("calimero.account.genesis.v1"),Ei=new TextEncoder().encode("calimero.device.id.v1"),ge=2,Ii=237;async function Vn(t,e){if(e.length!==16)throw new Error(`nonce must be 16 bytes, got ${e.length}`);let n=u(t,"account",32);return h(await R(Ei,[n,e]))}async function Qe(t){return R(Si,[u(t.account,"account",32),u(t.device,"device",32),u(t.signPublicKey,"signPublicKey",32),u(t.kemPublicKey,"kemPublicKey",32),w(t.keyEpoch),w(t.deviceEpoch)])}function Wn(t){return g(new Uint8Array([ge]),t.rootPublicKey,w(0),u(t.account,"account",32),u(t.device,"device",32),u(t.signPublicKey,"signPublicKey",32),u(t.kemPublicKey,"kemPublicKey",32),w(t.keyEpoch),w(t.deviceEpoch),t.signature)}async function Jn(t){let e=await C(t.rootSecret,t.signer,"rootSecret"),n=u(e.publicKey,"signer.publicKey",32),r=await H(e.publicKey),o=0,i=await Qe({account:r,device:t.device,signPublicKey:t.signPublicKey,kemPublicKey:t.kemPublicKey,keyEpoch:o,deviceEpoch:t.deviceEpoch}),a=await e.sign(i),s=Wn({rootPublicKey:n,account:r,device:t.device,signPublicKey:t.signPublicKey,kemPublicKey:t.kemPublicKey,keyEpoch:o,deviceEpoch:t.deviceEpoch,signature:a});return h(s)}function Mt(t){let e=u(t,"credential",Ii);if(e[0]!==ge)throw new Error(`this credential has account genesis version ${e[0]}, not ${ge} \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)=>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:n.getUint32(165,!0),deviceEpoch:n.getUint32(169,!0),signature:o(173,64)}}async function Ye(t){let e=Mt(t),n=await H(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 Hn(e.rootPublicKey,u(e.signature,"signature",64),await Qe(e)))throw new Error(`the root key of account ${e.account} did not sign this certificate`);return e}async function Xe(t){return H(h(await J(t)))}async function H(t){return h(await R(ki,[g(new Uint8Array([ge]),u(t,"rootPublicKey",32))]))}var Pi=new TextEncoder().encode("calimero.device.scope.v1");async function _t(t){return R(Pi,[u(t.account,"account",32),u(t.device,"device",32),w(t.scopeEpoch),w(t.keyEpoch),...t.applications.map((e,n)=>u(e,`applications[${n}]`,32))])}async function zn(t){let e=await C(t.rootSecret,t.signer,"rootSecret"),n=u(e.publicKey,"signer.publicKey",32),r=await H(h(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 _t({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 h(g(new Uint8Array([ge]),n,w(0),u(r,"account",32),u(t.device,"device",32),w(o.length),...o.map((d,p)=>u(d,`applications[${p}]`,32)),w(i),w(a),c))}var Gt=["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 Ti=new TextEncoder().encode("calimero.mdma.account-link.v1\0"),Di=new TextEncoder().encode("calimero.mdma.account-login.v1\0"),me=256,Qn=me/32,$t=(me+Qn)/11;async function Yn(){let t=crypto.getRandomValues(new Uint8Array(me/8));return rr(h(t),await ir(t))}async function Xn(t){let e=or(t);return rr(h(await sr(e)),e.join(" "))}async function Ht(t){return u(t,"secret",32),{secret:t,publicKey:h(await J(t)),accountId:await Xe(t)}}async function Zn(){let t=crypto.getRandomValues(new Uint8Array(me/8)),e=await ir(t);return{...await tr(t),phrase:e}}async function er(t){return tr(await sr(or(t)))}async function tr(t){let e=await pe(h(t),"rootSecret");return t.fill(0),{publicKey:e.publicKey,accountId:await H(e.publicKey),signer:e}}async function K(t){let e=typeof t=="string"?await pe(t,"rootSecret"):t;return nr(e)}async function Ze(t,e){return nr(await C(t,e,"rootSecret"))}async function nr(t){return{signer:t,publicKey:t.publicKey,accountId:await H(t.publicKey)}}async function Ie(t){if(!t.nonce)throw new Error("nonce is required to sign an account link");let n=await(await C(t.rootSecret,t.signer,"rootSecret")).sign(g(Ti,new TextEncoder().encode(t.nonce)));return lr(n)}async function et(t){if(!t.nonce)throw new Error("nonce is required to sign an account login");let n=await(await C(t.rootSecret,t.signer,"rootSecret")).sign(g(Di,new TextEncoder().encode(t.nonce)));return lr(n)}async function rr(t,e){return{...await Ht(t),phrase:e}}function or(t){let e=t.normalize("NFKD").toLowerCase().trim().split(/\s+/),n=e[0]===""?0:e.length;if(n!==$t)throw new Error(`recovery phrase must be ${$t} words, got ${n}`);return e}async function ir(t){let e=cr(t)+await ar(t),n=[];for(let r=0;r<$t;r+=1){let o=Number.parseInt(e.slice(r*11,r*11+11),2);n.push(Gt[o])}return n.join(" ")}async function sr(t){let e="";for(let r of t){let o=Gt.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(me/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(me)!==await ar(n))throw new Error("recovery phrase checksum failed \u2014 check for a mistyped or transposed word");return n}async function ar(t){let e=new Uint8Array(await crypto.subtle.digest("SHA-256",t));return cr(e).slice(0,Qn)}function cr(t){let e="";for(let n of t)e+=n.toString(2).padStart(8,"0");return e}function lr(t){let e="";for(let n of t)e+=String.fromCharCode(n);return btoa(e)}var Ui=new TextEncoder().encode("calimero.mdma.routing-read.v1\0");async function ur(t,e){u(e,"deviceSecret",32);let n=await W(e),r=g(Ui,new TextEncoder().encode(t)),o=new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},n,r));return Oi(o)}async function tt(t,e){return{"X-Calimero-Credential":e.credential,"X-Calimero-Nonce":t.nonce,"X-Calimero-Signature":await ur(t.nonce,e.deviceSecret)}}function Oi(t){let e="";for(let n of t)e+=String.fromCharCode(n);return btoa(e)}var Ni="https://manager.cloud.calimero.network";function qt(t,e){return typeof t.can_execute=="boolean"?t.can_execute:e}function Lt(t){return typeof t.tee_role=="string"&&t.tee_role!==""?t.tee_role:null}function Kt(t){return t.find(e=>e.canExecute&&e.relayUrl!==null&&e.executorAccount!==null)??null}var Mi="x-mdma-session-refresh",_i="x-mdma-session-expires",q=class{constructor(e={}){this.session=null;this.baseUrl=(e.cloudBaseUrl||Ni).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 K(e),{nonce:o}=await this.getAccountLoginChallenge();return this.submitAccountLogin({rootPublicKey:r,nonce:o,signature:await et({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:Lt(r),canExecute:qt(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 Kt(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:Lt(r),canExecute:qt(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 tt(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 tt(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:Lt(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:qt(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 enableFoundedNamespaceHa(e,n){return this.request("POST",`/api/cloud/me/namespaces/${encodeURIComponent(e)}/enable-ha`,{body:{groups:[],ownership_proof:n}})}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 K(e),{nonce:i}=await this.getAccountLinkChallenge();return this.submitAccountLink({accountId:o,rootPublicKey:r,nonce:i,signature:await Ie({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 Ze(e.rootSecret,e.signer),i=await this.request("POST","/api/cloud/accounts/link",{body:{grant:e.grant,root_public_key:r,signature:await Ie({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 I(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 I(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(Mi);if(!n||!this.session)return;let r=e.headers.get(_i),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 Gi(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 $i(t){if(t)return typeof t=="function"?t:Ve(t)}var Hi="mero-js:token-refresh";function qi(){let e=globalThis.navigator?.locks;return e&&typeof e.request=="function"?e:null}function Bt(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 he=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=$i(this.config.requestProof);this.httpClient=de({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=Un(this.httpClient,{baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||"",timeoutMs:this.config.timeoutMs}),this.adminClient=Be(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 ke({httpClient:this.httpClient})),this.rpcClient}get events(){return this.sseClient||(this.sseClient=new $({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 Ee({httpClient:this.httpClient,sse:this.events})),this.ephemeralClient}get cloud(){return this.cloudClient||(this.cloudClient=new q(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 z({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:Bt(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=qi();return n?n.request(Hi,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:Bt(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||Bt(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 Dt(e)}static buildAuthLoginUrl(e,n){return Ut(e,n)}};function Li(t){return new he(t)}var jt=class{constructor(){this.tokens=null}getTokens(){return this.tokens}setTokens(e){this.tokens=e}clear(){this.tokens=null}},Ki="mero-tokens",Ft=class{constructor(e=Ki){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 Bi=new TextEncoder().encode("calimero.warrant.v2"),ji=new TextEncoder().encode("calimero.warrant.intent.v1"),dr=64,Fi="00".repeat(32);async function Vt(t,e){let n=new TextEncoder().encode(JSON.stringify(e));return R(ji,[new TextEncoder().encode(t),n])}async function nt(t){let e=u(t.context,"context",32),n=u(t.authorAccount,"authorAccount",32),r=u(t.executor,"executor",32),o=u(t.appVersion??Fi,"appVersion",32),i=Y(t.accountHeads,"accountHeads"),a=Y(t.governanceFloor,"governanceFloor"),s=await C(t.deviceSecret,t.signer,"deviceSecret"),c=u(s.publicKey,"signer.publicKey",32),d=new TextEncoder().encode(t.method),p=await Vt(t.method,t.argsJson),l=x(t.nonce),m=x(t.notAfter),b=await R(Bi,[e,n,c,r,o,d,p,x(i.length),...i,x(a.length),...a,l,m]),A=Pe(await s.sign(b));return h(g(e,n,c,r,o,w(d.length),d,p,w(i.length),...i,w(a.length),...a,l,m,A))}function Pe(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 Y(t,e){let n=t??[];if(n.length>dr)throw new Error(`${e} cites ${n.length} heads, over the ${dr} a node accepts`);return n.map((r,o)=>u(r,`${e}[${o}]`,32))}var Vi=new TextEncoder().encode("calimero.context-creation-warrant.v1"),Wi=new TextEncoder().encode("calimero.context-creation.init.v1"),rt=256;async function Wt(t){let e=new TextEncoder().encode(JSON.stringify(t));return R(Wi,[e])}async function Ji(t){return R(Vi,[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 ot(t){let e=u(t.group,"group",32),n=t.seed===void 0?crypto.getRandomValues(new Uint8Array(32)):u(t.seed,"seed",32),r=u(t.authorAccount,"authorAccount",32),o=u(t.executor,"executor",32),i=u(t.applicationId,"applicationId",32),a=pr(t.serviceName,"serviceName"),s=pr(t.name,"name"),c=Y(t.accountHeads,"accountHeads"),d=Y(t.governanceFloor,"governanceFloor"),p=await C(t.deviceSecret,t.signer,"deviceSecret"),l=u(p.publicKey,"signer.publicKey",32),m=await Wt(t.initArgs),b=await Ji({group:e,seed:n,authorAccount:r,deviceKey:l,executor:o,applicationId:i,serviceName:a,name:s,initHash:m,accountHeads:c,governanceFloor:d,nonce:t.nonce,notAfter:t.notAfter}),A=Pe(await p.sign(b));return{warrant:h(g(e,n,r,l,o,i,gr(a),gr(s),m,w(c.length),...c,w(d.length),...d,x(t.nonce),x(t.notAfter),A)),seed:h(n)}}function mr(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,m)=>{if(o+l>n.length)throw new Error(`creation warrant ends inside ${m} (${n.length} bytes)`);let b=n.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 m=i(1,l)[0];if(m===0)return null;if(m!==1)throw new Error(`${l} has option tag ${m}, expected 0 or 1`);let b=a(l);if(b>rt)throw new Error(`${l} is ${b} bytes, over the ${rt} a node accepts`);return new TextDecoder("utf-8",{fatal:!0}).decode(i(b,l))},d=l=>{let m=a(l);if(m>64)throw new Error(`${l} cites ${m} heads, over the 64 a node accepts`);return Array.from({length:m},()=>h(i(32,l)))},p={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:d("accountHeads"),governanceFloor:d("governanceFloor"),nonce:s("nonce"),notAfter:s("notAfter"),signature:h(i(64,"signature"))};if(o!==n.length)throw new Error(`creation warrant is ${n.length} bytes but its fields account for ${o}`);return p}function pr(t,e){if(t===void 0)return null;let n=new TextEncoder().encode(t);if(n.length>rt)throw new Error(`${e} is ${n.length} UTF-8 bytes, over the ${rt} a node accepts`);return n}function gr(t){return t===null?new Uint8Array([0]):g(new Uint8Array([1]),w(t.length),t)}var zi=new TextEncoder().encode("calimero.governance-warrant.v1"),Qi=new TextEncoder().encode("calimero.governance-warrant.op.v1"),Yi={group:0,root:1};async function Jt(t){return R(Qi,[new Uint8Array([zt(t.kind)]),t.bytes])}async function Xi(t){return R(zi,[t.scope,new Uint8Array([zt(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 Te(t){let e=u(t.scope,"scope",32),n=u(t.authorAccount,"authorAccount",32),r=u(t.executor,"executor",32),o=Y(t.accountHeads,"accountHeads"),i=Y(t.governanceFloor,"governanceFloor"),a=zt(t.op.kind),s=await C(t.deviceSecret,t.signer,"deviceSecret"),c=u(s.publicKey,"signer.publicKey",32),d=await Jt(t.op),p=await Xi({scope:e,kind:t.op.kind,authorAccount:n,deviceKey:c,executor:r,opHash:d,accountHeads:o,governanceFloor:i,nonce:t.nonce,notAfter:t.notAfter}),l=Pe(await s.sign(p));return h(g(e,new Uint8Array([a]),n,c,r,d,w(o.length),...o,w(i.length),...i,x(t.nonce),x(t.notAfter),l))}function hr(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,m)=>{if(o+l>n.length)throw new Error(`governance warrant ends inside ${m} (${n.length} bytes)`);let b=n.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 m=a(l);if(m>64)throw new Error(`${l} cites ${m} heads, over the 64 a node accepts`);return Array.from({length:m},()=>h(i(32,l)))},d=()=>{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)`)},p={scope:h(i(32,"scope")),kind:d(),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!==n.length)throw new Error(`governance warrant is ${n.length} bytes but its fields account for ${o}`);return p}function zt(t){let e=Yi[t];if(e===void 0)throw new Error(`op kind must be 'group' or 'root', got ${String(t)}`);return e}var Zi={Admin:0,Member:1,ReadOnly:2},U={MemberAdded:1,MemberRemoved:2,MemberLeft:3,MemberRoleSet:4,MemberCapabilitySet:5,DefaultCapabilitiesSet:6,TargetApplicationSet:7,ContextDetached:9,SubgroupVisibilitySet:10,GroupMetadataSet:11,MemberMetadataSet:12,ContextMetadataSet:13,ContextCapabilityGranted:16,ContextCapabilityRevoked:17},De={GroupCreated:0,GroupReparented:1,GroupDeleted:2,MemberJoinedOpen:7,NamespaceCreatedV2:9},es=new TextEncoder().encode("calimero.namespace.id.v1"),Yt=new Uint8Array(32),it=w(0);function yr(t){let e=Zi[t];if(e===void 0)throw new Error(`role must be Admin, Member or ReadOnly, got ${String(t)}`);return new Uint8Array([e])}function k(t){return new Uint8Array([t])}function br(t,e){return{kind:"group",bytes:g(k(U.MemberAdded),u(t,"member",32),yr(e))}}function wr(t){return{kind:"group",bytes:g(k(U.MemberRemoved),u(t,"member",32),Yt,it)}}function Ar(t){return{kind:"group",bytes:g(k(U.MemberLeft),u(t,"member",32),Yt,it)}}function xr(t,e){return{kind:"group",bytes:g(k(U.MemberRoleSet),u(t,"member",32),yr(e))}}var ts=new TextEncoder().encode("calimero.subgroup.id.v1");async function Xt(t,e,n,r){return h(await R(ts,[u(t,"admin",32),u(e,"parentId",32),new Uint8Array([n?1:0]),u(r,"salt",32)]))}function fr(t,e){if(t.length===0)throw new Error(`${e} must not be empty`);let n=new TextEncoder().encode(t);return g(w(n.length),n)}function st(t){return{kind:"group",bytes:g(k(U.TargetApplicationSet),Yt,u(t.applicationId,"applicationId",32),fr(t.package,"package"),fr(t.version,"version"))}}function at(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:g(k(U.DefaultCapabilitiesSet),w(t))}}function Zt(t){return{kind:"root",bytes:g(k(De.GroupCreated),u(t.groupId,"groupId",32),u(t.parentId,"parentId",32),k(t.restricted?1:0),u(t.admin,"admin",32),u(t.salt,"salt",32))}}async function Rr(t){let e=t.salt??h(crypto.getRandomValues(new Uint8Array(32))),n=await Xt(t.admin,t.parentId,t.restricted,e);return{groupId:n,salt:e,op:Zt({...t,groupId:n,salt:e})}}function vr(t,e){return{kind:"root",bytes:g(k(De.GroupReparented),u(t,"childGroupId",32),u(e,"newParentId",32))}}function Cr(t){return{kind:"root",bytes:g(k(De.GroupDeleted),u(t,"rootGroupId",32),it,it)}}async function ct(t,e){return h(await R(es,[u(t,"founder",32),u(e,"salt",32)]))}function lt(t){let e=G(t.credential,"credential");if(e.length===0)throw new Error("credential must be the founder's AccountProof<DeviceCert>, got nothing");return{kind:"root",bytes:g(k(De.NamespaceCreatedV2),u(t.founder,"founder",32),e,u(t.salt,"salt",32))}}function Qt(t){let e=new TextEncoder().encode(t);return g(w(e.length),e)}function en(t){return t===void 0?k(0):g(k(1),Qt(t))}function tn(t={}){let e=new TextEncoder,n=Object.entries(t).map(([r,o])=>[e.encode(r),o,r]).sort(([r],[o])=>{for(let i=0;i<Math.min(r.length,o.length);i++)if(r[i]!==o[i])return r[i]-o[i];return r.length-o.length});return g(w(n.length),...n.flatMap(([,r,o])=>[Qt(o),Qt(r)]))}function ns(t,e){if(!Number.isInteger(t)||t<0||t>4294967295)throw new Error(`${e} must be a u32 bit mask, got ${String(t)}`);if(oe(t,T.CAN_AUTHOR_ON_BEHALF))throw new Error(`${e} may not include CAN_AUTHOR_ON_BEHALF (512): a relay never carries a change to it`);return t}function Sr(t,e){return{kind:"group",bytes:g(k(U.MemberCapabilitySet),u(t,"member",32),w(ns(e,"capabilities")))}}function kr(t){return{kind:"group",bytes:g(k(U.ContextDetached),u(t,"contextId",32))}}function Er(t){if(t!=="open"&&t!=="restricted")throw new Error(`mode must be open or restricted, got ${String(t)}`);return{kind:"group",bytes:g(k(U.SubgroupVisibilitySet),k(t==="open"?0:1))}}function Ir(t={}){return{kind:"group",bytes:g(k(U.GroupMetadataSet),en(t.name),tn(t.data))}}function Pr(t,e={}){return{kind:"group",bytes:g(k(U.MemberMetadataSet),u(t,"member",32),en(e.name),tn(e.data))}}function Tr(t,e={}){return{kind:"group",bytes:g(k(U.ContextMetadataSet),u(t,"contextId",32),en(e.name),tn(e.data))}}function Dr(t){if(!Number.isInteger(t)||t<1||t>255)throw new Error(`capability must be a non-zero u8, got ${String(t)}`);return k(t)}function Ur(t,e,n){return{kind:"group",bytes:g(k(U.ContextCapabilityGranted),u(t,"contextId",32),u(e,"member",32),Dr(n))}}function Or(t,e,n){return{kind:"group",bytes:g(k(U.ContextCapabilityRevoked),u(t,"contextId",32),u(e,"member",32),Dr(n))}}function Nr(t){return{kind:"root",bytes:g(k(De.MemberJoinedOpen),u(t.member,"member",32),u(t.groupId,"groupId",32),G(t.credential,"credential"))}}var ut=300,se=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"}},rs=t=>new Promise(e=>setTimeout(e,t));function os(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 X=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 C(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??ut,c=await nt({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}),d=await this.json("POST",`/admin-api/contexts/${encodeURIComponent(e)}/intents`,{method:n,argsJson:r,warrant:c,authorProof:this.config.authorProof});return{rootHash:d.data.rootHash,returns:d.data.returns??null}}async presenceIntent(e,n){await this.jsonOnce("POST",`/admin-api/contexts/${encodeURIComponent(e)}/presence-intents`,n)}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 se(`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 se(`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??ut,{warrant:c}=await ot({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}),d=await this.json("POST",`/admin-api/groups/${encodeURIComponent(e.groupId)}/context-intents`,{warrant:c,authorProof:this.config.authorProof,initArgs:o});return{contextId:d.data.contextId,groupId:d.data.groupId,memberPublicKey:d.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 se(`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??ut,s=await Te({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?h(u(e.salt,"salt",32)):h(crypto.getRandomValues(new Uint8Array(32))),o=await ct(this.config.authorAccount,r),i=lt({founder:this.config.authorAccount,credential:this.config.authorProof,salt:r}),a=e.defaultCapabilities===void 0?void 0:at(e.defaultCapabilities),s=e.application?st(e.application):void 0,c=await this.authorSigner(),d=await this.config.nonces.next(),p=this.config.ttlSeconds??ut,l=await Te({scope:o,op:i,authorAccount:this.config.authorAccount,executor:n,nonce:d,notAfter:BigInt(Math.floor(Date.now()/1e3))+BigInt(p),signer:c}),m=await this.postGovernance(o,i,l),b={namespaceId:m.groupId,salt:r,teeEnabled:m.teeEnabled??!1,...m.teeError?{teeError:m.teeError}:{}},A=b,y=v=>v instanceof Error?v.message:String(v);if(s)try{await this.govern({groupId:b.namespaceId,op:s}),A={...A,applicationSet:!0}}catch(v){A={...A,applicationSet:!1,applicationError:y(v)}}if(a)try{await this.govern({groupId:b.namespaceId,op:a}),A={...A,defaultCapabilitiesSet:!0}}catch(v){A={...A,defaultCapabilitiesSet:!1,defaultCapabilitiesError:y(v)}}return A}async postGovernance(e,n,r){return(await this.json("POST",`/admin-api/groups/${encodeURIComponent(e)}/governance-intents`,{warrant:r,authorProof:this.config.authorProof,op:h(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 I&&a.status===429)||i>=this.rateLimitRetries)throw a;let c=os(a.headers);await rs(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 I(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 d=is(c);throw new se(d,/nonce/i.test(d),s.status)}throw new I(s.status,s.statusText,`${this.baseUrl}${n}`,s.headers,c)}if(s.status!==204)return await s.json()}};function is(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 ae=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 ss=new TextEncoder().encode("calimero.auth.login.v1"),Mr={webOrigin:0,codeSigningId:1,cli:2};function _r(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 as(t){return g(Uint8Array.from([Mr[t.kind]]),_r(t))}function cs(t){let e=Uint8Array.from([Mr[t.kind]]);if(t.kind==="cli")return e;let n=_r(t);return g(e,w(n.length),n)}async function dt(t){let e=u(t.node,"node",32),n=u(t.challenge,"challenge",32),r=u(t.sessionKey,"sessionKey",32),o=await C(t.deviceSecret,t.signer,"deviceSecret"),i=u(o.publicKey,"signer.publicKey",32),a=x(t.issuedAt),s=x(t.expiresAt),c=await R(ss,[e,as(t.audience),n,r,i,a,s]),d=await o.sign(c);return h(g(e,cs(t.audience),n,r,i,a,s,d))}var ls=300;async function nn(){let t=h(crypto.getRandomValues(new Uint8Array(32)));return{publicKey:h(await J(t)),secret:t}}async function pt(t){let e=t.nodeUrl.replace(/\/+$/,""),n=t.timeoutMs??1e4,r=async(m,b)=>{let A=new AbortController,y=setTimeout(()=>A.abort(),n),v;try{let S={...b,signal:A.signal};v=t.fetch?await t.fetch(`${e}${m}`,S):await globalThis.fetch(`${e}${m}`,S)}catch(S){throw new I(0,S instanceof Error?S.name:"NetworkError",`${e}${m}`,new Headers,S instanceof Error?S.message:String(S))}finally{clearTimeout(y)}let E=await v.text().catch(()=>"");if(!v.ok)throw new I(v.status,v.statusText,`${e}${m}`,v.headers,E);return E?JSON.parse(E):{}},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 nn(),s=Math.floor(Date.now()/1e3),c=await dt({node:t.node,audience:t.audience,challenge:i,sessionKey:a.publicKey,issuedAt:s,expiresAt:s+(t.ttlSeconds??ls),signer:await C(t.deviceSecret,t.signer,"deviceSecret")}),d=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}})}),p=d.access_token??d.data?.access_token,l=d.refresh_token??d.data?.refresh_token;if(!p)throw new Error("the node minted no session");return{accessToken:p,refreshToken:l??"",sessionKey:a.publicKey,sessionSecret:a.secret}}var us=3e4;function gt(){let t=globalThis.location?.origin;return t?{kind:"webOrigin",origin:t}:{kind:"cli"}}function ds(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 fe=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-us>e?this.session.accessToken:(this.pending||(this.pending=this.loginNow().finally(()=>{this.pending=null})),(await this.pending).accessToken)}async loginNow(){let e=await pt({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=ds(e.accessToken),e}get events(){return this.sseClient||(this.sseClient=new $({baseUrl:this.config.nodeUrl,getAuthToken:()=>this.accessToken()})),this.sseClient}get ws(){return this.wsClient||(this.wsClient=new z({baseUrl:this.config.nodeUrl,getAuthToken:()=>this.accessToken()})),this.wsClient}close(){this.sseClient?.close(),this.wsClient?.close()}};var B=t=>new TextEncoder().encode(t),ps=B("calimero.auth.request.v1"),gs=B("calimero.auth.request.body.v1"),rn="X-Calimero-Proof",ms=300;async function on(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"?B(t.body):t.body,i=await R(gs,[o]),a=Math.floor(t.now??Date.now()/1e3),s=a+(t.validForSeconds??ms),c=await R(ps,[B(e),B(n),i,x(a),x(s)]),d=await hs(c,t);if(d.length!==64)throw new Error(`the signer returned ${d.length} bytes, not a 64-byte signature`);let p=g(w(B(e).length),B(e),w(B(n).length),B(n),i,x(a),x(s),d),l=fs(r,"credential");return h(g(l,new Uint8Array([0]),p))}async function hs(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 W(e.deviceSecret);return new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},n,t))}function fs(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 u(n,e,n.length/2)}function sn(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 on({method:e,path:n,body:r,credential:t.credential,deviceSecret:t.deviceSecret,signer:t.signer,validForSeconds:t.validForSeconds});return{[rn]:o}}}function ys(t){return new URL(t).pathname}var Gr=new TextEncoder().encode("calimero/presence/1");async function $r(t){let e=t===null?new Uint8Array([0]):g(new Uint8Array([1]),w(t.length),t);return new Uint8Array(await crypto.subtle.digest("SHA-256",e))}async function an(t){return g(Gr,u(t.contextId,"contextId",32),u(t.author,"author",32),x(t.seq),x(t.sentAtMs),await $r(t.state))}var bs=2500,Ue=class{constructor(e){this.timers=new Map;this.lastSeq=new Map;this.refused=new Set;this.generation=new Map;this.relay=e.relay,this.events=e.events,this.heartbeatMs=e.heartbeatMs??bs,this.now=e.now??Date.now}async set(e,n,r=Q()){let o=this.bump(e);this.refused.delete(e);let i=n===null?null:new Uint8Array(r.encode(n));await this.send(e,i),!(i===null||this.refused.has(e))&&this.generation.get(e)===o&&this.timers.set(e,setInterval(()=>{this.send(e,i).catch(()=>{})},this.heartbeatMs))}subscribe(e,n,r=Q()){return ze(this.events(),e,n,r)}close(){for(let e of new Set([...this.timers.keys(),...this.generation.keys()]))this.bump(e)}bump(e){this.stop(e);let n=(this.generation.get(e)??0)+1;return this.generation.set(e,n),n}stop(e){let n=this.timers.get(e);n!==void 0&&clearInterval(n),this.timers.delete(e)}nextSeq(e){let n=Math.max(this.now(),(this.lastSeq.get(e)??0)+1);return this.lastSeq.set(e,n),n}async send(e,n){if(this.refused.has(e))return;let r=await this.relay.authorSigner(),o=this.nextSeq(e),i=this.now(),a=await an({contextId:e,author:r.publicKey,seq:BigInt(o),sentAtMs:BigInt(i),state:n}),s=h(await r.sign(a));try{await this.relay.presenceIntent(e,{state:n===null?null:h(n),seq:o,sentAtMs:i,signature:s,authorProof:this.relay.authorProof})}catch(c){let d=c.status;if(d===void 0||d===0||d===429||d>=500)return;throw this.refused.add(e),this.stop(e),c}}};function Hr(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 qr(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 ws(t,e){let n=e?.nodeKey;return n?new fe({nodeUrl:e?.nodeUrl??t.relayUrl,nodeKey:n,accountProof:e?.accountProof??t.authorProof,audience:e?.audience??gt(),signer:e?.signer?async()=>e.signer:()=>t.authorSigner(),clientName:e?.clientName,ttlSeconds:e?.ttlSeconds,fetch:e?.fetch,timeoutMs:e?.timeoutMs}):null}var ce=class{constructor(e){this.relayObserver=null;this.relayAdmin=null;this.proofAuthorizer=null;this.relayUrl=null;this.proofEvents=null;this.relayPresence=null;if(e.transport==="relay"){this.transport="relay",this.nodeClient=null;let o=e.relay instanceof X?e.relay:new X(e.relay);if(this.relayObserver=ws(o,e.observe),this.rpcTransport=new ae(o,this.relayObserver),this.relayUrl=o.relayUrl,e.proof&&(this.proofAuthorizer=sn(e.proof)),e.session){let i=e.session;this.relayAdmin=Gn({baseUrl:o.relayUrl,getAuthToken:typeof i=="string"?async()=>i:i})}else if(this.proofAuthorizer){let i=this.proofAuthorizer;this.relayAdmin=Be(Ce({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 he(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 Hr("node connection","it holds a signing key and a relay URL, not a node");return this.nodeClient}get relay(){if(!(this.rpcTransport instanceof ae))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 $({baseUrl:this.relayUrl,authorize:this.proofAuthorizer})),this.proofEvents;throw qr("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."):qr("WebSocket events")}get ephemeral(){return this.nodeClient?this.nodeClient.ephemeral:(this.relayPresence??(this.relayPresence=new Ue({relay:this.relay,events:()=>this.events})),this.relayPresence)}get cloud(){if(!this.nodeClient)throw Hr("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 Lr(t){return new ce(t)}function ht(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 cn(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 As(t){return{getWarrantNonce:(e,n)=>t.client.getWarrantNonceAsAuthor(e,t.authorProof)}}var mt=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 xs(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??ht(1),r=t.onLookupFailure??"throw",o=null,i=null,a=async()=>{let s=await Promise.allSettled(e.map(p=>p.getWarrantNonce(t.contextId,t.authorDeviceKey))),c=null,d=!1;for(let p of s){if(p.status!=="fulfilled")continue;let l=p.value;if(l.kind==="exhausted"){d=!0;continue}(c===null||l.nextNonce>c)&&(c=l.nextNonce)}if(c===null&&d)throw new mt(t.contextId,t.authorDeviceKey);if(c===null){let p=s.find(m=>m.status==="rejected"),l=p&&p.status==="rejected"?p.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 Rs="Noise_NK_25519_AESGCM_SHA256",ln=32,vs=16,Cs=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,110,4,34,4,32]),dn=class t{constructor(e){this.k=null;this.n=0;this.ck=e,this.h=e}static async initialize(){let e=new TextEncoder().encode(Rs),n=new Uint8Array(32);return n.set(e),new t(n)}async mixHash(e){this.h=await ks(g(this.h,e))}async mixKey(e){let[n,r]=await jr(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:Br(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:Br(this.n),additionalData:this.h},this.k,e));return this.n+=1,await this.mixHash(e),n}split(){return jr(this.ck,new Uint8Array)}};async function Fr(t,e,n){let r=await dn.initialize();await r.mixHash(e),await r.mixHash(t);let o=await Ss(n);return await r.mixHash(o.publicKey),await r.mixKey(await Kr(o.privateKey,t)),{message1:g(o.publicKey,await r.encryptAndHash(new Uint8Array)),async finish(a){if(a.length<ln+vs)throw new Error("Noise: message 2 is too short");let s=a.slice(0,ln);return await r.mixHash(s),await r.mixKey(await Kr(o.privateKey,s)),{payload:await r.decryptAndHash(a.slice(ln)),split:await r.split()}}}}async function Ss(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",g(Cs,t),{name:"X25519"},!0,["deriveBits"]),n=await crypto.subtle.exportKey("jwk",e);return{privateKey:e,publicKey:Es(n.x)}}async function Kr(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 Br(t){let e=new Uint8Array(12);return new DataView(e.buffer).setBigUint64(4,BigInt(t),!1),e}async function ks(t){return new Uint8Array(await crypto.subtle.digest("SHA-256",t))}async function un(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 jr(t,e){let n=await un(t,e),r=await un(n,new Uint8Array([1])),o=await un(n,g(r,new Uint8Array([2])));return[r,o]}function Es(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 zr="/sealed/v2/handshake",Qr="/sealed/v2",Ne="application/vnd.calimero.sealed",pn=2,Is=new TextEncoder().encode("calimero/sealed-http/v2"),Oe=16,Ps=1+Oe+8,Ts=0,Ds=1,Us=2,Os=1+64*1024+16,Ns=1024,Ms=6e4,_s="calimero.tee-attest.transport-key.v1",Gs=[101,204,205,304],Yr=new TextEncoder,Me=class extends Error{constructor(){super("The node no longer holds the attested transport key; attest again for the current one");this.name="StaleTransportKeyError"}},ye=class extends Error{constructor(n,r,o,i){super(o);this.status=n;this.code=r;this.retryAfterMs=i;this.name="SealedTransportError"}};async function Xr(t,e){let n=await crypto.subtle.digest("SHA-256",g(Yr.encode(_s),t,e));return new Uint8Array(n)}async function Zr(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=h(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=u(o.transportPublicKey,"transportPublicKey",32),a=n.applicationHash?u(n.applicationHash,"applicationHash",32):new Uint8Array(32),s=h(await Xr(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 _e(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 eo({baseUrl:t.baseUrl,transportPublicKey:()=>Zr(r,t.verify,{applicationId:t.applicationId,applicationHash:t.applicationHash}),fetch:e})}function eo(t){let e=new URL(t.baseUrl),n=e.pathname.replace(/\/+$/,""),r=`${e.origin}${n}`,o=t.fetch??((l,m)=>fetch(l,m)),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 Wr(o,r,await Vr(a))}catch(l){if(!(l instanceof Me)||!i)throw l;return a=Promise.resolve().then(i),Wr(o,r,await Vr(a))}},d=async()=>{let l=s??p(void 0),m=await l;if(Date.now()<m.renewAt)return[m,l];let b=p(l);return[await b,b]},p=l=>{if(s===l){let m=c();s=m,m.catch(()=>{s===m&&(s=void 0)})}return s};return async(l,m)=>{let b=new Request(l,m),A=new URL(b.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 y=[];b.headers.forEach((D,_)=>y.push([_,D]));let v={method:b.method,path:A.pathname.slice(n.length)+A.search,headers:y},E=new Uint8Array(await b.arrayBuffer()),S=async D=>{let{requestId:_,header:ee,envelope:te}=await Hs(D,v,E),ne=await o(`${r}${Qr}`,{method:"POST",headers:{"content-type":Ne},body:te,signal:b.signal});if(ne.headers.get("content-type")!==Ne)throw await no(ne);return Ls(ne,D.responseKey,ee,_)},[F,M]=await d();try{return await S(F)}catch(D){if(!(D instanceof ye)||D.code!=="unknown_session")throw D;return S(await p(M))}}}async function Vr(t){let e=await t;if(e.length!==32)throw new Error("transportPublicKey must be 32 bytes");return e}async function Wr(t,e,n){try{return await Jr(t,e,n)}catch(r){if(!(r instanceof ye)||r.code!=="busy")throw r;return await new Promise(o=>setTimeout(o,r.retryAfterMs??1e3)),Jr(t,e,n)}}async function Jr(t,e,n){let r=await Fr(n,Is),o=await t(`${e}${zr}`,{method:"POST",headers:{"content-type":Ne},body:g(new Uint8Array([pn]),n,r.message1)});if(o.headers.get("content-type")!==Ne)throw await no(o);let i=await Bs(o,Ns);return $s(r,i)}async function $s(t,e){if(e[0]!==pn)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!==Oe+4)throw new Error("The handshake reply is malformed");let i=r.slice(0,Oe),a=new DataView(r.buffer,r.byteOffset).getUint32(Oe,!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-Ms,header(d){let p=new Uint8Array(Ps);return p[0]=pn,p.set(i,1),new DataView(p.buffer).setBigUint64(1+Oe,BigInt(d),!1),p}}}async function Hs(t,e,n){let r=t.nextRequestId;t.nextRequestId+=1;let o=t.header(r),i=await crypto.subtle.encrypt({name:"AES-GCM",iv:to(r,0),additionalData:o},t.requestKey,qs(e,n));return{requestId:r,header:o,envelope:g(o,new Uint8Array(i))}}function to(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 qs(t,e){let n=Yr.encode(JSON.stringify(t)),r=new Uint8Array(4);return new DataView(r.buffer).setUint32(0,n.length,!1),g(r,n,e)}async function Ls(t,e,n,r){if(!t.body)throw new Error("The sealed response has no body");let o=Ks(t.body.getReader()),i=0,a=async()=>{let p=await o.next();if(!p)return null;let l;try{l=new Uint8Array(await crypto.subtle.decrypt({name:"AES-GCM",iv:to(r,i),additionalData:n},e,p))}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!==Ts)throw new Error("The sealed response is malformed");let c=JSON.parse(new TextDecoder().decode(s.data));if(Gs.includes(c.status))return await o.cancel(),new Response(null,{status:c.status,headers:c.headers});let d=new ReadableStream({async pull(p){try{let l=await a();l?l.kind===Ds?p.enqueue(l.data):l.kind===Us?(p.close(),await o.cancel()):p.error(new Error("The sealed response is malformed")):p.error(new Error("The sealed response was cut short"))}catch(l){p.error(l)}},cancel(){return o.cancel()}});return new Response(d,{status:c.status,headers:c.headers})}function Ks(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=g(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>Os)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 Bs(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=g(r,i),r.length>e)throw await n.cancel(),new Error("The handshake reply is malformed: it is too long")}}async function no(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 Me;let r=Number(t.headers.get("retry-after")),o=Number.isFinite(r)&&r>0?Math.min(r,5)*1e3:void 0;return new ye(t.status,e,n,o)}async function ro(t){if(!t.sessionToken&&!t.googleIdToken)throw new Error("connectCloud needs either a sessionToken or a googleIdToken");let e=await C(t.deviceSecret,t.signer,"deviceSecret"),n=new q({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=Fs(r,t.namespaceId),i=await n.getNamespaceRelays(o.namespaceId),a=Kt(i);if(!a)throw new Error(Vs(o,i));let s=new X({relayUrl:a.relayUrl,executorAccount:a.executorAccount,authorAccount:t.authorAccount,authorProof:t.authorProof,signer:e,nonces:t.nonces??Ws(e.publicKey),ttlSeconds:t.ttlSeconds,fetch:t.seal?_e({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,d,p)=>s.execute(c,d,p),client:new ce({transport:"relay",relay:s,observe:{nodeKey:t.relayNodeKey??a.nodeKey,audience:t.observeAudience,fetch:t.fetch,timeoutMs:t.timeoutMs}})}}async function js(t){let{root:e,authorAccount:n,...r}=t,o=await C(r.deviceSecret,r.signer,"deviceSecret"),i=await K(e),s=await new q({cloudBaseUrl:t.cloudBaseUrl,onSession:t.onSession,fetch:t.fetch,timeoutMs:t.timeoutMs}).signInWithAccount(i.signer);return ro({...r,deviceSecret:void 0,signer:o,sessionToken:s.sessionToken,authorAccount:n??i.accountId})}function Fs(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 Vs(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 Ws(t){let e=`mero-js:warrant-nonce:${t}`;try{return cn(e)}catch{return ht(1)}}var Js="https://cloud.calimero.network";function io(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??Js);return e.searchParams.set("link-account",t.accountId),e.searchParams.set("callback-url",t.returnTo),e.toString()}function zs(t){throw window.location.assign(io(t)),new Error("redirecting to the cloud to authorise this link")}function Qs(t=window.location){let e=new URLSearchParams(t.hash.replace(/^#/,"")),n=e.get("error");if(n)throw oo(),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:(oo(),{grant:r,account:o})}function oo(){typeof history>"u"||!history.replaceState||history.replaceState(null,"",location.pathname+location.search)}async function Ys(t){let e=await K(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 q({cloudBaseUrl:t.cloudBaseUrl,fetch:t.fetch}).linkAccountWithGrant({grant:t.grant,signer:e.signer})}var Xs="enrol-device",Zs="enrol-kem",ea="callback-url",ta="state";function co(t){ao(t.devicePublicKey,"devicePublicKey"),ao(t.kemPublicKey,"kemPublicKey"),sa(t.returnTo),ia(t.returnTo);let e=new URL(t.walletUrl);return e.searchParams.set(Xs,t.devicePublicKey),e.searchParams.set(Zs,t.kemPublicKey),e.searchParams.set(ea,t.returnTo),t.state&&e.searchParams.set(ta,t.state),e.toString()}function na(t){throw window.location.assign(co(t)),new Error("redirecting to the wallet to approve this device")}function ra(t=window.location){let e=new URLSearchParams(t.hash.replace(/^#/,"")),n=e.get("error");if(n)throw so(),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;so();let a=e.get("state");return{credential:r,account:o,device:i,...a?{state:a}:{}}}function so(){typeof history>"u"||!history.replaceState||history.replaceState(null,"",location.pathname+location.search)}async function oa(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 Ye(t.credential);if(e.signPublicKey!==le(t.devicePublicKey))throw new Error(`this credential certifies device key ${e.signPublicKey}, but this app holds ${le(t.devicePublicKey)} \u2014 it would sign with a key the certificate does not cover`);if(t.kemPublicKey!==void 0&&e.kemPublicKey!==le(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!==le(t.account))throw new Error(`the wallet reported account ${le(t.account)}, but the credential names ${e.account}`);if(e.device!==le(t.device))throw new Error(`the wallet reported device ${le(t.device)}, but the credential names ${e.device}`);return{credential:t.credential,account:e.account,device:e.device,certificate:e}}function ao(t,e){if(!/^[0-9a-f]{64}$/.test(t))throw new Error(`${e} must be 64 lowercase hex characters`)}function le(t){return t.trim().toLowerCase()}function lo(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 ia(t){lo(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 sa(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 aa=new TextEncoder().encode("calimero.mdma.account-ownership-claim.v1\0"),ca=6e4,uo=5*6e4;function po(t){let e="";for(let n of t)e+=String.fromCharCode(n);return btoa(e)}var gn=(t,e)=>{if(!/^[0-9a-fA-F]{64}$/.test(t))throw new Error(`${e} must be 64 hex characters`);return t.toLowerCase()};async function la(t){let e=t.ttlMs??ca;if(!(e>0&&e<=uo))throw new Error(`ttlMs must be in (0, ${uo}]`);if(!t.subject)throw new Error("subject must be the cloud login email");let n=await C(t.deviceSecret,t.signer,"deviceSecret"),r=(t.now??Date.now)(),o=Array.from(crypto.getRandomValues(new Uint8Array(16)),s=>s.toString(16).padStart(2,"0")).join(""),i=new TextEncoder().encode(JSON.stringify({v:1,audience:"mdma:enable-ha-namespace",group_id:gn(t.namespaceId,"namespaceId"),account_id:gn(t.accountId,"accountId"),salt:gn(t.salt,"salt"),subject:t.subject,nonce:o,issued_at_ms:r,expires_at_ms:r+e})),a=await n.sign(g(aa,i));return{kind:"account",credential:t.credential,signed_payload:po(i),signature:po(a)}}var ua=/^[0-9a-f]{96}$/,da=["mrtd","rtmr0","rtmr1","rtmr2","rtmr3"];function mn(t){let e=be(t.allowedMrtd??[],"allowedMrtd"),n=(t.allowedMeasurements??[]).map((s,c)=>{let d=`allowedMeasurements[${c}]`;return da.map(p=>be([s?.[p]??""],`${d}.${p}`)[0]).join()}),r=[be(t.allowedRtmr0??[],"allowedRtmr0"),be(t.allowedRtmr1??[],"allowedRtmr1"),be(t.allowedRtmr2??[],"allowedRtmr2"),be(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:d,collateral:p})=>{let l=ga(s),m=p??await t.fetchCollateral?.(l);if(!m)throw new Error("The node sent no collateral for its quote, and no fetchCollateral was given to get it");let b;try{b=t.dcapVerify(l,m,Math.floor(i()/1e3))}catch(E){throw new Error(`The quote did not verify: ${E?.message??String(E)}`)}if(b.status==="Revoked"||!o.includes(b.status))throw new Error(`The platform's TCB status is ${b.status}, which is not accepted`);let A=pa(b.report),y=[A.mrTd,A.rtMr0,A.rtMr1,A.rtMr2,A.rtMr3].map(E=>h(E));if(n.length>0&&!n.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([A.rtMr0,A.rtMr1,A.rtMr2,A.rtMr3].forEach((E,S)=>{let F=r[S];if(F.length>0&&!F.includes(h(E)))throw new Error(`RTMR${S} ${h(E)} is not one this verifier trusts`)}),h(A.reportData)!==`${c}${d}`.toLowerCase())throw new Error("The quote does not commit to this nonce and binding");return!0},{includeCollateral:!0})}function be(t,e){return t.map(n=>{let r=n.trim().toLowerCase();if(!ua.test(r))throw new Error(`${e} holds ${JSON.stringify(n)}, which is not a 48-byte hex measurement`);return r})}function pa(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 ga(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 ma=["UpToDate","SWHardeningNeeded","ConfigurationNeeded","ConfigurationAndSWHardeningNeeded","OutOfDate","OutOfDateConfigurationNeeded"];function hn(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 d=Object.keys(o?.profiles??{}).join(", ")||"none";throw new Error(`${a} has no profile ${JSON.stringify(e)} (it has: ${d})`)}let c=(s.allowed_tcb_statuses??["uptodate"]).map(d=>ha(d,a));return n=n===void 0?c:n.filter(d=>c.includes(d)),{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 ha(t,e){let n=ma.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 go=[{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"]}],mo=[{baseUrl:"https://rekor.sigstore.dev",logId:"c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d",publicKey:"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE2G2Y+2tabdTV5BcGiBIx0a9fAFwrkBbmLSGtks4L3qX6yYY0zufBnhC8Ur/iy55GhWP/9A/bY2LhC30M9+RYtw==",validFor:{start:"2021-01-12T11:53:27Z"}}];var fa="1.2.840.10045.2.1",ya={"1.2.840.10045.3.1.7":"P-256","1.3.132.0.34":"P-384"},ba={"P-256":32,"P-384":48},wa={"1.2.840.10045.4.3.2":"SHA-256","1.2.840.10045.4.3.3":"SHA-384"};function ho(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 Ae(t){let e=ho(t,0,t.length);if(e.end!==t.length)throw new Error("it has trailing bytes");return e}function O(t){let e=[];for(let n=t.start;n<t.end;){let r=ho(t.bytes,n,t.end);e.push(r),n=r.end}return e}function P(t,e,n){if(!t||t.tag!==e)throw new Error(`${n} is not where it should be`);return t}function Z(t){return t.bytes.slice(t.start,t.end)}function ft(t){return t.bytes.slice(t.offset,t.end)}function we(t){let e=Z(P(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 Aa(t){let e=new TextDecoder().decode(Z(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,d,p]=o.slice(2).map(Number);return Date.UTC(i,a-1,s,c,d,p)}function fn(t){try{let[e,n,r,...o]=O(P(Ae(t),48,"The certificate"));if(o.length>0)throw new Error("it has fields after its signature");let i=O(P(e,48,"The signed part")),a=i[0]?.tag===160?1:0,[s,c,d,p,l,m,...b]=i.slice(a);P(s,2,"The serial number");let A=we(O(P(n,48,"The signature algorithm"))[0]);if(we(O(P(c,48,"The signature algorithm"))[0])!==A)throw new Error("it names two different signature algorithms");let v=wa[A];if(!v)throw new Error(`it is signed with ${A}, not ECDSA with SHA-256 or SHA-384`);let[E,S]=O(P(p,48,"The validity")).map(Aa);if(S===void 0)throw new Error("its validity is incomplete");let[F,M]=O(P(m,48,"The public key"));P(M,3,"The public key");let[D,_]=O(P(F,48,"The key algorithm"));if(we(D)!==fa)throw new Error("its key is not an elliptic-curve key");let ee=ya[we(_)];if(!ee)throw new Error("its key is on a curve other than P-256 or P-384");let te=new Map,ne=b.find(Rt=>Rt.tag===163);if(ne){let[Rt]=O(ne);for(let ri of O(P(Rt,48,"The extensions"))){let ue=O(P(ri,48,"An extension"));if(ue.length===3)P(ue[1],1,"An extension's critical flag");else if(ue.length!==2)throw new Error("it has a malformed extension");let vt=we(ue[0]);if(te.has(vt))throw new Error(`it has extension ${vt} twice`);te.set(vt,Z(P(ue[ue.length-1],4,"An extension value")))}}let Tn=Z(P(r,3,"The signature"));if(Tn[0]!==0)throw new Error("its signature is not a whole number of bytes");return{der:t,tbs:ft(e),signatureHash:v,signature:Tn.slice(1),issuer:ft(P(d,48,"The issuer")),subject:ft(P(l,48,"The subject")),notBefore:E,notAfter:S,spki:ft(m),curve:ee,extensions:te}}catch(e){throw new Error(`The certificate is malformed: ${e.message}`)}}function fo(t){return O(P(Ae(t),48,"The list")).map(we)}function xa(t,e){let n=ba[e],r=O(P(Ae(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=Z(P(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 yt(t,e,n,r,o){let i;try{i=xa(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 L(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 yn(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 L(n[0][1],e)}var Ra="2.5.29.17",va="2.5.29.37",Ca="1.3.6.1.5.5.7.3.3",Sa="1.3.6.1.4.1.57264.1.8",ka="1.3.6.1.4.1.57264.1.1",Ea=134,Ia=12,Pa=48,Ta=new TextEncoder,xe=t=>new TextDecoder().decode(t);async function yo(t,e,n,r){let{base64Signature:o,cert:i,rekorBundle:a}=Na(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=L(o,"The bundle signature"),d=yn(xe(L(i,"The bundle certificate")),"The bundle certificate"),p=fn(d),l=mo.find(S=>S.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 m=Ta.encode(`{"body":${JSON.stringify(s.body)},"integratedTime":${s.integratedTime},"logID":${JSON.stringify(s.logID)},"logIndex":${s.logIndex}}`);if(!await yt(L(l.publicKey,"The Rekor key"),"P-256","SHA-256",L(a.SignedEntryTimestamp,"The signed entry timestamp"),m))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(!Ao(A,l.validFor))throw new Error(`Rekor log ${l.baseUrl} was not in use at ${Ge(A)}, when the entry says it was logged`);let y=Ma(s.body),v=h(new Uint8Array(await crypto.subtle.digest("SHA-256",t)));if(y.hash!==v)throw new Error("The file's SHA-256 is not the one Rekor logged: the file is not the one signed");if(!bn(L(y.signature,"The logged signature"),c))throw new Error("The bundle's signature is not the one Rekor logged");let E=yn(xe(L(y.publicKey,"The logged certificate")),"The logged certificate");if(!bn(E,d))throw new Error("The bundle's certificate is not the one Rekor logged");if(p.curve!=="P-256"||!await yt(p.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 Da(p,A),Oa(p,n),{integratedTime:s.integratedTime}}async function Da(t,e){if(!wo(t,e))throw new Error(`The signing certificate was valid ${Ge(t.notBefore)} to ${Ge(t.notAfter)}, not at ${Ge(e)} when Rekor logged it`);let n=[];for(let r of go){let o=r.certChain.map(a=>fn(L(a,"A Fulcio certificate")));if(!await bo(t,o[0]))continue;let i=await Ua(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 ${Ge(e)}: ${n.join("; ")}`:"The signing certificate was not issued by a Fulcio CA in the Sigstore trust root")}async function Ua(t,e,n){if(!Ao(n,e))return"the trust root says it was not issuing certificates then";for(let[r,o]of t.entries()){if(!wo(o,n))return`its certificate ${r} was not valid then`;let i=t[r+1]??o;if(!await bo(o,i))return`its certificate ${r} is not signed by the next`}}async function bo(t,e){return bn(t.issuer,e.subject)?yt(e.spki,e.curve,t.signatureHash,t.signature,t.tbs):!1}function Oa(t,e){let n=t.extensions.get(Ra);if(!n)throw new Error("The signing certificate names no identity");let r=O(P(Ae(n),Pa,"The subject alternative name")),o=r.filter(d=>d.tag===Ea).map(d=>xe(Z(d)));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(Sa),a=t.extensions.get(ka),s=i?xe(Z(P(Ae(i),Ia,"The OIDC issuer"))):a?xe(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(va);if(!c||!fo(c).includes(Ca))throw new Error("The signing certificate is not for code signing")}function Na(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 Ma(t){let e;try{e=JSON.parse(xe(L(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 wo(t,e){return t.notBefore<=e&&e<=t.notAfter}function Ao(t,e){return Date.parse(e.start)<=t&&(e.end===void 0||t<=Date.parse(e.end))}function Ge(t){return new Date(t).toISOString()}function bn(t,e){return t.length===e.length&&t.every((n,r)=>n===e[r])}var wn=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"}),_a=["mrtd","rtmr0","rtmr1","rtmr2","rtmr3"],Ro="https://cloud.calimero.network";async function vo(t,e,n={}){let r=typeof t=="string"?new TextEncoder().encode(t):t;await yo(r,e,{identity:n.identity??wn.identity,issuer:n.issuer??wn.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=>_a.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 Co(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 So(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 ko(t,e={}){let n=await Io(t,e.fetch??fetch);if(n===void 0)throw new Error(`${Eo(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 Eo(t){return`${t.replace(/\/+$/,"")}/admin-api/tee/info`}async function Io(t,e){let n=Eo(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 So(o)}function Po(t,e){return`${t.replace(/\/+$/,"")}/api/tee/node-releases/${$e(e,"version")}`}async function To(t){let e=$e(t.minReleaseVersion,"minReleaseVersion"),n=$e(t.release?.version,"The release version"),r=await vo(t.release.publishedMrtds,t.release.bundle,{expectedVersion:n,identity:t.identity,issuer:t.issuer});if($a(n,e)<0)throw new Error(`Release ${n} is older than the minimum trusted, ${e}`);return hn([r],{profile:t.profile})}function Do(t){return $e(t.minReleaseVersion,"minReleaseVersion"),Object.assign(async n=>{let r=await To({release:await t.release(),profile:t.profile,minReleaseVersion:t.minReleaseVersion,identity:t.identity,issuer:t.issuer});return mn({dcapVerify:t.dcapVerify,fetchCollateral:t.fetchCollateral,now:t.now,...r})(n)},{includeCollateral:!0})}function Ga(t){let{baseUrl:e,releaseSource:n,releaseVersion:r,applicationId:o,applicationHash:i,fetch:a,...s}=t;r!==void 0&&$e(r,"releaseVersion");let c=a??((p,l)=>fetch(p,l));return _e({baseUrl:e,verify:Do({...s,release:async()=>{let p=r===void 0?await ko(e,{fetch:c}):await Io(e,c)??r;return typeof n=="function"?n({baseUrl:e,version:p,fetch:c}):Co(Po(n??Ro,p),{fetch:c})}}),applicationId:o,applicationHash:i,fetch:c})}var Uo=/^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/;function $e(t,e){let n=typeof t=="string"?Uo.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 $a(t,e){let[n,r]=xo(t),[o,i]=xo(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[d,p]=[a[c],s[c]];if(d===void 0||p===void 0)return d===void 0?-1:1;let[l,m]=[/^\d+$/.test(d),/^\d+$/.test(p)],b=l&&m?Math.sign(Number(d)-Number(p)):l!==m?l?-1:1:d<p?-1:d>p?1:0;if(b!==0)return b}return 0}function xo(t){let e=Uo.exec(t);return[[Number(e[1]),Number(e[2]),Number(e[3])],e[4]]}var bt=1440*60,xn={Admin:0,Member:1,ReadOnly:2};function He(t){let e=t.admitters??[];return g(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)=>u(n,`admitters[${r}]`,32)))}async function Rn(t){return new Uint8Array(await crypto.subtle.digest("SHA-256",He(t)))}function vn(t){return[...new Set(t.filter(n=>n.role==="Admin").map(n=>n.identity.toLowerCase()))].sort()}async function Oo(t){let e=await C(t.deviceSecret,t.signer,"deviceSecret"),n=u(e.publicKey,"signer.publicKey",32),r=u(t.groupId,"groupId",32);u(t.inviterAccount,"inviterAccount",32);let o=[...t.admitters??[]].map(m=>m.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=vn(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((m,b)=>u(m,`admitters[${b}]`,32));let i=t.invitedRole??xn.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??bt,bt);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 d={inviter_identity:Array.from(n),group_id:Array.from(r),expiration_timestamp:a+s,secret_salt:Array.from(c),invited_role:i,admitters:o},p=await e.sign(await Rn(d));if(p.length!==64)throw new Error(`signer returned ${p.length} bytes, expected a 64-byte Ed25519 signature`);let l={invitation:d,inviter_signature:h(p),inviter_account:t.inviterAccount.trim().toLowerCase()};return t.admitterAddrs?.length&&(l.admitter_addrs=[...t.admitterAddrs]),t.applicationId&&(l.application_id=Array.from(u(t.applicationId,"applicationId",32))),t.appKey&&(l.app_key=Array.from(u(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 Cn=20,Ha=new TextEncoder().encode("calimero.namespace.v1"),qa=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 Mo(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 g(new Uint8Array([1]),new Uint8Array(t))}function _o(t){let e=new TextEncoder().encode(t);return g(w(e.length),e)}function wt(t){let e=t.invitation,n=t.admitter_addrs??[];return g(He(e),_o(t.inviter_signature),t.inviter_account?g(new Uint8Array([1]),u(t.inviter_account,"inviter_account",32)):new Uint8Array([0]),w(n.length),...n.map(_o),Mo(t.application_id,"application_id"),Mo(t.app_key,"app_key"))}async function Go(t){let e=t.parentOpHashes??[],n=u(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?g(new Uint8Array([No.MemberJoinedAt]),u(t.member,"member",32),wt(t.invitation),x(o),n):g(new Uint8Array([No.MemberJoined]),u(t.member,"member",32),wt(t.invitation),n),a=g(new Uint8Array([qa]),i),s=await C(t.deviceSecret,t.signer,"deviceSecret"),c=u(s.publicKey,"signer.publicKey",32),d=g(new Uint8Array([Cn]),u(t.namespaceId,"namespaceId",32),w(e.length),...e.map((m,b)=>u(m,`parentOpHashes[${b}]`,32)),c,x(t.nonce),a),p=await s.sign(g(Ha,d)),l=new Uint8Array([0]);return h(g(d,p,l))}var La=new TextEncoder().encode("calimero.account.owner-op.v1"),Ka=new TextEncoder().encode("calimero.account.owner-op.body.v1"),Ba=new TextEncoder().encode("calimero.account.genesis.v1"),ja=2,Sn={transferOwnership:0,adminChanged:1,groupDelete:2,teeAdmissionPolicy:3,teeAuthoringPolicy:4,teeReleaseAdmissionPolicy:5},Re={GroupDelete:14,TransferOwnership:21,TeeAuthoringPolicySet:33,TeeAdmissionPolicySetV2:37,TeeReleaseAdmissionPolicySetV2:38,RootGuarded:42},Ho={AdminChanged:3,RootGuarded:12},Fa={replica:0,relay:1},Va=new TextEncoder;function N(t){return new Uint8Array([t])}function qo(t){let e=Va.encode(t);return g(w(e.length),e)}function j(t){return g(w(t.length),...t.map(qo))}function Lo(t){return N(t?1:0)}function Ko(t){let e=Fa[t??"replica"];if(e===void 0)throw new Error(`mode must be replica or relay, got ${String(t)}`);return N(e)}function Bo(t){return{kind:"transferOwnership",plane:"group",bytes:g(N(Re.TransferOwnership),u(t,"newOwner",32))}}function jo(){return{kind:"groupDelete",plane:"group",bytes:N(Re.GroupDelete)}}function Fo(t){return{kind:"adminChanged",plane:"root",bytes:g(N(Ho.AdminChanged),u(t,"newAdmin",32))}}function Vo(t){return{kind:"teeAuthoringPolicy",plane:"group",bytes:g(N(Re.TeeAuthoringPolicySet),j(t))}}function Wo(t){return{kind:"teeAdmissionPolicy",plane:"group",bytes:g(N(Re.TeeAdmissionPolicySetV2),j(t.allowedMrtd),j(t.allowedRtmr0),j(t.allowedRtmr1),j(t.allowedRtmr2),j(t.allowedRtmr3),j(t.allowedTcbStatuses),Lo(t.acceptMock),Ko(t.mode))}}function Jo(t){let e=t.minReleaseVersion===void 0?N(0):g(N(1),qo(t.minReleaseVersion));return{kind:"teeReleaseAdmissionPolicy",plane:"group",bytes:g(N(Re.TeeReleaseAdmissionPolicySetV2),j(t.allowedProfiles),e,j(t.allowedTcbStatuses),Lo(t.acceptMock),Ko(t.mode))}}async function kn(t){return R(Ka,[t])}async function En(t){return R(La,[u(t.account,"account",32),u(t.namespaceId,"namespaceId",32),u(t.groupId,"groupId",32),N(zo(t.kind)),t.opDigest,x(t.counter),w(t.keyEpoch)])}function zo(t){let e=Sn[t];if(e===void 0)throw new Error(`unknown owner-op kind ${String(t)}`);return e}var $o=132;async function Qo(t){let e=await J(t.rootSecret),n=g(N(ja),e),r=h(await R(Ba,[n])),o=t.keyEpoch??0,i=(t.chain??[]).map((p,l)=>{let m=G(p,`chain[${l}]`);if(m.length!==$o)throw new Error(`chain[${l}] must be a ${$o}-byte RootKeyHandoff, got ${m.length}`);return m});if(o>i.length)throw new Error(`keyEpoch ${o} needs ${o} handoffs in chain, got ${i.length}`);let a=await kn(t.op.bytes),s=await En({account:r,namespaceId:t.namespaceId,groupId:t.groupId,kind:t.op.kind,opDigest:a,counter:t.counter,keyEpoch:o}),c=await W(t.rootSecret),d=new Uint8Array(await crypto.subtle.sign("Ed25519",c,s));return h(g(n,w(i.length),...i,u(r,"account",32),u(t.namespaceId,"namespaceId",32),u(t.groupId,"groupId",32),N(zo(t.op.kind)),a,x(t.counter),w(o),d))}function Yo(t,e){let n=t.plane==="group"?Re.RootGuarded:Ho.RootGuarded;return g(N(n),t.bytes,G(e,"rootProof"))}var Xo=[2428,2429,2528,2529],Wa="localhost",Ja=2e3;function Zo(t){return`http://${Wa}:${t}`}function ei(t,e){let n=t.endsWith("/")?t:`${t}/`;return new URL(e,n).toString()}async function ti(t,e={}){let{timeoutMs:n=Ja,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=ei(t,"admin-api/health"),d=await fetch(c,{method:"GET",signal:o.signal});if(!d.ok)return!1;try{let p=await d.json(),l=p?.data?.status!==void 0?p?.data?.status:p?.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 za(t={}){let{ports:e=Xo,timeoutMs:n,signal:r}=t;return(await Promise.all(e.map(async i=>{let a=Zo(i);return await ti(a,{timeoutMs:n,signal:r})?a:null}))).filter(i=>i!==null)}var Qa=new TextEncoder().encode("calimero.tee-attest.key-binding.v1"),At=new TextEncoder().encode("MOCK_TDX_QUOTE_V1"),Ya=568;function Xa(...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 In(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 Za(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 ec(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 xt(t){let e=await crypto.subtle.digest("SHA-256",Xa(Qa,new Uint8Array(32),t));return new Uint8Array(e)}function Pn(t){let e=t.length>=At.length&&In(t.subarray(0,At.length),At),n=e?At.length:Ya;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 ni(t){let e=crypto.getRandomValues(new Uint8Array(32)),n=`${t.relayUrl.replace(/\/+$/,"")}/admin-api/tee/attest`,r=JSON.stringify({nonce:h(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 m=await i.text().catch(()=>"");throw new Error(`the relay would not attest (HTTP ${i.status})${m?`: ${m}`:""}`)}let a=await i.json(),s=a.data??a;if(typeof s.quoteB64!="string")throw new Error("the relay returned no quote");let c=ec(s.boundPublicKey,"boundPublicKey"),d=Za(s.quoteB64),{reportData:p,mock:l}=Pn(d);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:h(e),reportDataSuffix:h(await xt(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(d);else throw new Error("a real TDX quote needs a verify (or verifyQuote) to check its signature and measurements");if(!In(p.subarray(0,32),e))throw new Error("the quote does not carry our nonce: it was not made for this request");if(!In(p.subarray(32,64),await xt(c)))throw new Error("the quote does not bind the key the relay named: refusing it");return{nodeKey:h(c),mock:l}}export{ie as AdminApiClient,re as AuthApiClient,V as AuthRevokedError,T as CAPABILITIES,Ac as CAPABILITY_PRESETS,q as CloudClient,Xo as DEFAULT_LOCAL_NODE_PORTS,Ro as DEFAULT_RELEASE_MIRROR,Ee as EphemeralClient,zr as HANDSHAKE_PATH,I as HTTPError,xn as INVITED_ROLE,se as IntentRefusedError,Ft as LocalStorageTokenStore,bt as MAX_INVITATION_VALIDITY_SECS,jt as MemoryTokenStore,ce as MeroClient,he as MeroJs,wn as NODE_RELEASE_SIGNER,Sn as OWNER_OP_KIND,Gr as PRESENCE_DOMAIN,rn as REQUEST_PROOF_HEADER,X as RelayClient,fe as RelayObserver,Ue as RelayPresenceClient,ae as RelayTransport,ke as RpcClient,We as RpcError,Ne as SEALED_CONTENT_TYPE,Qr as SEALED_PATH,Cn as SIGNED_NAMESPACE_OP_SCHEMA_VERSION,ye as SealedTransportError,$ as SseClient,Me as StaleTransportKeyError,mt as WarrantNonceExhaustedError,Ke as WarrantNonceRouteUnavailableError,ve as WebHttpClient,z as WsClient,Xe as accountForRoot,H as accountForRootPublicKey,Xn as accountRootFromPhrase,Ht as accountRootFromSecret,er as accountRootSignerFromPhrase,Fo as adminChangedOp,Gi as admitterAddrsFromNetworkStatus,xt as attestKeyBinding,ni as attestRelayNodeKey,As as authorNonceLookup,zs as beginCloudLink,na as beginDeviceEnrolment,Ut as buildAuthLoginUrl,lo as callbackIsForeign,Fe as callerProof,xc as capMask,Rc as capNames,Pt as classifyError,io as cloudLinkUrl,Po as cloudNodeReleaseUrl,Ct as combineSignals,fi as compareSemver,Ys as completeCloudLink,oa as completeDeviceEnrolment,ro as connectCloud,js as connectCloudWithAccount,Ur as contextCapabilityGrantedOp,Or as contextCapabilityRevokedOp,kr as contextDetachedOp,Tr as contextMetadataSetOp,Zn as createAccountRootSigner,Gn as createAdminApiClient,Be as createAdminApiClientFromHttpClient,_e as createAttestedSealedFetch,bc as createAuthApiClient,Un as createAuthApiClientFromHttpClient,Hc as createBrowserAdminApiClient,fc as createBrowserAuthApiClient,de as createBrowserHttpClient,Ce as createHttpClient,cn as createLocalStorageNonceSource,ht as createMemoryNonceSource,Lr as createMeroClient,Li as createMeroJs,qc as createNodeAdminApiClient,yc as createNodeAuthApiClient,qe as createNodeHttpClient,sn as createProofAuthorizer,Ve as createProofSigner,mn as createQuoteVerifier,xs as createRecoveringNonceSource,li as createRetryableMethod,eo as createSealedFetch,Ga as createSignedReleaseSealedFetch,Do as createSignedReleaseVerifier,St as createTimeoutSignal,kt as createUniversalHttpClient,Xt as createdSubgroupId,Wt as creationInitHash,vn as defaultAdmitters,gt as defaultAudience,at as defaultCapabilitiesSetOp,Qe as deviceCertPayload,co as deviceEnrolmentUrl,_t as deviceScopePayload,za as discoverLocalNodes,He as encodeGroupInvitation,wt as encodeSignedInvitation,Zr as fetchAttestedTransportKey,Co as fetchNodeRelease,ko as fetchNodeReleaseVersion,ct as foundedNamespaceId,Yn as generateAccountRoot,nn as generateSessionKey,Jt as governanceOpHash,Zt as groupCreatedOp,jo as groupDeleteOp,Cr as groupDeletedOp,Rn as groupInvitationHash,Ir as groupMetadataSetOp,vr as groupReparentedOp,oe as hasCap,Nc as hexEncodeUtf8,Vt as intentHash,gi as isSettled,Q as jsonCodec,Zo as localNodeUrl,pt as login,br as memberAddedOp,Sr as memberCapabilitySetOp,Nr as memberJoinedOpenOp,Ar as memberLeftOp,Pr as memberMetadataSetOp,wr as memberRemovedOp,xr as memberRoleSetOp,Vn as mintDeviceId,lt as namespaceCreatedOp,ei as nodeEndpoint,So as nodeReleaseVersionFromImage,kn as ownerOpDigest,En as ownerOpSigningPayload,Dt as parseAuthCallback,mr as parseCreationWarrant,Mt as parseDeviceCredential,hr as parseGovernanceWarrant,Nn as parseWarrantNonce,an as presenceStatementBytes,ti as probeNodeHealth,Qs as readCloudLinkCallback,ra as readEnrolmentCallback,On as redeemInvitation,Pn as reportDataOf,Ot as requestBodyHash,K as resolveRoot,Ze as resolveRootPair,Yo as rootGuardedOpBytes,tt as routingProofHeaders,Ec as shouldRetain,Ie as signAccountLink,et as signAccountLogin,la as signAccountOwnershipClaim,ot as signCreationWarrant,Jn as signDeviceCert,zn as signDeviceScope,Te as signGovernanceWarrant,Oo as signGroupInvitation,dt as signLoginStatement,Go as signMemberJoinOp,Qo as signOwnerOpProof,je as signRequest,on as signRequestProof,ur as signRoutingChallenge,nt as signWarrant,ys as signedPath,jn as signerFromCryptoKey,pe as signerFromSecret,$r as stateHash,Rr as subgroupCreation,Er as subgroupVisibilitySetOp,ze as subscribePresence,st as targetApplicationSetOp,Wo as teeAdmissionPolicyOp,Vo as teeAuthoringPolicyOp,Jo as teeReleaseAdmissionPolicyOp,Bo as transferOwnershipOp,Xr as transportKeyBinding,To as trustSignedRelease,hn as trustedMeasurementsFromReleases,Ye as verifyDeviceCredential,vo as verifySignedNodeRelease,Et as withCap,Le as withRetry,vc as withoutCap};
3
3
  //# sourceMappingURL=index.browser.mjs.map