@calimero-network/mero-js 23.8.1 → 23.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,3 @@
1
- function Tt(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 Dt(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 fi=new Set(["token_reuse","token_revoked"]);function yi(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 S=class extends Error{constructor(n,r,o,i,a){let s=yi(a)??(n===0&&a?.trim()?a.trim():void 0);super(s?`HTTP ${n} ${r}: ${s}`:`HTTP ${n} ${r}`);this.status=n;this.statusText=r;this.url=o;this.headers=i;this.bodyText=a;this.name="HTTPError";this.explanation=s}toJSON(){return{status:this.status,statusText:this.statusText,url:this.url,headers:Hn(this.headers),bodyText:this.bodyText}}},V=class extends S{constructor(n,r,o,i,a,s){super(r,o,i,a,s);this.reason=n;this.name="AuthRevokedError";this.message=`Authentication revoked (${n}): HTTP ${r} ${o}`}};function Hn(t){let e={};return t.forEach((n,r)=>{e[r]=n}),e}function bi(t){try{return new URL(t).pathname}catch{let e=t.indexOf("?");return e===-1?t:t.slice(0,e)}}var Ce=class{constructor(e){this.transport=e;this.refreshTokenPromise=null;this.onTokenRefreshPromise=null}async get(e,n){return this.request(e,{...n,method:"GET"})}async post(e,n,r){return this.request(e,{...r,method:"POST",body:n?JSON.stringify(n):void 0,headers:{"Content-Type":"application/json",...r?.headers}})}async put(e,n,r){return this.request(e,{...r,method:"PUT",body:n?JSON.stringify(n):void 0,headers:{"Content-Type":"application/json",...r?.headers}})}async delete(e,n){return this.request(e,{...n,method:"DELETE"})}async patch(e,n,r){return this.request(e,{...r,method:"PATCH",body:n?JSON.stringify(n):void 0,headers:{"Content-Type":"application/json",...r?.headers}})}async head(e,n){let r=await this.makeRequest(e,{...n,method:"HEAD",parse:"response"});return{headers:Hn(r.headers),status:r.status}}async request(e,n){return this.makeRequest(e,n)}async makeRequest(e,n,r=0,o){let a=this.buildUrl(e),s=o??Date.now(),c=this.createAbortSignal(n),u=await this.buildHeaders(n?.headers),p;u instanceof Headers?(p={},u.forEach((b,v)=>{p[v]=b})):p=u;let l=n?.method||"GET";if(this.transport.authorizeRequest){let b=n?.body;if(b!==void 0&&typeof b!="string"&&!(b instanceof Uint8Array))throw new Error("this transport authorizes each request against its body, so the body must be a string or Uint8Array \u2014 a stream cannot be signed, because the signature would have to read bytes the request then cannot send.");Object.assign(p,await this.transport.authorizeRequest({method:l,path:new URL(a).pathname,body:b}))}let m={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)&&(m.body=n.body);let A;if(r>0&&o!==void 0){let b=n?.timeoutMs||this.transport.timeoutMs;if(b){let v=Date.now()-s,I=Math.max(0,b-v);A=this.createAbortSignal({...n,timeoutMs:I})}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 b=await this.transport.getProof({method:m.method??"GET",path:bi(a),body:m.body});b&&(p["X-Calimero-Proof"]=b)}try{let b=await this.transport.fetch(a,m);if(!b.ok){let v=await this.getBodyText(b),I=new S(b.status,b.statusText,a,b.headers,v),k=b.headers.get("x-auth-error");if((b.status===401||b.status===403)&&k&&fi.has(k)){if(this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,this.transport.onAuthRevoked)try{await this.transport.onAuthRevoked()}catch{}throw new V(k,b.status,b.statusText,a,b.headers,v)}let F=n?.signal?.aborted===!0;if(b.status===401&&this.transport.refreshToken&&k==="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 te=n?.timeoutMs||this.transport.timeoutMs;if(te&&o!==void 0){let ne=Date.now()-s;if(te-ne<=0)throw I}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:I}throw I}return this.parseResponse(b,n?.parse)}catch(b){throw b instanceof S||b instanceof Error&&b.message.includes("onTokenRefresh")?b:new S(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(Dt(r)),n.length>0?Tt(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 Se(t){return new Ce(t)}function pe(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 Se(e)}function Ve(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 Se(r)}function Ut(t){return typeof window<"u"?pe(t):Ve(t)}function wi(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 Ai(t){let n=250*Math.pow(2,t-1),r=(Math.random()-.5)*.4*n;return Math.max(0,n+r)}async function We(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,!wi(r,n-o))throw r;let a=Ai(o),u=r.headers?.get?.("Retry-After");if(u){let p=parseInt(u,10);if(!isNaN(p))a=Math.max(a,p*1e3);else{let l=new Date(u);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 xi(t,e={}){return async(...n)=>We(()=>t(...n),e)}var oe=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 ke=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 Dc(t){let e=new ke;return new oe(e)}function Uc(t){let e=new ke;return new oe(e)}function Oc(t){let e=new ke;return new oe(e)}function $n(t,e){return new oe(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},Mc={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 _c(...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 Gc(t){return Object.keys(T).filter(e=>ie(t,T[e]))}function ie(t,e){let n=e>>>0;return(t&n)>>>0===n}function Ot(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 vi(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 Ci(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 Nt(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 Mt(t){let e=Ci(t),n;return e!==void 0?n=vi(e):t instanceof TypeError?n="unreachable":n="unknown",{kind:n,status:e,retryable:Ri[n],message:Nt(t)}}function Si(t){return t.status!=="failed"||!t.retryable}function Kc(t){return!Si(t)}function ki(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 Ei(t,e){let{kind:n,status:r}=Mt(t),o=ki(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 qn(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=Nt(i,"Could not join. Check the invitation."),{reason:c,retryable:u}=Ei(i,s);return{status:"failed",namespaceId:n,message:s,reason:c,retryable:u}}var Je=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 _t(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 Ln(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:_t(t,n,"highWaterNonce"),windowWidth:_t(t,n,"windowWidth")??0n},o=_t(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 Ii(t,e){let[n,r]=Kn(t),[o,i]=Kn(e),a=n.split("."),s=o.split("."),c=Math.max(a.length,s.length);for(let m=0;m<c;m++){let y=Bn(a[m]??"0",s[m]??"0");if(y!==0)return y}if(r===void 0&&i===void 0)return 0;if(r===void 0)return 1;if(i===void 0)return-1;let u=r.split("."),p=i.split("."),l=Math.max(u.length,p.length);for(let m=0;m<l;m++){if(m>=u.length)return-1;if(m>=p.length)return 1;let y=Bn(u[m],p[m]);if(y!==0)return y}return 0}function Kn(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 Bn(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 Pi(t,e,n){return We(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 se=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 Pi(r.toString(),"versions",n)).json();return(Array.isArray(i)?i:[]).map(a=>a.appVersion).filter(a=>typeof a=="string").sort((a,s)=>Ii(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 qn({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 S&&i.status===404?new Je(r,i):i}return Ln(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 S&&i.status===404?new Je(r,i):i}return Ln(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(ie(n,T.CAN_AUTHOR_ON_BEHALF))return{changed:!1,defaultCapabilities:n};let r=Ot(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(ie(r,T.CAN_AUTHOR_ON_BEHALF))return{changed:!1,capabilities:r};let o=Ot(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 zc(t){return Array.from(new TextEncoder().encode(t),e=>e.toString(16).padStart(2,"0")).join("")}function el(t){return new se(pe(t))}function tl(t){return new se(Ve(t))}function jn(t){return new se(Ut(t))}function ze(t,e){return new se(t)}function Gt(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 Ht(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 Fn=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 d(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=d(t,"deviceSecret",32),n=g(Fn,e);try{return await crypto.subtle.importKey("pkcs8",n,{name:"Ed25519"},!1,["sign"])}catch(r){let o=r instanceof Error?`: ${r.message}`:"";throw new Error("this runtime has no WebCrypto Ed25519, so a warrant cannot be signed here. Node 18.4+, Safari 17+, Firefox 129+ and Chrome 137+ have it; otherwise mint the warrant with `merod account warrant`"+o)}}async function Vn(t,e,n){let r=await crypto.subtle.importKey("raw",d(t,"publicKey",32),{name:"Ed25519"},!1,["verify"]);return crypto.subtle.verify({name:"Ed25519"},r,e,n)}async function J(t){let e=d(t,"deviceSecret",32),n=g(Fn,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 Ti=new TextEncoder().encode("calimero.auth.request.v1"),Di=new TextEncoder().encode("calimero.auth.request.body.v1");function Wn(t){let e=new TextEncoder().encode(t);return g(w(e.length),e)}async function $t(t=new Uint8Array(0)){let e=typeof t=="string"?new TextEncoder().encode(t):t;return R(Di,[e])}async function Qe(t){let e=await W(t.signerSecret),n=await $t(t.body),r=x(t.issuedAt),o=x(t.expiresAt),i=new TextEncoder,a=await R(Ti,[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(Wn(t.method),Wn(t.path),n,r,o,s))}function Ye(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 Ui(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 Xe(t){let e=t.ttlSeconds??120,n=t.now??(()=>Math.floor(Date.now()/1e3));return async r=>{let o=n();return Ye({credential:t.credential,session:t.session,request:await Qe({method:r.method,path:r.path,body:Ui(r.body),issuedAt:o,expiresAt:o+e,signerSecret:t.signerSecret})})}}var Ze=class extends Error{constructor(e,n,r,o){super(n),this.name="RpcError",this.code=e,this.data=r,this.type=o}};async function qt(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 Ze(o.code??-1,o.message??o.type??"RPC error",o.data,o.type)}return r.result}var Ee=class{constructor(e){this.kind="node";this.canSubscribe=!0;this.httpClient=e.httpClient}async execute(e){let n=await qt(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 Oi=new Set(["MigrationStarted","MigrationProgress","CascadeProgress","MigrationCompleted"]);function Jn(t){return t.type!==void 0&&Oi.has(t.type)}var Ni=new Set(["token_reuse","token_revoked"]),Mi=new Set([401,403]);function zn(t){let e=t.headers.get("x-auth-error");return!e||!Mi.has(t.status)?null:Ni.has(e)?e:null}var H=class{constructor(e){this.sessionId=null;this.abortController=null;this.reconnectTimer=null;this.subscribedContextIds=new Set;this.subscribedGroupIds=new Set;this.presence=new Map;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=>{Jn(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=zn(n),o=await n.text().catch(()=>{});throw r?new V(r,n.status,n.statusText,e,n.headers,o):new S(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 u=c.slice(5).trim();u&&this.handleMessage(u)}}if(o+=r.decode(),o.startsWith("data:")){let i=o.slice(5).trim();i&&this.handleMessage(i)}}catch(i){if(this.closed)return;let a=i instanceof Error?i:new Error(String(i));this.emit("error",a)}this.closed||this.scheduleReconnect()}handleMessage(e){try{let n=JSON.parse(e);if(n.type==="connect"&&n.session_id){this.sessionId=n.session_id,this.emit("connect",n.session_id),this.presence.clear(),(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){n.result.type==="Ephemeral"&&this.notePresence(n.result.contextId,r),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})}isSubscribed(e){return this.subscribedContextIds.has(e)}presenceSeed(e){let n=Date.now();return[...this.presence.get(e)?.values()??[]].map(({data:r,at:o})=>({...r,ageMs:(typeof r.ageMs=="number"?r.ageMs:0)+(n-o)}))}notePresence(e,n){if(!this.subscribedContextIds.has(e))return;let r=n;if(!r||typeof r.author!="string")return;let o=this.presence.get(e);o||this.presence.set(e,o=new Map),r.removed?o.delete(r.author):o.set(r.author,{data:r,at:Date.now()})}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),this.presence.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=zn(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 S(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 et=class et{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),et.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()}};et.MAX_BACKOFF_MS=3e4;var z=et;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 Ie=class{constructor(e){this.httpClient=e.httpClient,this.sse=e.sse}async set(e,n,r=Q()){await qt(this.httpClient,"set_ephemeral",{contextId:e,state:r.encode(n)})}subscribe(e,n,r=Q()){return tt(this.sse,e,n,r)}};function tt(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,u={author:s.author,state:c||s.state===void 0?void 0:r.decode(s.state),removed:c};s.ageMs!==void 0&&(u.ageMs=s.ageMs),s.account!==void 0&&(u.account=s.account),n(u)};if(t.on("event",o),t.isSubscribed?.(e))for(let i of t.presenceSeed?.(e)??[])o({contextId:e,type:"Ephemeral",data:i});return t.connect().catch(()=>{}),t.subscribe([e]).catch(()=>{}),()=>{t.off("event",o)}}var _i=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,112,4,34,4,32]);function Qn(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 ge(t,e="secret"){let n=d(t,e,32),r=g(_i,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 Qn(a)}return Xn(o,i)}async function Yn(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")d(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 Xn(t,n)}function Xn(t,e){return{publicKey:e,async sign(n){try{return new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},t,n))}catch(r){throw Qn(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 ge(t,n);throw new Error(`${n} or signer is required`)}var Gi=new TextEncoder().encode("calimero.mdma.account-ownership-claim.v1\0"),Hi=6e4,Zn=5*6e4,er=1024,nr="mdma:enable-ha-namespace",rr="mdma:enable-ha-namespace-as-account";function tr(t){let e="";for(let n of t)e+=String.fromCharCode(n);return btoa(e)}var Lt=(t,e)=>{if(!/^[0-9a-fA-F]{64}$/.test(t))throw new Error(`${e} must be 64 hex characters`);return t.toLowerCase()};async function or(t,e,n,r){if(r!==void 0&&!(r.length>0&&r.length<=er))throw new Error(`relayUrl must be a non-empty string of at most ${er} characters`);let o=t.ttlMs??Hi;if(!(o>0&&o<=Zn))throw new Error(`ttlMs must be in (0, ${Zn}]`);let i=Lt(t.namespaceId,"namespaceId"),a=Lt(t.accountId,"accountId"),s=Lt(t.salt,"salt"),c=await C(t.deviceSecret,t.signer,"deviceSecret"),u=(t.now??Date.now)(),p=Array.from(crypto.getRandomValues(new Uint8Array(16)),y=>y.toString(16).padStart(2,"0")).join(""),l=new TextEncoder().encode(JSON.stringify({v:1,audience:e,group_id:i,account_id:a,salt:s,...n===void 0?{}:{subject:n},nonce:p,issued_at_ms:u,expires_at_ms:u+o,...r===void 0?{}:{relay_url:r}})),m=await c.sign(g(Gi,l));return{kind:"account",credential:t.credential,signed_payload:tr(l),signature:tr(m)}}async function $i(t){if(!t.subject)throw new Error("subject must be the cloud login email");return or(t,nr,t.subject)}async function Kt(t){return or(t,rr,void 0,t.relayUrl)}var qi=new TextEncoder().encode("calimero.device.cert.v1"),Li=new TextEncoder().encode("calimero.account.genesis.v1"),Ki=new TextEncoder().encode("calimero.device.id.v1"),me=2,Bi=237;async function ir(t,e){if(e.length!==16)throw new Error(`nonce must be 16 bytes, got ${e.length}`);let n=d(t,"account",32);return h(await R(Ki,[n,e]))}async function nt(t){return R(qi,[d(t.account,"account",32),d(t.device,"device",32),d(t.signPublicKey,"signPublicKey",32),d(t.kemPublicKey,"kemPublicKey",32),w(t.keyEpoch),w(t.deviceEpoch)])}function sr(t){return g(new Uint8Array([me]),t.rootPublicKey,w(0),d(t.account,"account",32),d(t.device,"device",32),d(t.signPublicKey,"signPublicKey",32),d(t.kemPublicKey,"kemPublicKey",32),w(t.keyEpoch),w(t.deviceEpoch),t.signature)}async function ar(t){let e=await C(t.rootSecret,t.signer,"rootSecret"),n=d(e.publicKey,"signer.publicKey",32),r=await $(e.publicKey),o=0,i=await nt({account:r,device:t.device,signPublicKey:t.signPublicKey,kemPublicKey:t.kemPublicKey,keyEpoch:o,deviceEpoch:t.deviceEpoch}),a=await e.sign(i),s=sr({rootPublicKey:n,account:r,device:t.device,signPublicKey:t.signPublicKey,kemPublicKey:t.kemPublicKey,keyEpoch:o,deviceEpoch:t.deviceEpoch,signature:a});return h(s)}function Bt(t){let e=d(t,"credential",Bi);if(e[0]!==me)throw new Error(`this credential has account genesis version ${e[0]}, not ${me} \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 rt(t){let e=Bt(t),n=await $(e.rootPublicKey);if(n!==e.account)throw new Error(`this credential names account ${e.account}, but its root key derives ${n} \u2014 the certificate was re-pointed at another account`);if(!await Vn(e.rootPublicKey,d(e.signature,"signature",64),await nt(e)))throw new Error(`the root key of account ${e.account} did not sign this certificate`);return e}async function ot(t){return $(h(await J(t)))}async function $(t){return h(await R(Li,[g(new Uint8Array([me]),d(t,"rootPublicKey",32))]))}var ji=new TextEncoder().encode("calimero.device.scope.v1");async function jt(t){return R(ji,[d(t.account,"account",32),d(t.device,"device",32),w(t.scopeEpoch),w(t.keyEpoch),...t.applications.map((e,n)=>d(e,`applications[${n}]`,32))])}async function cr(t){let e=await C(t.rootSecret,t.signer,"rootSecret"),n=d(e.publicKey,"signer.publicKey",32),r=await $(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 jt({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([me]),n,w(0),d(r,"account",32),d(t.device,"device",32),w(o.length),...o.map((u,p)=>d(u,`applications[${p}]`,32)),w(i),w(a),c))}var Ft=["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 Fi=new TextEncoder().encode("calimero.mdma.account-link.v1\0"),Vi=new TextEncoder().encode("calimero.mdma.account-login.v1\0"),he=256,lr=he/32,Vt=(he+lr)/11;async function ur(){let t=crypto.getRandomValues(new Uint8Array(he/8));return fr(h(t),await br(t))}async function dr(t){let e=yr(t);return fr(h(await wr(e)),e.join(" "))}async function Wt(t){return d(t,"secret",32),{secret:t,publicKey:h(await J(t)),accountId:await ot(t)}}async function pr(){let t=crypto.getRandomValues(new Uint8Array(he/8)),e=await br(t);return{...await mr(t),phrase:e}}async function gr(t){return mr(await wr(yr(t)))}async function mr(t){let e=await ge(h(t),"rootSecret");return t.fill(0),{publicKey:e.publicKey,accountId:await $(e.publicKey),signer:e}}async function K(t){let e=typeof t=="string"?await ge(t,"rootSecret"):t;return hr(e)}async function it(t,e){return hr(await C(t,e,"rootSecret"))}async function hr(t){return{signer:t,publicKey:t.publicKey,accountId:await $(t.publicKey)}}async function Pe(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(Fi,new TextEncoder().encode(t.nonce)));return Rr(n)}async function st(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(Vi,new TextEncoder().encode(t.nonce)));return Rr(n)}async function fr(t,e){return{...await Wt(t),phrase:e}}function yr(t){let e=t.normalize("NFKD").toLowerCase().trim().split(/\s+/),n=e[0]===""?0:e.length;if(n!==Vt)throw new Error(`recovery phrase must be ${Vt} words, got ${n}`);return e}async function br(t){let e=xr(t)+await Ar(t),n=[];for(let r=0;r<Vt;r+=1){let o=Number.parseInt(e.slice(r*11,r*11+11),2);n.push(Ft[o])}return n.join(" ")}async function wr(t){let e="";for(let r of t){let o=Ft.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(he/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(he)!==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 xr(e).slice(0,lr)}function xr(t){let e="";for(let n of t)e+=n.toString(2).padStart(8,"0");return e}function Rr(t){let e="";for(let n of t)e+=String.fromCharCode(n);return btoa(e)}var Wi=new TextEncoder().encode("calimero.mdma.routing-read.v1\0");async function vr(t,e){d(e,"deviceSecret",32);let n=await W(e),r=g(Wi,new TextEncoder().encode(t)),o=new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},n,r));return Ji(o)}async function at(t,e){return{"X-Calimero-Credential":e.credential,"X-Calimero-Nonce":t.nonce,"X-Calimero-Signature":await vr(t.nonce,e.deviceSecret)}}function Ji(t){let e="";for(let n of t)e+=String.fromCharCode(n);return btoa(e)}var zi="https://manager.cloud.calimero.network";function Jt(t,e){return typeof t.can_execute=="boolean"?t.can_execute:e}function zt(t){return typeof t.tee_role=="string"&&t.tee_role!==""?t.tee_role:null}function Qt(t){return t.find(e=>e.canExecute&&e.relayUrl!==null&&e.executorAccount!==null)??null}var Qi=/^[0-9a-f]{64}$/;function Yi(t){return typeof t=="string"&&Qi.test(t)?t:null}var Y=class extends S{constructor(n,r,o,i,a,s){super(r,o,i,a,s);this.code=n;this.name="AccountHaRefusedError"}},Te=class extends Y{constructor(){super(...arguments);this.name="AccountNotLinkedError"}};Te.CODE="account_not_linked";var De=class extends Y{constructor(){super(...arguments);this.name="AccountLinkedToSeveralUsersError"}};De.CODE="account_linked_to_several_users";var Ue=class extends Y{constructor(){super(...arguments);this.name="HaRequestPendingError"}};Ue.CODE="ha_request_pending";var Oe=class extends Y{constructor(){super(...arguments);this.name="UnknownRelayError"}};Oe.CODE="unknown_relay";var Ne=class extends Y{constructor(){super(...arguments);this.name="RelayNotDialableError"}};Ne.CODE="relay_not_dialable";var Cr={409:[Te,De,Ue],422:[Oe,Ne]};function Xi(t){if(t)try{let e=JSON.parse(t);if(typeof e?.error=="string")return e.error;if(typeof e?.detail=="string")return e.detail;let n=e?.detail?.error;if(typeof n=="string")return n}catch{}}var Zi="x-mdma-session-refresh",es="x-mdma-session-expires",q=class{constructor(e={}){this.session=null;this.baseUrl=(e.cloudBaseUrl||zi).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 st({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:zt(r),canExecute:Jt(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 Qt(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:zt(r),canExecute:Jt(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 at(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 at(n,this.routingCredential)})).relays??[]).map(o=>({peerId:String(o.peer_id??""),relayUrl:o.relay_url??null,fresh:o.fresh===!0,executorAccount:Yi(o.executor_account),assigned:o.assigned===!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:zt(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:Jt(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 enableHaAsAccount(e){let n=await Kt({namespaceId:e.namespaceId,accountId:e.accountId,salt:e.salt,credential:e.credential,deviceSecret:e.deviceSecret,signer:e.signer,ttlMs:e.ttlMs,relayUrl:e.relayUrl}),r=e.accountId.toLowerCase(),o=e.namespaceId.toLowerCase();try{return await this.request("POST",`/api/cloud/accounts/${encodeURIComponent(r)}/namespaces/${encodeURIComponent(o)}/enable-ha`,{body:{ownership_proof:n},anonymous:!0})}catch(i){if(i instanceof S&&Cr[i.status]){let a=Xi(i.bodyText),s=Cr[i.status].find(c=>c.CODE===a);if(s&&a)throw new s(a,i.status,i.statusText,i.url,i.headers,i.bodyText)}throw i}}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 Pe({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 it(e.rootSecret,e.signer),i=await this.request("POST","/api/cloud/accounts/link",{body:{grant:e.grant,root_public_key:r,signature:await Pe({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 S(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 S(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(Zi);if(!n||!this.session)return;let r=e.headers.get(es),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 ts(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 ns(t){if(t)return typeof t=="function"?t:Xe(t)}var rs="mero-js:token-refresh";function os(){let e=globalThis.navigator?.locks;return e&&typeof e.request=="function"?e:null}function Yt(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 fe=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=ns(this.config.requestProof);this.httpClient=pe({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=$n(this.httpClient,{baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||"",timeoutMs:this.config.timeoutMs}),this.adminClient=ze(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 Ee({httpClient:this.httpClient})),this.rpcClient}get events(){return this.sseClient||(this.sseClient=new H({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 Ie({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:Yt(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=os();return n?n.request(rs,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:Yt(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||Yt(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 Gt(e)}static buildAuthLoginUrl(e,n){return Ht(e,n)}};function is(t){return new fe(t)}var Xt=class{constructor(){this.tokens=null}getTokens(){return this.tokens}setTokens(e){this.tokens=e}clear(){this.tokens=null}},ss="mero-tokens",Zt=class{constructor(e=ss){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 as=new TextEncoder().encode("calimero.warrant.v2"),cs=new TextEncoder().encode("calimero.warrant.intent.v1"),Sr=64,ls="00".repeat(32);async function en(t,e){let n=new TextEncoder().encode(JSON.stringify(e));return R(cs,[new TextEncoder().encode(t),n])}async function ct(t){let e=d(t.context,"context",32),n=d(t.authorAccount,"authorAccount",32),r=d(t.executor,"executor",32),o=d(t.appVersion??ls,"appVersion",32),i=X(t.accountHeads,"accountHeads"),a=X(t.governanceFloor,"governanceFloor"),s=await C(t.deviceSecret,t.signer,"deviceSecret"),c=d(s.publicKey,"signer.publicKey",32),u=new TextEncoder().encode(t.method),p=await en(t.method,t.argsJson),l=x(t.nonce),m=x(t.notAfter),y=await R(as,[e,n,c,r,o,u,p,x(i.length),...i,x(a.length),...a,l,m]),A=Me(await s.sign(y));return h(g(e,n,c,r,o,w(u.length),u,p,w(i.length),...i,w(a.length),...a,l,m,A))}function Me(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 X(t,e){let n=t??[];if(n.length>Sr)throw new Error(`${e} cites ${n.length} heads, over the ${Sr} a node accepts`);return n.map((r,o)=>d(r,`${e}[${o}]`,32))}var us=new TextEncoder().encode("calimero.context-creation-warrant.v1"),ds=new TextEncoder().encode("calimero.context-creation.init.v1"),lt=256;async function tn(t){let e=new TextEncoder().encode(JSON.stringify(t));return R(ds,[e])}async function ps(t){return R(us,[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 ut(t){let e=d(t.group,"group",32),n=t.seed===void 0?crypto.getRandomValues(new Uint8Array(32)):d(t.seed,"seed",32),r=d(t.authorAccount,"authorAccount",32),o=d(t.executor,"executor",32),i=d(t.applicationId,"applicationId",32),a=kr(t.serviceName,"serviceName"),s=kr(t.name,"name"),c=X(t.accountHeads,"accountHeads"),u=X(t.governanceFloor,"governanceFloor"),p=await C(t.deviceSecret,t.signer,"deviceSecret"),l=d(p.publicKey,"signer.publicKey",32),m=await tn(t.initArgs),y=await ps({group:e,seed:n,authorAccount:r,deviceKey:l,executor:o,applicationId:i,serviceName:a,name:s,initHash:m,accountHeads:c,governanceFloor:u,nonce:t.nonce,notAfter:t.notAfter}),A=Me(await p.sign(y));return{warrant:h(g(e,n,r,l,o,i,Er(a),Er(s),m,w(c.length),...c,w(u.length),...u,x(t.nonce),x(t.notAfter),A)),seed:h(n)}}function Ir(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 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 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 y=a(l);if(y>lt)throw new Error(`${l} is ${y} bytes, over the ${lt} a node accepts`);return new TextDecoder("utf-8",{fatal:!0}).decode(i(y,l))},u=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:u("accountHeads"),governanceFloor:u("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 kr(t,e){if(t===void 0)return null;let n=new TextEncoder().encode(t);if(n.length>lt)throw new Error(`${e} is ${n.length} UTF-8 bytes, over the ${lt} a node accepts`);return n}function Er(t){return t===null?new Uint8Array([0]):g(new Uint8Array([1]),w(t.length),t)}var gs=new TextEncoder().encode("calimero.governance-warrant.v1"),ms=new TextEncoder().encode("calimero.governance-warrant.op.v1"),hs={group:0,root:1};async function nn(t){return R(ms,[new Uint8Array([rn(t.kind)]),t.bytes])}async function fs(t){return R(gs,[t.scope,new Uint8Array([rn(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 _e(t){let e=d(t.scope,"scope",32),n=d(t.authorAccount,"authorAccount",32),r=d(t.executor,"executor",32),o=X(t.accountHeads,"accountHeads"),i=X(t.governanceFloor,"governanceFloor"),a=rn(t.op.kind),s=await C(t.deviceSecret,t.signer,"deviceSecret"),c=d(s.publicKey,"signer.publicKey",32),u=await nn(t.op),p=await fs({scope:e,kind:t.op.kind,authorAccount:n,deviceKey:c,executor:r,opHash:u,accountHeads:o,governanceFloor:i,nonce:t.nonce,notAfter:t.notAfter}),l=Me(await s.sign(p));return h(g(e,new Uint8Array([a]),n,c,r,u,w(o.length),...o,w(i.length),...i,x(t.nonce),x(t.notAfter),l))}function Pr(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 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 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)))},u=()=>{let l=i(1,"kind")[0];if(l===0)return"group";if(l===1)return"root";throw new Error(`governance warrant has kind ${l}, expected 0 (group) or 1 (root)`)},p={scope:h(i(32,"scope")),kind:u(),authorAccount:h(i(32,"authorAccount")),deviceKey:h(i(32,"deviceKey")),executor:h(i(32,"executor")),opHash:h(i(32,"opHash")),accountHeads:c("accountHeads"),governanceFloor:c("governanceFloor"),nonce:s("nonce"),notAfter:s("notAfter"),signature:h(i(64,"signature"))};if(o!==n.length)throw new Error(`governance warrant is ${n.length} bytes but its fields account for ${o}`);return p}function rn(t){let e=hs[t];if(e===void 0)throw new Error(`op kind must be 'group' or 'root', got ${String(t)}`);return e}var ys={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},Ge={GroupCreated:0,GroupReparented:1,GroupDeleted:2,MemberJoinedOpen:7,NamespaceCreatedV2:9},bs=new TextEncoder().encode("calimero.namespace.id.v1"),sn=new Uint8Array(32),dt=w(0);function Dr(t){let e=ys[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 Ur(t,e){return{kind:"group",bytes:g(E(U.MemberAdded),d(t,"member",32),Dr(e))}}function Or(t){return{kind:"group",bytes:g(E(U.MemberRemoved),d(t,"member",32),sn,dt)}}function Nr(t){return{kind:"group",bytes:g(E(U.MemberLeft),d(t,"member",32),sn,dt)}}function Mr(t,e){return{kind:"group",bytes:g(E(U.MemberRoleSet),d(t,"member",32),Dr(e))}}var ws=new TextEncoder().encode("calimero.subgroup.id.v1");async function an(t,e,n,r){return h(await R(ws,[d(t,"admin",32),d(e,"parentId",32),new Uint8Array([n?1:0]),d(r,"salt",32)]))}function Tr(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 pt(t){return{kind:"group",bytes:g(E(U.TargetApplicationSet),sn,d(t.applicationId,"applicationId",32),Tr(t.package,"package"),Tr(t.version,"version"))}}function gt(t){if(!Number.isInteger(t)||t<0||t>4294967295)throw new Error(`capabilities must be a u32 bit mask, got ${String(t)}`);if(ie(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(E(U.DefaultCapabilitiesSet),w(t))}}function cn(t){return{kind:"root",bytes:g(E(Ge.GroupCreated),d(t.groupId,"groupId",32),d(t.parentId,"parentId",32),E(t.restricted?1:0),d(t.admin,"admin",32),d(t.salt,"salt",32))}}async function _r(t){let e=t.salt??h(crypto.getRandomValues(new Uint8Array(32))),n=await an(t.admin,t.parentId,t.restricted,e);return{groupId:n,salt:e,op:cn({...t,groupId:n,salt:e})}}function Gr(t,e){return{kind:"root",bytes:g(E(Ge.GroupReparented),d(t,"childGroupId",32),d(e,"newParentId",32))}}function Hr(t){return{kind:"root",bytes:g(E(Ge.GroupDeleted),d(t,"rootGroupId",32),dt,dt)}}async function mt(t,e){return h(await R(bs,[d(t,"founder",32),d(e,"salt",32)]))}function ht(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(E(Ge.NamespaceCreatedV2),d(t.founder,"founder",32),e,d(t.salt,"salt",32))}}function on(t){let e=new TextEncoder().encode(t);return g(w(e.length),e)}function ln(t){return t===void 0?E(0):g(E(1),on(t))}function un(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])=>[on(o),on(r)]))}function As(t,e){if(!Number.isInteger(t)||t<0||t>4294967295)throw new Error(`${e} must be a u32 bit mask, got ${String(t)}`);if(ie(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 $r(t,e){return{kind:"group",bytes:g(E(U.MemberCapabilitySet),d(t,"member",32),w(As(e,"capabilities")))}}function qr(t){return{kind:"group",bytes:g(E(U.ContextDetached),d(t,"contextId",32))}}function Lr(t){if(t!=="open"&&t!=="restricted")throw new Error(`mode must be open or restricted, got ${String(t)}`);return{kind:"group",bytes:g(E(U.SubgroupVisibilitySet),E(t==="open"?0:1))}}function Kr(t={}){return{kind:"group",bytes:g(E(U.GroupMetadataSet),ln(t.name),un(t.data))}}function Br(t,e={}){return{kind:"group",bytes:g(E(U.MemberMetadataSet),d(t,"member",32),ln(e.name),un(e.data))}}function jr(t,e={}){return{kind:"group",bytes:g(E(U.ContextMetadataSet),d(t,"contextId",32),ln(e.name),un(e.data))}}function Fr(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 Vr(t,e,n){return{kind:"group",bytes:g(E(U.ContextCapabilityGranted),d(t,"contextId",32),d(e,"member",32),Fr(n))}}function Wr(t,e,n){return{kind:"group",bytes:g(E(U.ContextCapabilityRevoked),d(t,"contextId",32),d(e,"member",32),Fr(n))}}function Jr(t){return{kind:"root",bytes:g(E(Ge.MemberJoinedOpen),d(t.member,"member",32),d(t.groupId,"groupId",32),G(t.credential,"credential"))}}var ft=300,ae=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"}},xs=t=>new Promise(e=>setTimeout(e,t));function Rs(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 Z=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??ft,c=await ct({context:e,authorAccount:this.config.authorAccount,executor:o,method:n,argsJson:r,nonce:a,notAfter:BigInt(Math.floor(Date.now()/1e3))+BigInt(s),signer:i}),u=await this.json("POST",`/admin-api/contexts/${encodeURIComponent(e)}/intents`,{method:n,argsJson:r,warrant:c,authorProof:this.config.authorProof});return{rootHash:u.data.rootHash,returns:u.data.returns??null}}async 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 ae(`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 ae(`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??ft,{warrant:c}=await ut({group:e.groupId,seed:e.seed,authorAccount:this.config.authorAccount,executor:r,applicationId:e.applicationId,serviceName:e.serviceName,name:e.name,initArgs:o,nonce:a,notAfter:BigInt(Math.floor(Date.now()/1e3))+BigInt(s),signer:i}),u=await this.json("POST",`/admin-api/groups/${encodeURIComponent(e.groupId)}/context-intents`,{warrant:c,authorProof:this.config.authorProof,initArgs:o});return{contextId:u.data.contextId,groupId:u.data.groupId,memberPublicKey:u.data.memberPublicKey}}async describeGovernance(e){return(await this.json("GET",`/admin-api/groups/${encodeURIComponent(e)}/governance-intents`)).data}async govern(e){let n=await this.describeGovernance(e.groupId);if(!n.canActOnBehalf)throw new ae(`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??ft,s=await _e({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(d(e.salt,"salt",32)):h(crypto.getRandomValues(new Uint8Array(32))),o=await mt(this.config.authorAccount,r),i=ht({founder:this.config.authorAccount,credential:this.config.authorProof,salt:r}),a=e.defaultCapabilities===void 0?void 0:gt(e.defaultCapabilities),s=e.application?pt(e.application):void 0,c=await this.authorSigner(),u=await this.config.nonces.next(),p=this.config.ttlSeconds??ft,l=await _e({scope:o,op:i,authorAccount:this.config.authorAccount,executor:n,nonce:u,notAfter:BigInt(Math.floor(Date.now()/1e3))+BigInt(p),signer:c}),m=await this.postGovernance(o,i,l),y={namespaceId:m.groupId,salt:r,teeEnabled:m.teeEnabled??!1,...m.teeError?{teeError:m.teeError}:{}},A=y,b=v=>v instanceof Error?v.message:String(v);if(s)try{await this.govern({groupId:y.namespaceId,op:s}),A={...A,applicationSet:!0}}catch(v){A={...A,applicationSet:!1,applicationError:b(v)}}if(a)try{await this.govern({groupId:y.namespaceId,op:a}),A={...A,defaultCapabilitiesSet:!0}}catch(v){A={...A,defaultCapabilitiesSet:!1,defaultCapabilitiesError:b(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 S&&a.status===429)||i>=this.rateLimitRetries)throw a;let c=Rs(a.headers);await xs(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 S(0,c instanceof Error?c.name:"NetworkError",`${this.baseUrl}${n}`,new Headers,c instanceof Error?c.message:String(c))}finally{clearTimeout(a)}if(!s.ok){let c=await s.text().catch(()=>"");if(s.status===400||s.status===403){let u=vs(c);throw new ae(u,/nonce/i.test(u),s.status)}throw new S(s.status,s.statusText,`${this.baseUrl}${n}`,s.headers,c)}if(s.status!==204)return await s.json()}};function vs(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 ce=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 Cs=new TextEncoder().encode("calimero.auth.login.v1"),zr={webOrigin:0,codeSigningId:1,cli:2};function Qr(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 Ss(t){return g(Uint8Array.from([zr[t.kind]]),Qr(t))}function ks(t){let e=Uint8Array.from([zr[t.kind]]);if(t.kind==="cli")return e;let n=Qr(t);return g(e,w(n.length),n)}async function yt(t){let e=d(t.node,"node",32),n=d(t.challenge,"challenge",32),r=d(t.sessionKey,"sessionKey",32),o=await C(t.deviceSecret,t.signer,"deviceSecret"),i=d(o.publicKey,"signer.publicKey",32),a=x(t.issuedAt),s=x(t.expiresAt),c=await R(Cs,[e,Ss(t.audience),n,r,i,a,s]),u=await o.sign(c);return h(g(e,ks(t.audience),n,r,i,a,s,u))}var Es=300;async function dn(){let t=h(crypto.getRandomValues(new Uint8Array(32)));return{publicKey:h(await J(t)),secret:t}}async function bt(t){let e=t.nodeUrl.replace(/\/+$/,""),n=t.timeoutMs??1e4,r=async(m,y)=>{let A=new AbortController,b=setTimeout(()=>A.abort(),n),v;try{let k={...y,signal:A.signal};v=t.fetch?await t.fetch(`${e}${m}`,k):await globalThis.fetch(`${e}${m}`,k)}catch(k){throw new S(0,k instanceof Error?k.name:"NetworkError",`${e}${m}`,new Headers,k instanceof Error?k.message:String(k))}finally{clearTimeout(b)}let I=await v.text().catch(()=>"");if(!v.ok)throw new S(v.status,v.statusText,`${e}${m}`,v.headers,I);return I?JSON.parse(I):{}},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 dn(),s=Math.floor(Date.now()/1e3),c=await yt({node:t.node,audience:t.audience,challenge:i,sessionKey:a.publicKey,issuedAt:s,expiresAt:s+(t.ttlSeconds??Es),signer:await C(t.deviceSecret,t.signer,"deviceSecret")}),u=await r("/auth/token",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({auth_method:"account_proof",public_key:a.publicKey,client_name:t.clientName??e,timestamp:s,provider_data:{challenge:i,login_statement:c,account_proof:t.accountProof}})}),p=u.access_token??u.data?.access_token,l=u.refresh_token??u.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 Is=3e4;function wt(){let t=globalThis.location?.origin;return t?{kind:"webOrigin",origin:t}:{kind:"cli"}}function Ps(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 ye=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-Is>e?this.session.accessToken:(this.pending||(this.pending=this.loginNow().finally(()=>{this.pending=null})),(await this.pending).accessToken)}async loginNow(){let e=await bt({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=Ps(e.accessToken),e}get events(){return this.sseClient||(this.sseClient=new H({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),Ts=B("calimero.auth.request.v1"),Ds=B("calimero.auth.request.body.v1"),pn="X-Calimero-Proof",Us=300;async function gn(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(Ds,[o]),a=Math.floor(t.now??Date.now()/1e3),s=a+(t.validForSeconds??Us),c=await R(Ts,[B(e),B(n),i,x(a),x(s)]),u=await Os(c,t);if(u.length!==64)throw new Error(`the signer returned ${u.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),u),l=Ns(r,"credential");return h(g(l,new Uint8Array([0]),p))}async function Os(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 Ns(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 d(n,e,n.length/2)}function mn(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 gn({method:e,path:n,body:r,credential:t.credential,deviceSecret:t.deviceSecret,signer:t.signer,validForSeconds:t.validForSeconds});return{[pn]:o}}}function Ms(t){return new URL(t).pathname}var Yr=new TextEncoder().encode("calimero/presence/1");async function Xr(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 hn(t){return g(Yr,d(t.contextId,"contextId",32),d(t.author,"author",32),x(t.seq),x(t.sentAtMs),await Xr(t.state))}var _s=2500,He=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??_s,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 tt(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 hn({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 u=c.status;if(u===void 0||u===0||u===429||u>=500)return;throw this.refused.add(e),this.stop(e),c}}};function Zr(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 eo(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 Gs(t,e){let n=e?.nodeKey;return n?new ye({nodeUrl:e?.nodeUrl??t.relayUrl,nodeKey:n,accountProof:e?.accountProof??t.authorProof,audience:e?.audience??wt(),signer:e?.signer?async()=>e.signer:()=>t.authorSigner(),clientName:e?.clientName,ttlSeconds:e?.ttlSeconds,fetch:e?.fetch,timeoutMs:e?.timeoutMs}):null}var le=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 Z?e.relay:new Z(e.relay);if(this.relayObserver=Gs(o,e.observe),this.rpcTransport=new ce(o,this.relayObserver),this.relayUrl=o.relayUrl,e.proof&&(this.proofAuthorizer=mn(e.proof)),e.session){let i=e.session;this.relayAdmin=jn({baseUrl:o.relayUrl,getAuthToken:typeof i=="string"?async()=>i:i})}else if(this.proofAuthorizer){let i=this.proofAuthorizer;this.relayAdmin=ze(Se({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 fe(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 Zr("node connection","it holds a signing key and a relay URL, not a node");return this.nodeClient}get relay(){if(!(this.rpcTransport instanceof ce))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 H({baseUrl:this.relayUrl,authorize:this.proofAuthorizer})),this.proofEvents;throw eo("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."):eo("WebSocket events")}get ephemeral(){return this.nodeClient?this.nodeClient.ephemeral:(this.relayPresence??(this.relayPresence=new He({relay:this.relay,events:()=>this.events})),this.relayPresence)}get cloud(){if(!this.nodeClient)throw Zr("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 to(t){return new le(t)}function xt(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 fn(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 Hs(t){return{getWarrantNonce:(e,n)=>t.client.getWarrantNonceAsAuthor(e,t.authorProof)}}var At=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 $s(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??xt(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,u=!1;for(let p of s){if(p.status!=="fulfilled")continue;let l=p.value;if(l.kind==="exhausted"){u=!0;continue}(c===null||l.nextNonce>c)&&(c=l.nextNonce)}if(c===null&&u)throw new At(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 qs="Noise_NK_25519_AESGCM_SHA256",yn=32,Ls=16,Ks=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,110,4,34,4,32]),wn=class t{constructor(e){this.k=null;this.n=0;this.ck=e,this.h=e}static async initialize(){let e=new TextEncoder().encode(qs),n=new Uint8Array(32);return n.set(e),new t(n)}async mixHash(e){this.h=await js(g(this.h,e))}async mixKey(e){let[n,r]=await oo(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:ro(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:ro(this.n),additionalData:this.h},this.k,e));return this.n+=1,await this.mixHash(e),n}split(){return oo(this.ck,new Uint8Array)}};async function io(t,e,n){let r=await wn.initialize();await r.mixHash(e),await r.mixHash(t);let o=await Bs(n);return await r.mixHash(o.publicKey),await r.mixKey(await no(o.privateKey,t)),{message1:g(o.publicKey,await r.encryptAndHash(new Uint8Array)),async finish(a){if(a.length<yn+Ls)throw new Error("Noise: message 2 is too short");let s=a.slice(0,yn);return await r.mixHash(s),await r.mixKey(await no(o.privateKey,s)),{payload:await r.decryptAndHash(a.slice(yn)),split:await r.split()}}}}async function Bs(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(Ks,t),{name:"X25519"},!0,["deriveBits"]),n=await crypto.subtle.exportKey("jwk",e);return{privateKey:e,publicKey:Fs(n.x)}}async function no(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 ro(t){let e=new Uint8Array(12);return new DataView(e.buffer).setBigUint64(4,BigInt(t),!1),e}async function js(t){return new Uint8Array(await crypto.subtle.digest("SHA-256",t))}async function bn(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 oo(t,e){let n=await bn(t,e),r=await bn(n,new Uint8Array([1])),o=await bn(n,g(r,new Uint8Array([2])));return[r,o]}function Fs(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 lo="/sealed/v2/handshake",uo="/sealed/v2",qe="application/vnd.calimero.sealed",An=2,Vs=new TextEncoder().encode("calimero/sealed-http/v2"),$e=16,Ws=1+$e+8,Js=0,zs=1,Qs=2,Ys=1+64*1024+16,Xs=1024,Zs=6e4,ea="calimero.tee-attest.transport-key.v1",ta=[101,204,205,304],po=new TextEncoder,Le=class extends Error{constructor(){super("The node no longer holds the attested transport key; attest again for the current one");this.name="StaleTransportKeyError"}},be=class extends Error{constructor(n,r,o,i){super(o);this.status=n;this.code=r;this.retryAfterMs=i;this.name="SealedTransportError"}};async function go(t,e){let n=await crypto.subtle.digest("SHA-256",g(po.encode(ea),t,e));return new Uint8Array(n)}async function mo(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=d(o.transportPublicKey,"transportPublicKey",32),a=n.applicationHash?d(n.applicationHash,"applicationHash",32):new Uint8Array(32),s=h(await go(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 Ke(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 ho({baseUrl:t.baseUrl,transportPublicKey:()=>mo(r,t.verify,{applicationId:t.applicationId,applicationHash:t.applicationHash}),fetch:e})}function ho(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 ao(o,r,await so(a))}catch(l){if(!(l instanceof Le)||!i)throw l;return a=Promise.resolve().then(i),ao(o,r,await so(a))}},u=async()=>{let l=s??p(void 0),m=await l;if(Date.now()<m.renewAt)return[m,l];let y=p(l);return[await y,y]},p=l=>{if(s===l){let m=c();s=m,m.catch(()=>{s===m&&(s=void 0)})}return s};return async(l,m)=>{let y=new Request(l,m),A=new URL(y.url);if(A.origin!==e.origin||!A.pathname.startsWith(`${n}/`))throw new Error(`Refusing to send ${A.href} outside the sealed node at ${t.baseUrl}`);let b=[];y.headers.forEach((D,_)=>b.push([_,D]));let v={method:y.method,path:A.pathname.slice(n.length)+A.search,headers:b},I=new Uint8Array(await y.arrayBuffer()),k=async D=>{let{requestId:_,header:te,envelope:ne}=await ra(D,v,I),re=await o(`${r}${uo}`,{method:"POST",headers:{"content-type":qe},body:ne,signal:y.signal});if(re.headers.get("content-type")!==qe)throw await yo(re);return ia(re,D.responseKey,te,_)},[F,M]=await u();try{return await k(F)}catch(D){if(!(D instanceof be)||D.code!=="unknown_session")throw D;return k(await p(M))}}}async function so(t){let e=await t;if(e.length!==32)throw new Error("transportPublicKey must be 32 bytes");return e}async function ao(t,e,n){try{return await co(t,e,n)}catch(r){if(!(r instanceof be)||r.code!=="busy")throw r;return await new Promise(o=>setTimeout(o,r.retryAfterMs??1e3)),co(t,e,n)}}async function co(t,e,n){let r=await io(n,Vs),o=await t(`${e}${lo}`,{method:"POST",headers:{"content-type":qe},body:g(new Uint8Array([An]),n,r.message1)});if(o.headers.get("content-type")!==qe)throw await yo(o);let i=await aa(o,Xs);return na(r,i)}async function na(t,e){if(e[0]!==An)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!==$e+4)throw new Error("The handshake reply is malformed");let i=r.slice(0,$e),a=new DataView(r.buffer,r.byteOffset).getUint32($e,!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-Zs,header(u){let p=new Uint8Array(Ws);return p[0]=An,p.set(i,1),new DataView(p.buffer).setBigUint64(1+$e,BigInt(u),!1),p}}}async function ra(t,e,n){let r=t.nextRequestId;t.nextRequestId+=1;let o=t.header(r),i=await crypto.subtle.encrypt({name:"AES-GCM",iv:fo(r,0),additionalData:o},t.requestKey,oa(e,n));return{requestId:r,header:o,envelope:g(o,new Uint8Array(i))}}function fo(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 oa(t,e){let n=po.encode(JSON.stringify(t)),r=new Uint8Array(4);return new DataView(r.buffer).setUint32(0,n.length,!1),g(r,n,e)}async function ia(t,e,n,r){if(!t.body)throw new Error("The sealed response has no body");let o=sa(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:fo(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!==Js)throw new Error("The sealed response is malformed");let c=JSON.parse(new TextDecoder().decode(s.data));if(ta.includes(c.status))return await o.cancel(),new Response(null,{status:c.status,headers:c.headers});let u=new ReadableStream({async pull(p){try{let l=await a();l?l.kind===zs?p.enqueue(l.data):l.kind===Qs?(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(u,{status:c.status,headers:c.headers})}function sa(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>Ys)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 aa(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 yo(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 Le;let r=Number(t.headers.get("retry-after")),o=Number.isFinite(r)&&r>0?Math.min(r,5)*1e3:void 0;return new be(t.status,e,n,o)}async function bo(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=la(r,t.namespaceId),i=await n.getNamespaceRelays(o.namespaceId),a=Qt(i);if(!a)throw new Error(ua(o,i));let s=new Z({relayUrl:a.relayUrl,executorAccount:a.executorAccount,authorAccount:t.authorAccount,authorProof:t.authorProof,signer:e,nonces:t.nonces??da(e.publicKey),ttlSeconds:t.ttlSeconds,fetch:t.seal?Ke({baseUrl:a.relayUrl,verify:t.seal,fetch:t.fetch}):t.fetch,timeoutMs:t.timeoutMs});return{cloud:n,relay:s,namespaceId:o.namespaceId,namespace:o,relayInfo:a,execute:(c,u,p)=>s.execute(c,u,p),client:new le({transport:"relay",relay:s,observe:{nodeKey:t.relayNodeKey??a.nodeKey,audience:t.observeAudience,fetch:t.fetch,timeoutMs:t.timeoutMs}})}}async function ca(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 bo({...r,deviceSecret:void 0,signer:o,sessionToken:s.sessionToken,authorAccount:n??i.accountId})}function la(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 ua(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 da(t){let e=`mero-js:warrant-nonce:${t}`;try{return fn(e)}catch{return xt(1)}}var pa="https://cloud.calimero.network";function Ao(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??pa);return e.searchParams.set("link-account",t.accountId),e.searchParams.set("callback-url",t.returnTo),e.toString()}function ga(t){throw window.location.assign(Ao(t)),new Error("redirecting to the cloud to authorise this link")}function ma(t=window.location){let e=new URLSearchParams(t.hash.replace(/^#/,"")),n=e.get("error");if(n)throw wo(),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:(wo(),{grant:r,account:o})}function wo(){typeof history>"u"||!history.replaceState||history.replaceState(null,"",location.pathname+location.search)}async function ha(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 fa="enrol-device",ya="enrol-kem",ba="callback-url",wa="state";function vo(t){Ro(t.devicePublicKey,"devicePublicKey"),Ro(t.kemPublicKey,"kemPublicKey"),Ca(t.returnTo),va(t.returnTo);let e=new URL(t.walletUrl);return e.searchParams.set(fa,t.devicePublicKey),e.searchParams.set(ya,t.kemPublicKey),e.searchParams.set(ba,t.returnTo),t.state&&e.searchParams.set(wa,t.state),e.toString()}function Aa(t){throw window.location.assign(vo(t)),new Error("redirecting to the wallet to approve this device")}function xa(t=window.location){let e=new URLSearchParams(t.hash.replace(/^#/,"")),n=e.get("error");if(n)throw xo(),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;xo();let a=e.get("state");return{credential:r,account:o,device:i,...a?{state:a}:{}}}function xo(){typeof history>"u"||!history.replaceState||history.replaceState(null,"",location.pathname+location.search)}async function Ra(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 rt(t.credential);if(e.signPublicKey!==ue(t.devicePublicKey))throw new Error(`this credential certifies device key ${e.signPublicKey}, but this app holds ${ue(t.devicePublicKey)} \u2014 it would sign with a key the certificate does not cover`);if(t.kemPublicKey!==void 0&&e.kemPublicKey!==ue(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!==ue(t.account))throw new Error(`the wallet reported account ${ue(t.account)}, but the credential names ${e.account}`);if(e.device!==ue(t.device))throw new Error(`the wallet reported device ${ue(t.device)}, but the credential names ${e.device}`);return{credential:t.credential,account:e.account,device:e.device,certificate:e}}function Ro(t,e){if(!/^[0-9a-f]{64}$/.test(t))throw new Error(`${e} must be 64 lowercase hex characters`)}function ue(t){return t.trim().toLowerCase()}function Co(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 va(t){Co(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 Ca(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 Sa=/^[0-9a-f]{96}$/,ka=["mrtd","rtmr0","rtmr1","rtmr2","rtmr3"];function xn(t){let e=we(t.allowedMrtd??[],"allowedMrtd"),n=(t.allowedMeasurements??[]).map((s,c)=>{let u=`allowedMeasurements[${c}]`;return ka.map(p=>we([s?.[p]??""],`${u}.${p}`)[0]).join()}),r=[we(t.allowedRtmr0??[],"allowedRtmr0"),we(t.allowedRtmr1??[],"allowedRtmr1"),we(t.allowedRtmr2??[],"allowedRtmr2"),we(t.allowedRtmr3??[],"allowedRtmr3")];if(t.allowedMeasurements!==void 0&&n.length===0)throw new Error("allowedMeasurements is empty, so no quote would ever be accepted");if(n.length===0){if(e.length===0)throw new Error("No image is trusted: give allowedMeasurements, or allowedMrtd with allowedRtmr1-3");if(r.slice(1).some(s=>s.length===0))throw new Error("allowedMrtd alone does not name an image: the MRTD measures the TD firmware, which images share, and the image is in RTMR1-3. Give allowedMeasurements, or allowedRtmr1-3 too")}let o=t.allowedTcbStatuses??["UpToDate"],i=t.now??Date.now;return Object.assign(async({quoteB64:s,nonce:c,reportDataSuffix:u,collateral:p})=>{let l=Ia(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 y;try{y=t.dcapVerify(l,m,Math.floor(i()/1e3))}catch(I){throw new Error(`The quote did not verify: ${I?.message??String(I)}`)}if(y.status==="Revoked"||!o.includes(y.status))throw new Error(`The platform's TCB status is ${y.status}, which is not accepted`);let A=Ea(y.report),b=[A.mrTd,A.rtMr0,A.rtMr1,A.rtMr2,A.rtMr3].map(I=>h(I));if(n.length>0&&!n.includes(b.join()))throw new Error(`The measurements (MRTD ${b[0]}, RTMR0-3 ${b.slice(1).join(", ")}) are not an image this verifier trusts`);if(e.length>0&&!e.includes(b[0]))throw new Error(`MRTD ${b[0]} is not an image this verifier trusts`);if([A.rtMr0,A.rtMr1,A.rtMr2,A.rtMr3].forEach((I,k)=>{let F=r[k];if(F.length>0&&!F.includes(h(I)))throw new Error(`RTMR${k} ${h(I)} is not one this verifier trusts`)}),h(A.reportData)!==`${c}${u}`.toLowerCase())throw new Error("The quote does not commit to this nonce and binding");return!0},{includeCollateral:!0})}function we(t,e){return t.map(n=>{let r=n.trim().toLowerCase();if(!Sa.test(r))throw new Error(`${e} holds ${JSON.stringify(n)}, which is not a 48-byte hex measurement`);return r})}function Ea(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 Pa=["UpToDate","SWHardeningNeeded","ConfigurationNeeded","ConfigurationAndSWHardeningNeeded","OutOfDate","OutOfDateConfigurationNeeded"];function Rn(t,{profile:e}){if(t.length===0)throw new Error("No release given, so no image would be trusted");let n,r=t.map((o,i)=>{let a=o?.tag??`releases[${i}]`;if(o?.role!==void 0&&o.role!=="node")throw new Error(`${a} lists the measurements of a ${o.role}, not of a node image`);let s=o?.profiles?.[e];if(!s){let u=Object.keys(o?.profiles??{}).join(", ")||"none";throw new Error(`${a} has no profile ${JSON.stringify(e)} (it has: ${u})`)}let c=(s.allowed_tcb_statuses??["uptodate"]).map(u=>Ta(u,a));return n=n===void 0?c:n.filter(u=>c.includes(u)),{mrtd:s.mrtd,rtmr0:s.rtmr0,rtmr1:s.rtmr1,rtmr2:s.rtmr2,rtmr3:s.rtmr3}});if(!n||n.length===0)throw new Error("The releases given accept no TCB status in common");return{allowedMeasurements:r,allowedTcbStatuses:n}}function Ta(t,e){let n=Pa.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 So=[{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"]}],ko=[{baseUrl:"https://rekor.sigstore.dev",logId:"c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d",publicKey:"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE2G2Y+2tabdTV5BcGiBIx0a9fAFwrkBbmLSGtks4L3qX6yYY0zufBnhC8Ur/iy55GhWP/9A/bY2LhC30M9+RYtw==",validFor:{start:"2021-01-12T11:53:27Z"}}];var Da="1.2.840.10045.2.1",Ua={"1.2.840.10045.3.1.7":"P-256","1.3.132.0.34":"P-384"},Oa={"P-256":32,"P-384":48},Na={"1.2.840.10045.4.3.2":"SHA-256","1.2.840.10045.4.3.3":"SHA-384"};function Eo(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 xe(t){let e=Eo(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=Eo(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 ee(t){return t.bytes.slice(t.start,t.end)}function Rt(t){return t.bytes.slice(t.offset,t.end)}function Ae(t){let e=ee(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 Ma(t){let e=new TextDecoder().decode(ee(t)),n=t.tag===23?/^(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})Z$/.exec(e):null,r=t.tag===24?/^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})Z$/.exec(e):null,o=n??r;if(!o)throw new Error(`it holds the time ${JSON.stringify(e)}, which is not one a certificate may hold`);let i=Number(o[1]);n&&(i+=i<50?2e3:1900);let[a,s,c,u,p]=o.slice(2).map(Number);return Date.UTC(i,a-1,s,c,u,p)}function vn(t){try{let[e,n,r,...o]=O(P(xe(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,u,p,l,m,...y]=i.slice(a);P(s,2,"The serial number");let A=Ae(O(P(n,48,"The signature algorithm"))[0]);if(Ae(O(P(c,48,"The signature algorithm"))[0])!==A)throw new Error("it names two different signature algorithms");let v=Na[A];if(!v)throw new Error(`it is signed with ${A}, not ECDSA with SHA-256 or SHA-384`);let[I,k]=O(P(p,48,"The validity")).map(Ma);if(k===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(Ae(D)!==Da)throw new Error("its key is not an elliptic-curve key");let te=Ua[Ae(_)];if(!te)throw new Error("its key is on a curve other than P-256 or P-384");let ne=new Map,re=y.find(It=>It.tag===163);if(re){let[It]=O(re);for(let hi of O(P(It,48,"The extensions"))){let de=O(P(hi,48,"An extension"));if(de.length===3)P(de[1],1,"An extension's critical flag");else if(de.length!==2)throw new Error("it has a malformed extension");let Pt=Ae(de[0]);if(ne.has(Pt))throw new Error(`it has extension ${Pt} twice`);ne.set(Pt,ee(P(de[de.length-1],4,"An extension value")))}}let Gn=ee(P(r,3,"The signature"));if(Gn[0]!==0)throw new Error("its signature is not a whole number of bytes");return{der:t,tbs:Rt(e),signatureHash:v,signature:Gn.slice(1),issuer:Rt(P(u,48,"The issuer")),subject:Rt(P(l,48,"The subject")),notBefore:I,notAfter:k,spki:Rt(m),curve:te,extensions:ne}}catch(e){throw new Error(`The certificate is malformed: ${e.message}`)}}function Io(t){return O(P(xe(t),48,"The list")).map(Ae)}function _a(t,e){let n=Oa[e],r=O(P(xe(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=ee(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 vt(t,e,n,r,o){let i;try{i=_a(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 Cn(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 Ga="2.5.29.17",Ha="2.5.29.37",$a="1.3.6.1.5.5.7.3.3",qa="1.3.6.1.4.1.57264.1.8",La="1.3.6.1.4.1.57264.1.1",Ka=134,Ba=12,ja=48,Fa=new TextEncoder,Re=t=>new TextDecoder().decode(t);async function Po(t,e,n,r){let{base64Signature:o,cert:i,rekorBundle:a}=za(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"),u=Cn(Re(L(i,"The bundle certificate")),"The bundle certificate"),p=vn(u),l=ko.find(k=>k.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=Fa.encode(`{"body":${JSON.stringify(s.body)},"integratedTime":${s.integratedTime},"logID":${JSON.stringify(s.logID)},"logIndex":${s.logIndex}}`);if(!await vt(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(!Uo(A,l.validFor))throw new Error(`Rekor log ${l.baseUrl} was not in use at ${Be(A)}, when the entry says it was logged`);let b=Qa(s.body),v=h(new Uint8Array(await crypto.subtle.digest("SHA-256",t)));if(b.hash!==v)throw new Error("The file's SHA-256 is not the one Rekor logged: the file is not the one signed");if(!Sn(L(b.signature,"The logged signature"),c))throw new Error("The bundle's signature is not the one Rekor logged");let I=Cn(Re(L(b.publicKey,"The logged certificate")),"The logged certificate");if(!Sn(I,u))throw new Error("The bundle's certificate is not the one Rekor logged");if(p.curve!=="P-256"||!await vt(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,A),Ja(p,n),{integratedTime:s.integratedTime}}async function Va(t,e){if(!Do(t,e))throw new Error(`The signing certificate was valid ${Be(t.notBefore)} to ${Be(t.notAfter)}, not at ${Be(e)} when Rekor logged it`);let n=[];for(let r of So){let o=r.certChain.map(a=>vn(L(a,"A Fulcio certificate")));if(!await To(t,o[0]))continue;let i=await Wa(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 ${Be(e)}: ${n.join("; ")}`:"The signing certificate was not issued by a Fulcio CA in the Sigstore trust root")}async function Wa(t,e,n){if(!Uo(n,e))return"the trust root says it was not issuing certificates then";for(let[r,o]of t.entries()){if(!Do(o,n))return`its certificate ${r} was not valid then`;let i=t[r+1]??o;if(!await To(o,i))return`its certificate ${r} is not signed by the next`}}async function To(t,e){return Sn(t.issuer,e.subject)?vt(e.spki,e.curve,t.signatureHash,t.signature,t.tbs):!1}function Ja(t,e){let n=t.extensions.get(Ga);if(!n)throw new Error("The signing certificate names no identity");let r=O(P(xe(n),ja,"The subject alternative name")),o=r.filter(u=>u.tag===Ka).map(u=>Re(ee(u)));if(o.length!==1||r.length!==1||o[0]!==e.identity)throw new Error(`The release was signed by ${JSON.stringify(o.length===1?o[0]:o)}, not by ${e.identity}`);let i=t.extensions.get(qa),a=t.extensions.get(La),s=i?Re(ee(P(xe(i),Ba,"The OIDC issuer"))):a?Re(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||!Io(c).includes($a))throw new Error("The signing certificate is not for code signing")}function za(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 Qa(t){let e;try{e=JSON.parse(Re(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 Do(t,e){return t.notBefore<=e&&e<=t.notAfter}function Uo(t,e){return Date.parse(e.start)<=t&&(e.end===void 0||t<=Date.parse(e.end))}function Be(t){return new Date(t).toISOString()}function Sn(t,e){return t.length===e.length&&t.every((n,r)=>n===e[r])}var kn=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"}),Ya=["mrtd","rtmr0","rtmr1","rtmr2","rtmr3"],No="https://cloud.calimero.network";async function Mo(t,e,n={}){let r=typeof t=="string"?new TextEncoder().encode(t):t;await Po(r,e,{identity:n.identity??kn.identity,issuer:n.issuer??kn.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=>Ya.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 _o(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 Go(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 Ho(t,e={}){let n=await qo(t,e.fetch??fetch);if(n===void 0)throw new Error(`${$o(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 $o(t){return`${t.replace(/\/+$/,"")}/admin-api/tee/info`}async function qo(t,e){let n=$o(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 Go(o)}function Lo(t,e){return`${t.replace(/\/+$/,"")}/api/tee/node-releases/${je(e,"version")}`}async function Ko(t){let e=je(t.minReleaseVersion,"minReleaseVersion"),n=je(t.release?.version,"The release version"),r=await Mo(t.release.publishedMrtds,t.release.bundle,{expectedVersion:n,identity:t.identity,issuer:t.issuer});if(Za(n,e)<0)throw new Error(`Release ${n} is older than the minimum trusted, ${e}`);return Rn([r],{profile:t.profile})}function Bo(t){return je(t.minReleaseVersion,"minReleaseVersion"),Object.assign(async n=>{let r=await Ko({release:await t.release(),profile:t.profile,minReleaseVersion:t.minReleaseVersion,identity:t.identity,issuer:t.issuer});return xn({dcapVerify:t.dcapVerify,fetchCollateral:t.fetchCollateral,now:t.now,...r})(n)},{includeCollateral:!0})}function Xa(t){let{baseUrl:e,releaseSource:n,releaseVersion:r,applicationId:o,applicationHash:i,fetch:a,...s}=t;r!==void 0&&je(r,"releaseVersion");let c=a??((p,l)=>fetch(p,l));return Ke({baseUrl:e,verify:Bo({...s,release:async()=>{let p=r===void 0?await Ho(e,{fetch:c}):await qo(e,c)??r;return typeof n=="function"?n({baseUrl:e,version:p,fetch:c}):_o(Lo(n??No,p),{fetch:c})}}),applicationId:o,applicationHash:i,fetch:c})}var jo=/^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/;function je(t,e){let n=typeof t=="string"?jo.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 Za(t,e){let[n,r]=Oo(t),[o,i]=Oo(e);for(let c=0;c<3;c+=1)if(n[c]!==o[c])return n[c]<o[c]?-1:1;if(r===void 0||i===void 0)return r===i?0:r===void 0?1:-1;let a=r.split("."),s=i.split(".");for(let c=0;c<Math.max(a.length,s.length);c+=1){let[u,p]=[a[c],s[c]];if(u===void 0||p===void 0)return u===void 0?-1:1;let[l,m]=[/^\d+$/.test(u),/^\d+$/.test(p)],y=l&&m?Math.sign(Number(u)-Number(p)):l!==m?l?-1:1:u<p?-1:u>p?1:0;if(y!==0)return y}return 0}function Oo(t){let e=jo.exec(t);return[[Number(e[1]),Number(e[2]),Number(e[3])],e[4]]}var Ct=1440*60,In={Admin:0,Member:1,ReadOnly:2};function Fe(t){let e=t.admitters??[];return g(En(t.inviter_identity,"inviter_identity"),En(t.group_id,"group_id"),x(t.expiration_timestamp),En(t.secret_salt,"secret_salt"),new Uint8Array([t.invited_role]),w(e.length),...e.map((n,r)=>d(n,`admitters[${r}]`,32)))}async function Pn(t){return new Uint8Array(await crypto.subtle.digest("SHA-256",Fe(t)))}function Tn(t){return[...new Set(t.filter(n=>n.role==="Admin").map(n=>n.identity.toLowerCase()))].sort()}async function Fo(t){let e=await C(t.deviceSecret,t.signer,"deviceSecret"),n=d(e.publicKey,"signer.publicKey",32),r=d(t.groupId,"groupId",32);d(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=Tn(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,y)=>d(m,`admitters[${y}]`,32));let i=t.invitedRole??In.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??Ct,Ct);if(!Number.isInteger(s)||s<=0)throw new Error(`validForSecs must be a positive whole number, got ${t.validForSecs}`);let c=t.nonce??crypto.getRandomValues(new Uint8Array(32));if(c.length!==32)throw new Error(`nonce must be 32 bytes, got ${c.length}`);let u={inviter_identity:Array.from(n),group_id:Array.from(r),expiration_timestamp:a+s,secret_salt:Array.from(c),invited_role:i,admitters:o},p=await e.sign(await Pn(u));if(p.length!==64)throw new Error(`signer returned ${p.length} bytes, expected a 64-byte Ed25519 signature`);let l={invitation:u,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(d(t.applicationId,"applicationId",32))),t.appKey&&(l.app_key=Array.from(d(t.appKey,"appKey",32))),l}function En(t,e){if(t.length!==32)throw new Error(`${e} must be 32 bytes, got ${t.length}`);return new Uint8Array(t)}var Dn=21,ec=new TextEncoder().encode("calimero.namespace.v1"),tc=0,Vo={GroupCreated:0,GroupReparented:1,GroupDeleted:2,AdminChanged:3,PolicyUpdated:4,MemberJoined:5,KeyDelivery:6,MemberJoinedOpen:7,MemberJoinedAt:8,NamespaceCreatedV2:9,MemberJoinedViaTeeAttestation:10};function Wo(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 Jo(t){let e=new TextEncoder().encode(t);return g(w(e.length),e)}function St(t){let e=t.invitation,n=t.admitter_addrs??[];return g(Fe(e),Jo(t.inviter_signature),t.inviter_account?g(new Uint8Array([1]),d(t.inviter_account,"inviter_account",32)):new Uint8Array([0]),w(n.length),...n.map(Jo),Wo(t.application_id,"application_id"),Wo(t.app_key,"app_key"))}async function zo(t){let e=t.parentOpHashes??[],n=d(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([Vo.MemberJoinedAt]),d(t.member,"member",32),St(t.invitation),x(o),n):g(new Uint8Array([Vo.MemberJoined]),d(t.member,"member",32),St(t.invitation),n),a=g(new Uint8Array([tc]),i),s=await C(t.deviceSecret,t.signer,"deviceSecret"),c=d(s.publicKey,"signer.publicKey",32),u=g(new Uint8Array([Dn]),d(t.namespaceId,"namespaceId",32),w(e.length),...e.map((m,y)=>d(m,`parentOpHashes[${y}]`,32)),c,x(t.nonce),a),p=await s.sign(g(ec,u)),l=new Uint8Array([0]);return h(g(u,p,l))}var nc=new TextEncoder().encode("calimero.account.owner-op.v1"),rc=new TextEncoder().encode("calimero.account.owner-op.body.v1"),oc=new TextEncoder().encode("calimero.account.genesis.v1"),ic=2,Un={transferOwnership:0,adminChanged:1,groupDelete:2,teeAdmissionPolicy:3,teeAuthoringPolicy:4,teeReleaseAdmissionPolicy:5},ve={GroupDelete:14,TransferOwnership:21,TeeAuthoringPolicySet:33,TeeAdmissionPolicySetV2:37,TeeReleaseAdmissionPolicySetV2:38,RootGuarded:42},Yo={AdminChanged:3,RootGuarded:12},sc={replica:0,relay:1},ac=new TextEncoder;function N(t){return new Uint8Array([t])}function Xo(t){let e=ac.encode(t);return g(w(e.length),e)}function j(t){return g(w(t.length),...t.map(Xo))}function Zo(t){return N(t?1:0)}function ei(t){let e=sc[t??"replica"];if(e===void 0)throw new Error(`mode must be replica or relay, got ${String(t)}`);return N(e)}function ti(t){return{kind:"transferOwnership",plane:"group",bytes:g(N(ve.TransferOwnership),d(t,"newOwner",32))}}function ni(){return{kind:"groupDelete",plane:"group",bytes:N(ve.GroupDelete)}}function ri(t){return{kind:"adminChanged",plane:"root",bytes:g(N(Yo.AdminChanged),d(t,"newAdmin",32))}}function oi(t){return{kind:"teeAuthoringPolicy",plane:"group",bytes:g(N(ve.TeeAuthoringPolicySet),j(t))}}function ii(t){return{kind:"teeAdmissionPolicy",plane:"group",bytes:g(N(ve.TeeAdmissionPolicySetV2),j(t.allowedMrtd),j(t.allowedRtmr0),j(t.allowedRtmr1),j(t.allowedRtmr2),j(t.allowedRtmr3),j(t.allowedTcbStatuses),Zo(t.acceptMock),ei(t.mode))}}function si(t){let e=t.minReleaseVersion===void 0?N(0):g(N(1),Xo(t.minReleaseVersion));return{kind:"teeReleaseAdmissionPolicy",plane:"group",bytes:g(N(ve.TeeReleaseAdmissionPolicySetV2),j(t.allowedProfiles),e,j(t.allowedTcbStatuses),Zo(t.acceptMock),ei(t.mode))}}async function On(t){return R(rc,[t])}async function Nn(t){return R(nc,[d(t.account,"account",32),d(t.namespaceId,"namespaceId",32),d(t.groupId,"groupId",32),N(ai(t.kind)),t.opDigest,x(t.counter),w(t.keyEpoch)])}function ai(t){let e=Un[t];if(e===void 0)throw new Error(`unknown owner-op kind ${String(t)}`);return e}var Qo=132;async function ci(t){let e=await J(t.rootSecret),n=g(N(ic),e),r=h(await R(oc,[n])),o=t.keyEpoch??0,i=(t.chain??[]).map((p,l)=>{let m=G(p,`chain[${l}]`);if(m.length!==Qo)throw new Error(`chain[${l}] must be a ${Qo}-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 On(t.op.bytes),s=await Nn({account:r,namespaceId:t.namespaceId,groupId:t.groupId,kind:t.op.kind,opDigest:a,counter:t.counter,keyEpoch:o}),c=await W(t.rootSecret),u=new Uint8Array(await crypto.subtle.sign("Ed25519",c,s));return h(g(n,w(i.length),...i,d(r,"account",32),d(t.namespaceId,"namespaceId",32),d(t.groupId,"groupId",32),N(ai(t.op.kind)),a,x(t.counter),w(o),u))}function li(t,e){let n=t.plane==="group"?ve.RootGuarded:Yo.RootGuarded;return g(N(n),t.bytes,G(e,"rootProof"))}var ui=[2428,2429,2528,2529],cc="localhost",lc=2e3;function di(t){return`http://${cc}:${t}`}function pi(t,e){let n=t.endsWith("/")?t:`${t}/`;return new URL(e,n).toString()}async function gi(t,e={}){let{timeoutMs:n=lc,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=pi(t,"admin-api/health"),u=await fetch(c,{method:"GET",signal:o.signal});if(!u.ok)return!1;try{let p=await u.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 uc(t={}){let{ports:e=ui,timeoutMs:n,signal:r}=t;return(await Promise.all(e.map(async i=>{let a=di(i);return await gi(a,{timeoutMs:n,signal:r})?a:null}))).filter(i=>i!==null)}var dc=new TextEncoder().encode("calimero.tee-attest.key-binding.v1"),kt=new TextEncoder().encode("MOCK_TDX_QUOTE_V1"),pc=568;function gc(...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 Mn(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 mc(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 hc(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 Et(t){let e=await crypto.subtle.digest("SHA-256",gc(dc,new Uint8Array(32),t));return new Uint8Array(e)}function _n(t){let e=t.length>=kt.length&&Mn(t.subarray(0,kt.length),kt),n=e?kt.length:pc;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 mi(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=hc(s.boundPublicKey,"boundPublicKey"),u=mc(s.quoteB64),{reportData:p,mock:l}=_n(u);if(l){if(!t.allowMock)throw new Error("the relay answered with a MOCK quote, which proves nothing about the hardware")}else if(t.verify){if(!await t.verify({quoteB64:s.quoteB64,nonce:h(e),reportDataSuffix:h(await Et(c)),...s.collateral?{collateral:s.collateral}:{}}))throw new Error("the relay's quote did not verify: not a trusted image, or not bound to this request")}else if(t.verifyQuote)await t.verifyQuote(u);else throw new Error("a real TDX quote needs a verify (or verifyQuote) to check its signature and measurements");if(!Mn(p.subarray(0,32),e))throw new Error("the quote does not carry our nonce: it was not made for this request");if(!Mn(p.subarray(32,64),await Et(c)))throw new Error("the quote does not bind the key the relay named: refusing it");return{nodeKey:h(c),mock:l}}export{rr as ACCOUNT_HA_AUDIENCE,nr as ACCOUNT_OWNERSHIP_AUDIENCE,Y as AccountHaRefusedError,De as AccountLinkedToSeveralUsersError,Te as AccountNotLinkedError,se as AdminApiClient,oe as AuthApiClient,V as AuthRevokedError,T as CAPABILITIES,Mc as CAPABILITY_PRESETS,q as CloudClient,ui as DEFAULT_LOCAL_NODE_PORTS,No as DEFAULT_RELEASE_MIRROR,Ie as EphemeralClient,lo as HANDSHAKE_PATH,S as HTTPError,Ue as HaRequestPendingError,In as INVITED_ROLE,ae as IntentRefusedError,Zt as LocalStorageTokenStore,Ct as MAX_INVITATION_VALIDITY_SECS,Xt as MemoryTokenStore,le as MeroClient,fe as MeroJs,kn as NODE_RELEASE_SIGNER,Un as OWNER_OP_KIND,Yr as PRESENCE_DOMAIN,pn as REQUEST_PROOF_HEADER,Z as RelayClient,Ne as RelayNotDialableError,ye as RelayObserver,He as RelayPresenceClient,ce as RelayTransport,Ee as RpcClient,Ze as RpcError,qe as SEALED_CONTENT_TYPE,uo as SEALED_PATH,Dn as SIGNED_NAMESPACE_OP_SCHEMA_VERSION,be as SealedTransportError,H as SseClient,Le as StaleTransportKeyError,Oe as UnknownRelayError,At as WarrantNonceExhaustedError,Je as WarrantNonceRouteUnavailableError,Ce as WebHttpClient,z as WsClient,ot as accountForRoot,$ as accountForRootPublicKey,dr as accountRootFromPhrase,Wt as accountRootFromSecret,gr as accountRootSignerFromPhrase,ri as adminChangedOp,ts as admitterAddrsFromNetworkStatus,Et as attestKeyBinding,mi as attestRelayNodeKey,Hs as authorNonceLookup,ga as beginCloudLink,Aa as beginDeviceEnrolment,Ht as buildAuthLoginUrl,Co as callbackIsForeign,Ye as callerProof,_c as capMask,Gc as capNames,Mt as classifyError,Ao as cloudLinkUrl,Lo as cloudNodeReleaseUrl,Tt as combineSignals,Ii as compareSemver,ha as completeCloudLink,Ra as completeDeviceEnrolment,bo as connectCloud,ca as connectCloudWithAccount,Vr as contextCapabilityGrantedOp,Wr as contextCapabilityRevokedOp,qr as contextDetachedOp,jr as contextMetadataSetOp,pr as createAccountRootSigner,jn as createAdminApiClient,ze as createAdminApiClientFromHttpClient,Ke as createAttestedSealedFetch,Oc as createAuthApiClient,$n as createAuthApiClientFromHttpClient,el as createBrowserAdminApiClient,Dc as createBrowserAuthApiClient,pe as createBrowserHttpClient,Se as createHttpClient,fn as createLocalStorageNonceSource,xt as createMemoryNonceSource,to as createMeroClient,is as createMeroJs,tl as createNodeAdminApiClient,Uc as createNodeAuthApiClient,Ve as createNodeHttpClient,mn as createProofAuthorizer,Xe as createProofSigner,xn as createQuoteVerifier,$s as createRecoveringNonceSource,xi as createRetryableMethod,ho as createSealedFetch,Xa as createSignedReleaseSealedFetch,Bo as createSignedReleaseVerifier,Dt as createTimeoutSignal,Ut as createUniversalHttpClient,an as createdSubgroupId,tn as creationInitHash,Tn as defaultAdmitters,wt as defaultAudience,gt as defaultCapabilitiesSetOp,nt as deviceCertPayload,vo as deviceEnrolmentUrl,jt as deviceScopePayload,uc as discoverLocalNodes,Fe as encodeGroupInvitation,St as encodeSignedInvitation,mo as fetchAttestedTransportKey,_o as fetchNodeRelease,Ho as fetchNodeReleaseVersion,mt as foundedNamespaceId,ur as generateAccountRoot,dn as generateSessionKey,nn as governanceOpHash,cn as groupCreatedOp,ni as groupDeleteOp,Hr as groupDeletedOp,Pn as groupInvitationHash,Kr as groupMetadataSetOp,Gr as groupReparentedOp,ie as hasCap,zc as hexEncodeUtf8,en as intentHash,Si as isSettled,Q as jsonCodec,di as localNodeUrl,bt as login,Ur as memberAddedOp,$r as memberCapabilitySetOp,Jr as memberJoinedOpenOp,Nr as memberLeftOp,Br as memberMetadataSetOp,Or as memberRemovedOp,Mr as memberRoleSetOp,ir as mintDeviceId,ht as namespaceCreatedOp,pi as nodeEndpoint,Go as nodeReleaseVersionFromImage,On as ownerOpDigest,Nn as ownerOpSigningPayload,Gt as parseAuthCallback,Ir as parseCreationWarrant,Bt as parseDeviceCredential,Pr as parseGovernanceWarrant,Ln as parseWarrantNonce,hn as presenceStatementBytes,gi as probeNodeHealth,ma as readCloudLinkCallback,xa as readEnrolmentCallback,qn as redeemInvitation,_n as reportDataOf,$t as requestBodyHash,K as resolveRoot,it as resolveRootPair,li as rootGuardedOpBytes,at as routingProofHeaders,Kc as shouldRetain,Kt as signAccountHaClaim,Pe as signAccountLink,st as signAccountLogin,$i as signAccountOwnershipClaim,ut as signCreationWarrant,ar as signDeviceCert,cr as signDeviceScope,_e as signGovernanceWarrant,Fo as signGroupInvitation,yt as signLoginStatement,zo as signMemberJoinOp,ci as signOwnerOpProof,Qe as signRequest,gn as signRequestProof,vr as signRoutingChallenge,ct as signWarrant,Ms as signedPath,Yn as signerFromCryptoKey,ge as signerFromSecret,Xr as stateHash,_r as subgroupCreation,Lr as subgroupVisibilitySetOp,tt as subscribePresence,pt as targetApplicationSetOp,ii as teeAdmissionPolicyOp,oi as teeAuthoringPolicyOp,si as teeReleaseAdmissionPolicyOp,ti as transferOwnershipOp,go as transportKeyBinding,Ko as trustSignedRelease,Rn as trustedMeasurementsFromReleases,rt as verifyDeviceCredential,Mo as verifySignedNodeRelease,Ot as withCap,We as withRetry,Hc as withoutCap};
1
+ function Gn(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 s of e)s.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 $n(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 Us=new Set(["token_reuse","token_revoked"]);function Os(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 T=class extends Error{constructor(n,r,o,i,s){let a=Os(s)??(n===0&&s?.trim()?s.trim():void 0);super(a?`HTTP ${n} ${r}: ${a}`:`HTTP ${n} ${r}`);this.status=n;this.statusText=r;this.url=o;this.headers=i;this.bodyText=s;this.name="HTTPError";this.explanation=a}toJSON(){return{status:this.status,statusText:this.statusText,url:this.url,headers:Yr(this.headers),bodyText:this.bodyText}}},ee=class extends T{constructor(n,r,o,i,s,a){super(r,o,i,s,a);this.reason=n;this.name="AuthRevokedError";this.message=`Authentication revoked (${n}): HTTP ${r} ${o}`}};function Yr(t){let e={};return t.forEach((n,r)=>{e[r]=n}),e}function Ms(t){try{return new URL(t).pathname}catch{let e=t.indexOf("?");return e===-1?t:t.slice(0,e)}}var Be=class{constructor(e){this.transport=e;this.refreshTokenPromise=null;this.onTokenRefreshPromise=null}async get(e,n){return this.request(e,{...n,method:"GET"})}async post(e,n,r){return this.request(e,{...r,method:"POST",body:n?JSON.stringify(n):void 0,headers:{"Content-Type":"application/json",...r?.headers}})}async put(e,n,r){return this.request(e,{...r,method:"PUT",body:n?JSON.stringify(n):void 0,headers:{"Content-Type":"application/json",...r?.headers}})}async delete(e,n){return this.request(e,{...n,method:"DELETE"})}async patch(e,n,r){return this.request(e,{...r,method:"PATCH",body:n?JSON.stringify(n):void 0,headers:{"Content-Type":"application/json",...r?.headers}})}async head(e,n){let r=await this.makeRequest(e,{...n,method:"HEAD",parse:"response"});return{headers:Yr(r.headers),status:r.status}}async request(e,n){return this.makeRequest(e,n)}async makeRequest(e,n,r=0,o){let s=this.buildUrl(e),a=o??Date.now(),c=this.createAbortSignal(n),u=await this.buildHeaders(n?.headers),d;u instanceof Headers?(d={},u.forEach((A,R)=>{d[R]=A})):d=u;let l=n?.method||"GET";if(this.transport.authorizeRequest){let A=n?.body;if(A!==void 0&&typeof A!="string"&&!(A instanceof Uint8Array))throw new Error("this transport authorizes each request against its body, so the body must be a string or Uint8Array \u2014 a stream cannot be signed, because the signature would have to read bytes the request then cannot send.");Object.assign(d,await this.transport.authorizeRequest({method:l,path:new URL(s).pathname,body:A}))}let g={method:l,headers:d},w=n?.body instanceof ReadableStream||typeof n?.body=="object"&&n?.body!==null&&"getReader"in n.body&&!(n.body instanceof Blob);(n?.body!==void 0&&!w||n?.body!==void 0&&w&&r===0)&&(g.body=n.body);let x;if(r>0&&o!==void 0){let A=n?.timeoutMs||this.transport.timeoutMs;if(A){let R=Date.now()-a,I=Math.max(0,A-R);x=this.createAbortSignal({...n,timeoutMs:I})}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 A=await this.transport.getProof({method:g.method??"GET",path:Ms(s),body:g.body});A&&(d["X-Calimero-Proof"]=A)}try{let A=await this.transport.fetch(s,g);if(!A.ok){let R=await this.getBodyText(A),I=new T(A.status,A.statusText,s,A.headers,R),P=A.headers.get("x-auth-error");if((A.status===401||A.status===403)&&P&&Us.has(P)){if(this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,this.transport.onAuthRevoked)try{await this.transport.onAuthRevoked()}catch{}throw new ee(P,A.status,A.statusText,s,A.headers,R)}let j=n?.signal?.aborted===!0;if(A.status===401&&this.transport.refreshToken&&P==="token_expired"&&r<1&&!w&&!j)try{let M=this.refreshTokenPromise;M||(M=this.transport.refreshToken(),this.refreshTokenPromise=M);let h=await M;if(!h||h.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 y=this.onTokenRefreshPromise;y||(y=this.transport.onTokenRefresh(h),this.onTokenRefreshPromise=y),await y,this.refreshTokenPromise=null,this.onTokenRefreshPromise=null;let S=n?.timeoutMs||this.transport.timeoutMs;if(S&&o!==void 0){let N=Date.now()-a;if(S-N<=0)throw I}return this.makeRequest(e,n,r+1,a)}catch(M){throw this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,M instanceof Error&&M.message.includes("onTokenRefresh")?M:I}throw I}return this.parseResponse(A,n?.parse)}catch(A){throw A instanceof T||A instanceof Error&&A.message.includes("onTokenRefresh")?A:new T(0,"Network Error",s,new Headers,A instanceof Error?A.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($n(r)),n.length>0?Gn(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 je(t){return new Be(t)}function Ae(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 je(e)}function bt(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 je(r)}function Hn(t){return typeof window<"u"?Ae(t):bt(t)}function _s(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 Gs(t){let n=250*Math.pow(2,t-1),r=(Math.random()-.5)*.4*n;return Math.max(0,n+r)}async function wt(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,!_s(r,n-o))throw r;let s=Gs(o),u=r.headers?.get?.("Retry-After");if(u){let d=parseInt(u,10);if(!isNaN(d))s=Math.max(s,d*1e3);else{let l=new Date(u);if(!isNaN(l.getTime())){let g=Math.max(0,l.getTime()-Date.now());s=Math.max(s,Math.min(g,6e4))}}}await new Promise(d=>setTimeout(d,s))}throw r||new Error("Retry failed without error")}function $s(t,e={}){return async(...n)=>wt(()=>t(...n),e)}var ae=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 Fe=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 yu(t){let e=new Fe;return new ae(e)}function bu(t){let e=new Fe;return new ae(e)}function wu(t){let e=new Fe;return new ae(e)}function Xr(t,e){return new ae(t)}var O={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},xu={NONE:0,JOIN_ONLY:O.CAN_JOIN_OPEN_SUBGROUPS,CONTRIBUTOR:O.CAN_CREATE_CONTEXT|O.CAN_INVITE_MEMBERS|O.CAN_JOIN_OPEN_SUBGROUPS,COLLABORATOR:O.CAN_CREATE_CONTEXT|O.CAN_INVITE_MEMBERS|O.CAN_JOIN_OPEN_SUBGROUPS|O.CAN_CREATE_SUBGROUP|O.CAN_DELETE_SUBGROUP|O.CAN_MANAGE_VISIBILITY};function vu(...t){let e=0;for(let n of t)if(typeof n=="number")e|=n;else if(Object.prototype.hasOwnProperty.call(O,n))e|=O[n];else throw new Error(`unknown capability: ${String(n)}`);return e>>>0}function Ru(t){return Object.keys(O).filter(e=>ce(t,O[e]))}function ce(t,e){let n=e>>>0;return(t&n)>>>0===n}function Ln(t,e){return(t|e)>>>0}function Cu(t,e){return(t&~e)>>>0}var Hs={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 Ls(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 Ks(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 Kn(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 qn(t){let e=Ks(t),n;return e!==void 0?n=Ls(e):t instanceof TypeError?n="unreachable":n="unknown",{kind:n,status:e,retryable:Hs[n],message:Kn(t)}}function qs(t){return t.status!=="failed"||!t.retryable}function Iu(t){return!qs(t)}function Bs(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 js(t,e){let{kind:n,status:r}=qn(t),o=Bs(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 Zr(t,e){let{namespaceId:n,invitation:r,teamName:o}=t,i=null;try{await e.join(n,r)}catch(d){i=d}let s=null;try{s=(await e.memberships()).includes(n)}catch{s=null}if(i===null)return{status:"joined",namespaceId:n,teamName:o};if(s===!0)return{status:"already-member",namespaceId:n,teamName:o};let a=Kn(i,"Could not join. Check the invitation."),{reason:c,retryable:u}=js(i,a);return{status:"failed",namespaceId:n,message:a,reason:c,retryable:u}}var At=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 Bn(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 eo(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:Bn(t,n,"highWaterNonce"),windowWidth:Bn(t,n,"windowWidth")??0n},o=Bn(t,n,"nextNonce");return o===void 0?{...r,kind:"exhausted",seen:!0,highWaterNonce:r.highWaterNonce??0xffffffffffffffffn}:{...r,kind:"open",nextNonce:o}}function b(t){return t?.data}function Fs(t,e){let[n,r]=to(t),[o,i]=to(e),s=n.split("."),a=o.split("."),c=Math.max(s.length,a.length);for(let g=0;g<c;g++){let w=no(s[g]??"0",a[g]??"0");if(w!==0)return w}if(r===void 0&&i===void 0)return 0;if(r===void 0)return 1;if(i===void 0)return-1;let u=r.split("."),d=i.split("."),l=Math.max(u.length,d.length);for(let g=0;g<l;g++){if(g>=u.length)return-1;if(g>=d.length)return 1;let w=no(u[g],d[g]);if(w!==0)return w}return 0}function to(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 no(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 Vs(t,e,n){return wt(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 le=class{constructor(e){this.httpClient=e}async healthCheck(){return b(await this.httpClient.get("/admin-api/health"))}async readinessCheck(){return b(await this.httpClient.get("/admin-api/ready"))}async isAuthed(){return this.httpClient.get("/admin-api/is-authed")}async installApplication(e){return b(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 Vs(r.toString(),"versions",n)).json();return(Array.isArray(i)?i:[]).map(s=>s.appVersion).filter(s=>typeof s=="string").sort((s,a)=>Fs(a,s))}async installDevApplication(e){return b(await this.httpClient.post("/admin-api/install-dev-application",e))}async uninstallApplication(e){return b(await this.httpClient.delete(`/admin-api/applications/${e}`))}async listApplications(){return b(await this.httpClient.get("/admin-api/applications"))}async getApplication(e){return b(await this.httpClient.get(`/admin-api/applications/${e}`))}async listApplicationVersions(e){return b(await this.httpClient.get(`/admin-api/applications/${e}/versions`))}async getApplicationAbi(e,n){let r=n?`?service_name=${encodeURIComponent(n)}`:"";return b(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 b(await this.httpClient.post("/admin-api/contexts",n))}async deleteContext(e){return b(await this.httpClient.delete(`/admin-api/contexts/${e}`))}async getContexts(){return b(await this.httpClient.get("/admin-api/contexts"))}async getContext(e){return b(await this.httpClient.get(`/admin-api/contexts/${e}`))}async getContextsForApplication(e){return b(await this.httpClient.get(`/admin-api/contexts/for-application/${e}`))}async generateContextIdentity(){return b(await this.httpClient.post("/admin-api/identity/context",{}))}async getContextIdentities(e){return b(await this.httpClient.get(`/admin-api/contexts/${e}/identities`))}async getContextIdentitiesOwned(e){return b(await this.httpClient.get(`/admin-api/contexts/${e}/identities-owned`))}async joinContext(e){return b(await this.httpClient.post(`/admin-api/contexts/${e}/join`,{}))}async getContextGroup(e){return b(await this.httpClient.get(`/admin-api/contexts/${e}/group`))}async getContextStorage(e){return b(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 b(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=b(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:b(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 b(await this.httpClient.post("/admin-api/alias/create/context",{alias:e.alias,contextId:e.contextId}))}async createApplicationAlias(e){return b(await this.httpClient.post("/admin-api/alias/create/application",{alias:e.alias,applicationId:e.applicationId}))}async lookupContextAlias(e){return b(await this.httpClient.post(`/admin-api/alias/lookup/context/${encodeURIComponent(e)}`,{}))}async lookupApplicationAlias(e){return b(await this.httpClient.post(`/admin-api/alias/lookup/application/${encodeURIComponent(e)}`,{}))}async deleteContextAlias(e){return b(await this.httpClient.post(`/admin-api/alias/delete/context/${encodeURIComponent(e)}`,{}))}async deleteApplicationAlias(e){return b(await this.httpClient.post(`/admin-api/alias/delete/application/${encodeURIComponent(e)}`,{}))}async listContextAliases(){return b(await this.httpClient.get("/admin-api/alias/list/context"))}async listApplicationAliases(){return b(await this.httpClient.get("/admin-api/alias/list/application"))}async createDeviceAlias(e){return b(await this.httpClient.post("/admin-api/alias/create/device",{alias:e.alias,deviceId:e.deviceId}))}async lookupDeviceAlias(e){return b(await this.httpClient.post(`/admin-api/alias/lookup/device/${encodeURIComponent(e)}`,{}))}async deleteDeviceAlias(e){return b(await this.httpClient.post(`/admin-api/alias/delete/device/${encodeURIComponent(e)}`,{}))}async listDeviceAliases(){return b(await this.httpClient.get("/admin-api/alias/list/device"))}async listNamespaces(){return b(await this.httpClient.get("/admin-api/namespaces"))}async getNamespace(e){return b(await this.httpClient.get(`/admin-api/namespaces/${e}`))}async getNodeIdentity(){return b(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 b(await this.httpClient.post(`/admin-api/contexts/${e}/intents`,n))}async queryContext(e,n){return b(await this.httpClient.post(`/admin-api/contexts/${e}/query`,n))}async getIntentRelay(e){return b(await this.httpClient.get(`/admin-api/contexts/${e}/intents`))}async listNamespacesForApplication(e){return b(await this.httpClient.get(`/admin-api/namespaces/for-application/${e}`))}async createNamespace(e){return b(await this.httpClient.post("/admin-api/namespaces",e))}async deleteNamespace(e){return b(await this.httpClient.request(`/admin-api/namespaces/${e}`,{method:"DELETE",body:"{}",headers:{"Content-Type":"application/json"}}))}async createNamespaceInvitation(e,n){return b(await this.httpClient.post(`/admin-api/namespaces/${e}/invite`,n??{}))}async admitJoin(e,n){return b(await this.httpClient.post(`/admin-api/namespaces/${e}/admit`,n,{timeoutMs:65e3}))}async joinNamespace(e,n){let r=b(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 Zr({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(s=>s.namespaceId)})}async createGroupInNamespace(e,n){return b(await this.httpClient.post(`/admin-api/namespaces/${e}/groups`,n??{}))}async listNamespaceGroups(e){return b(await this.httpClient.get(`/admin-api/namespaces/${e}/groups`))}async initAccountPairing(e){return b(await this.httpClient.post("/admin-api/account/pair-init",e))}async completeAccountPairing(e){return b(await this.httpClient.post("/admin-api/account/pair-complete",e))}async relinkAccountDevice(e,n){return b(await this.httpClient.post(`/admin-api/account/devices/${e}/relink`,n??{}))}async rescopeAccountDevice(e,n){return b(await this.httpClient.put(`/admin-api/account/devices/${encodeURIComponent(e)}/scope`,n))}async signWithAccountRoot(e){return b(await this.httpClient.post("/admin-api/account/sign-with-root",e))}async labelAccountDevice(e,n){return b(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 b(await this.httpClient.post(`/admin-api/namespaces/${e}/account/revoke`,n))}async linkAccountDevice(e,n){return b(await this.httpClient.post(`/admin-api/namespaces/${e}/account/link-device`,n))}async getGroupInfo(e){return b(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 b(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 T&&i.status===404?new At(r,i):i}return eo(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 T&&i.status===404?new At(r,i):i}return eo(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 b(await this.httpClient.post(`/admin-api/groups/${e}/accounts/${n}/seal`,r))}async listGroupContexts(e){return b(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 b(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(ce(n,O.CAN_AUTHOR_ON_BEHALF))return{changed:!1,defaultCapabilities:n};let r=Ln(n,O.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(ce(r,O.CAN_AUTHOR_ON_BEHALF))return{changed:!1,capabilities:r};let o=Ln(r,O.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 b(await this.httpClient.post(`/admin-api/groups/${e}/sync`,{}))}async upgradeGroup(e,n){return b(await this.httpClient.post(`/admin-api/groups/${e}/upgrade`,n))}async getGroupUpgradeStatus(e){return b(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 b(await this.httpClient.get(`/admin-api/groups/${n}/cascade-status`))}async retryGroupUpgrade(e){return b(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 b(await this.httpClient.post(`/admin-api/groups/${e}/invite`,n??{}))}async joinGroup(e){return b(await this.httpClient.post("/admin-api/groups/join",e))}async joinSubgroupInheritance(e){return b(await this.httpClient.post(`/admin-api/groups/${e}/join-via-inheritance`,{}))}async getTeeInfo(){return b(await this.httpClient.get("/admin-api/tee/info"))}async teeAttest(e){return b(await this.httpClient.post("/admin-api/tee/attest",e))}async teeVerifyQuote(e){return b(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 b(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 Mu(t){return Array.from(new TextEncoder().encode(t),e=>e.toString(16).padStart(2,"0")).join("")}function Lu(t){return new le(Ae(t))}function Ku(t){return new le(bt(t))}function ro(t){return new le(Hn(t))}function xt(t,e){return new le(t)}function jn(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 Fn(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 oo=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,112,4,34,4,32]);function v(t){let e=new Uint8Array(4);return new DataView(e.buffer).setUint32(0,t,!0),e}function f(t){return Array.from(t,e=>e.toString(16).padStart(2,"0")).join("")}function p(t,e,n){let r=t.trim();if(!/^[0-9a-fA-F]*$/.test(r)||r.length!==n*2)throw new Error(`${e} must be ${n*2} hex characters, got ${r.length}`);let o=new Uint8Array(n);for(let i=0;i<n;i+=1)o[i]=Number.parseInt(r.slice(i*2,i*2+2),16);return o}function F(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 C(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 k(t,e){let n=[C(t.length),t];for(let r of e)n.push(C(r.length),r);return new Uint8Array(await crypto.subtle.digest("SHA-256",m(...n)))}async function te(t){let e=p(t,"deviceSecret",32),n=m(oo,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 io(t,e,n){let r=await crypto.subtle.importKey("raw",p(t,"publicKey",32),{name:"Ed25519"},!1,["verify"]);return crypto.subtle.verify({name:"Ed25519"},r,e,n)}async function ne(t){let e=p(t,"deviceSecret",32),n=m(oo,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,"/")),s=>s.charCodeAt(0))}var Ws=new TextEncoder().encode("calimero.auth.request.v1"),Js=new TextEncoder().encode("calimero.auth.request.body.v1");function so(t){let e=new TextEncoder().encode(t);return m(v(e.length),e)}async function Vn(t=new Uint8Array(0)){let e=typeof t=="string"?new TextEncoder().encode(t):t;return k(Js,[e])}async function vt(t){let e=await te(t.signerSecret),n=await Vn(t.body),r=C(t.issuedAt),o=C(t.expiresAt),i=new TextEncoder,s=await k(Ws,[i.encode(t.method),i.encode(t.path),n,r,o]),a=new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},e,s));return f(m(so(t.method),so(t.path),n,r,o,a))}function Rt(t){let e=F(t.credential,"credential"),n=F(t.request,"request signature"),r=t.session===void 0?new Uint8Array([0]):m(new Uint8Array([1]),F(t.session,"session statement"));return f(m(e,r,n))}function zs(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 Ct(t){let e=t.ttlSeconds??120,n=t.now??(()=>Math.floor(Date.now()/1e3));return async r=>{let o=n();return Rt({credential:t.credential,session:t.session,request:await vt({method:r.method,path:r.path,body:zs(r.body),issuedAt:o,expiresAt:o+e,signerSecret:t.signerSecret})})}}var St=class extends Error{constructor(e,n,r,o){super(n),this.name="RpcError",this.code=e,this.data=r,this.type=o}};async function Wn(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 St(o.code??-1,o.message??o.type??"RPC error",o.data,o.type)}return r.result}var Ve=class{constructor(e){this.kind="node";this.canSubscribe=!0;this.httpClient=e.httpClient}async execute(e){let n=await Wn(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 Qs=new Set(["MigrationStarted","MigrationProgress","CascadeProgress","MigrationCompleted"]);function ao(t){return t.type!==void 0&&Qs.has(t.type)}var Ys=new Set(["token_reuse","token_revoked"]),Xs=new Set([401,403]);function co(t){let e=t.headers.get("x-auth-error");return!e||!Xs.has(t.status)?null:Ys.has(e)?e:null}var q=class{constructor(e){this.sessionId=null;this.abortController=null;this.reconnectTimer=null;this.subscribedContextIds=new Set;this.subscribedGroupIds=new Set;this.presence=new Map;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=>{ao(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=co(n),o=await n.text().catch(()=>{});throw r?new ee(r,n.status,n.statusText,e,n.headers,o):new T(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 ee)return;this.scheduleReconnect()}}}async readStream(e){let n=e.getReader(),r=new TextDecoder,o="";try{for(;;){let{done:i,value:s}=await n.read();if(i)break;o+=r.decode(s,{stream:!0});let a=o.split(`
2
+ `);o=a.pop()??"";for(let c of a)if(c.startsWith("data:")){let u=c.slice(5).trim();u&&this.handleMessage(u)}}if(o+=r.decode(),o.startsWith("data:")){let i=o.slice(5).trim();i&&this.handleMessage(i)}}catch(i){if(this.closed)return;let s=i instanceof Error?i:new Error(String(i));this.emit("error",s)}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.presence.clear(),(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){n.result.type==="Ephemeral"&&this.notePresence(n.result.contextId,r),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})}isSubscribed(e){return this.subscribedContextIds.has(e)}presenceSeed(e){let n=Date.now();return[...this.presence.get(e)?.values()??[]].map(({data:r,at:o})=>({...r,ageMs:(typeof r.ageMs=="number"?r.ageMs:0)+(n-o)}))}notePresence(e,n){if(!this.subscribedContextIds.has(e))return;let r=n;if(!r||typeof r.author!="string")return;let o=this.presence.get(e);o||this.presence.set(e,o=new Map),r.removed?o.delete(r.author):o.set(r.author,{data:r,at:Date.now()})}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),this.presence.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}),s=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(!s.ok){let a=co(s),c=await s.text().catch(()=>{});this.emit("error",a?new ee(a,s.status,s.statusText,`${this.baseUrl}/sse/subscription`,s.headers,c):new T(s.status,s.statusText,`${this.baseUrl}/sse/subscription`,s.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 kt=class kt{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),kt.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()}};kt.MAX_BACKOFF_MS=3e4;var re=kt;function oe(){return{encode(t){return Array.from(new TextEncoder().encode(JSON.stringify(t)))},decode(t){return JSON.parse(new TextDecoder().decode(new Uint8Array(t)))}}}var We=class{constructor(e){this.httpClient=e.httpClient,this.sse=e.sse}async set(e,n,r=oe()){await Wn(this.httpClient,"set_ephemeral",{contextId:e,state:r.encode(n)})}subscribe(e,n,r=oe()){return Et(this.sse,e,n,r)}};function Et(t,e,n,r=oe()){let o=i=>{let s=i;if(s.type!=="Ephemeral"||s.contextId!==e)return;let a=s.data;if(!a?.author)return;let c=!!a.removed,u={author:a.author,state:c||a.state===void 0?void 0:r.decode(a.state),removed:c};a.ageMs!==void 0&&(u.ageMs=a.ageMs),a.account!==void 0&&(u.account=a.account),n(u)};if(t.on("event",o),t.isSubscribed?.(e))for(let i of t.presenceSeed?.(e)??[])o({contextId:e,type:"Ephemeral",data:i});return t.connect().catch(()=>{}),t.subscribe([e]).catch(()=>{}),()=>{t.off("event",o)}}var Zs=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,112,4,34,4,32]);function lo(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 xe(t,e="secret"){let n=p(t,e,32),r=m(Zs,n),o,i;try{let s=await crypto.subtle.importKey("pkcs8",r,{name:"Ed25519"},!0,["sign"]),a=await crypto.subtle.exportKey("jwk",s);i=f(Uint8Array.from(atob(a.x.replace(/-/g,"+").replace(/_/g,"/")),c=>c.charCodeAt(0))),o=await crypto.subtle.importKey("pkcs8",r,{name:"Ed25519"},!1,["sign"])}catch(s){throw lo(s)}return po(o,i)}async function uo(t,e){if(t.type!=="private")throw new Error(`signerFromCryptoKey needs the private half of the pair, got a ${t.type} key`);if(!t.usages.includes("sign"))throw new Error("this CryptoKey cannot sign: generate it with usages ['sign', 'verify']");let n;if(typeof e=="string")p(e,"publicKey",32),n=e.trim().toLowerCase();else try{n=f(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 po(t,n)}function po(t,e){return{publicKey:e,async sign(n){try{return new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},t,n))}catch(r){throw lo(r)}}}}async function E(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 xe(t,n);throw new Error(`${n} or signer is required`)}var ea=new TextEncoder().encode("calimero.mdma.account-ownership-claim.v1\0"),ta=6e4,go=5*6e4,mo=1024,fo="mdma:enable-ha-namespace",yo="mdma:enable-ha-namespace-as-account";function ho(t){let e="";for(let n of t)e+=String.fromCharCode(n);return btoa(e)}var Jn=(t,e)=>{if(!/^[0-9a-fA-F]{64}$/.test(t))throw new Error(`${e} must be 64 hex characters`);return t.toLowerCase()};async function bo(t,e,n,r){if(r!==void 0&&!(r.length>0&&r.length<=mo))throw new Error(`relayUrl must be a non-empty string of at most ${mo} characters`);let o=t.ttlMs??ta;if(!(o>0&&o<=go))throw new Error(`ttlMs must be in (0, ${go}]`);let i=Jn(t.namespaceId,"namespaceId"),s=Jn(t.accountId,"accountId"),a=Jn(t.salt,"salt"),c=await E(t.deviceSecret,t.signer,"deviceSecret"),u=(t.now??Date.now)(),d=Array.from(crypto.getRandomValues(new Uint8Array(16)),w=>w.toString(16).padStart(2,"0")).join(""),l=new TextEncoder().encode(JSON.stringify({v:1,audience:e,group_id:i,account_id:s,salt:a,...n===void 0?{}:{subject:n},nonce:d,issued_at_ms:u,expires_at_ms:u+o,...r===void 0?{}:{relay_url:r}})),g=await c.sign(m(ea,l));return{kind:"account",credential:t.credential,signed_payload:ho(l),signature:ho(g)}}async function na(t){if(!t.subject)throw new Error("subject must be the cloud login email");return bo(t,fo,t.subject)}async function zn(t){return bo(t,yo,void 0,t.relayUrl)}var ra=new TextEncoder().encode("calimero.device.cert.v1"),oa=new TextEncoder().encode("calimero.account.genesis.v1"),ia=new TextEncoder().encode("calimero.device.id.v1"),ve=2,sa=237;async function wo(t,e){if(e.length!==16)throw new Error(`nonce must be 16 bytes, got ${e.length}`);let n=p(t,"account",32);return f(await k(ia,[n,e]))}async function It(t){return k(ra,[p(t.account,"account",32),p(t.device,"device",32),p(t.signPublicKey,"signPublicKey",32),p(t.kemPublicKey,"kemPublicKey",32),v(t.keyEpoch),v(t.deviceEpoch)])}function Ao(t){return m(new Uint8Array([ve]),t.rootPublicKey,v(0),p(t.account,"account",32),p(t.device,"device",32),p(t.signPublicKey,"signPublicKey",32),p(t.kemPublicKey,"kemPublicKey",32),v(t.keyEpoch),v(t.deviceEpoch),t.signature)}async function xo(t){let e=await E(t.rootSecret,t.signer,"rootSecret"),n=p(e.publicKey,"signer.publicKey",32),r=await V(e.publicKey),o=0,i=await It({account:r,device:t.device,signPublicKey:t.signPublicKey,kemPublicKey:t.kemPublicKey,keyEpoch:o,deviceEpoch:t.deviceEpoch}),s=await e.sign(i),a=Ao({rootPublicKey:n,account:r,device:t.device,signPublicKey:t.signPublicKey,kemPublicKey:t.kemPublicKey,keyEpoch:o,deviceEpoch:t.deviceEpoch,signature:s});return f(a)}function Qn(t){let e=p(t,"credential",sa);if(e[0]!==ve)throw new Error(`this credential has account genesis version ${e[0]}, not ${ve} \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,s)=>f(e.subarray(i,i+s));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 Pt(t){let e=Qn(t),n=await V(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 io(e.rootPublicKey,p(e.signature,"signature",64),await It(e)))throw new Error(`the root key of account ${e.account} did not sign this certificate`);return e}async function Tt(t){return V(f(await ne(t)))}async function V(t){return f(await k(oa,[m(new Uint8Array([ve]),p(t,"rootPublicKey",32))]))}var aa=new TextEncoder().encode("calimero.device.scope.v1");async function Yn(t){return k(aa,[p(t.account,"account",32),p(t.device,"device",32),v(t.scopeEpoch),v(t.keyEpoch),...t.applications.map((e,n)=>p(e,`applications[${n}]`,32))])}async function vo(t){let e=await E(t.rootSecret,t.signer,"rootSecret"),n=p(e.publicKey,"signer.publicKey",32),r=await V(f(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 s=0,a=await Yn({account:r,device:t.device,applications:o,scopeEpoch:i,keyEpoch:s}),c=await e.sign(a);if(c.length!==64)throw new Error(`signer returned ${c.length} bytes, expected a 64-byte Ed25519 signature`);return f(m(new Uint8Array([ve]),n,v(0),p(r,"account",32),p(t.device,"device",32),v(o.length),...o.map((u,d)=>p(u,`applications[${d}]`,32)),v(i),v(s),c))}var Xn=["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 ca=new TextEncoder().encode("calimero.mdma.account-link.v1\0"),la=new TextEncoder().encode("calimero.mdma.account-login.v1\0"),Re=256,Ro=Re/32,Zn=(Re+Ro)/11;async function Co(){let t=crypto.getRandomValues(new Uint8Array(Re/8));return To(f(t),await No(t))}async function So(t){let e=Do(t);return To(f(await Uo(e)),e.join(" "))}async function er(t){return p(t,"secret",32),{secret:t,publicKey:f(await ne(t)),accountId:await Tt(t)}}async function ko(){let t=crypto.getRandomValues(new Uint8Array(Re/8)),e=await No(t);return{...await Io(t),phrase:e}}async function Eo(t){return Io(await Uo(Do(t)))}async function Io(t){let e=await xe(f(t),"rootSecret");return t.fill(0),{publicKey:e.publicKey,accountId:await V(e.publicKey),signer:e}}async function Y(t){let e=typeof t=="string"?await xe(t,"rootSecret"):t;return Po(e)}async function Dt(t,e){return Po(await E(t,e,"rootSecret"))}async function Po(t){return{signer:t,publicKey:t.publicKey,accountId:await V(t.publicKey)}}async function Je(t){if(!t.nonce)throw new Error("nonce is required to sign an account link");let n=await(await E(t.rootSecret,t.signer,"rootSecret")).sign(m(ca,new TextEncoder().encode(t.nonce)));return _o(n)}async function Nt(t){if(!t.nonce)throw new Error("nonce is required to sign an account login");let n=await(await E(t.rootSecret,t.signer,"rootSecret")).sign(m(la,new TextEncoder().encode(t.nonce)));return _o(n)}async function To(t,e){return{...await er(t),phrase:e}}function Do(t){let e=t.normalize("NFKD").toLowerCase().trim().split(/\s+/),n=e[0]===""?0:e.length;if(n!==Zn)throw new Error(`recovery phrase must be ${Zn} words, got ${n}`);return e}async function No(t){let e=Mo(t)+await Oo(t),n=[];for(let r=0;r<Zn;r+=1){let o=Number.parseInt(e.slice(r*11,r*11+11),2);n.push(Xn[o])}return n.join(" ")}async function Uo(t){let e="";for(let r of t){let o=Xn.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(Re/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(Re)!==await Oo(n))throw new Error("recovery phrase checksum failed \u2014 check for a mistyped or transposed word");return n}async function Oo(t){let e=new Uint8Array(await crypto.subtle.digest("SHA-256",t));return Mo(e).slice(0,Ro)}function Mo(t){let e="";for(let n of t)e+=n.toString(2).padStart(8,"0");return e}function _o(t){let e="";for(let n of t)e+=String.fromCharCode(n);return btoa(e)}var ua=new TextEncoder().encode("calimero.tee-attest.key-binding.v1"),Ut=new TextEncoder().encode("MOCK_TDX_QUOTE_V1"),da=568;function pa(...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 tr(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 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}function ma(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 Ot(t){let e=await crypto.subtle.digest("SHA-256",pa(ua,new Uint8Array(32),t));return new Uint8Array(e)}function nr(t){let e=t.length>=Ut.length&&tr(t.subarray(0,Ut.length),Ut),n=e?Ut.length:da;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 Mt(t){let e=crypto.getRandomValues(new Uint8Array(32)),n=`${t.relayUrl.replace(/\/+$/,"")}/admin-api/tee/attest`,r=JSON.stringify({nonce:f(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 s=await i.json(),a=s.data??s;if(typeof a.quoteB64!="string")throw new Error("the relay returned no quote");let c=ma(a.boundPublicKey,"boundPublicKey"),u=ga(a.quoteB64),{reportData:d,mock:l}=nr(u);if(l){if(!t.allowMock)throw new Error("the relay answered with a MOCK quote, which proves nothing about the hardware")}else if(t.verify){if(!await t.verify({quoteB64:a.quoteB64,nonce:f(e),reportDataSuffix:f(await Ot(c)),...a.collateral?{collateral:a.collateral}:{}}))throw new Error("the relay's quote did not verify: not a trusted image, or not bound to this request")}else if(t.verifyQuote)await t.verifyQuote(u);else throw new Error("a real TDX quote needs a verify (or verifyQuote) to check its signature and measurements");if(!tr(d.subarray(0,32),e))throw new Error("the quote does not carry our nonce: it was not made for this request");if(!tr(d.subarray(32,64),await Ot(c)))throw new Error("the quote does not bind the key the relay named: refusing it");return{nodeKey:f(c),mock:l}}var ha="Noise_NK_25519_AESGCM_SHA256",rr=32,fa=16,ya=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,110,4,34,4,32]),ir=class t{constructor(e){this.k=null;this.n=0;this.ck=e,this.h=e}static async initialize(){let e=new TextEncoder().encode(ha),n=new Uint8Array(32);return n.set(e),new t(n)}async mixHash(e){this.h=await wa(m(this.h,e))}async mixKey(e){let[n,r]=await Ho(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:$o(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:$o(this.n),additionalData:this.h},this.k,e));return this.n+=1,await this.mixHash(e),n}split(){return Ho(this.ck,new Uint8Array)}};async function Lo(t,e,n){let r=await ir.initialize();await r.mixHash(e),await r.mixHash(t);let o=await ba(n);return await r.mixHash(o.publicKey),await r.mixKey(await Go(o.privateKey,t)),{message1:m(o.publicKey,await r.encryptAndHash(new Uint8Array)),async finish(s){if(s.length<rr+fa)throw new Error("Noise: message 2 is too short");let a=s.slice(0,rr);return await r.mixHash(a),await r.mixKey(await Go(o.privateKey,a)),{payload:await r.decryptAndHash(s.slice(rr)),split:await r.split()}}}}async function ba(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(ya,t),{name:"X25519"},!0,["deriveBits"]),n=await crypto.subtle.exportKey("jwk",e);return{privateKey:e,publicKey:Aa(n.x)}}async function Go(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 $o(t){let e=new Uint8Array(12);return new DataView(e.buffer).setBigUint64(4,BigInt(t),!1),e}async function wa(t){return new Uint8Array(await crypto.subtle.digest("SHA-256",t))}async function or(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 Ho(t,e){let n=await or(t,e),r=await or(n,new Uint8Array([1])),o=await or(n,m(r,new Uint8Array([2])));return[r,o]}function Aa(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 jo="/sealed/v2/handshake",Fo="/sealed/v2",Qe="application/vnd.calimero.sealed",sr=2,xa=new TextEncoder().encode("calimero/sealed-http/v2"),ze=16,va=1+ze+8,Ra=0,Ca=1,Sa=2,ka=1+64*1024+16,Ea=1024,Ia=6e4,Pa="calimero.tee-attest.transport-key.v1",Ta=[101,204,205,304],Vo=new TextEncoder,Ye=class extends Error{constructor(){super("The node no longer holds the attested transport key; attest again for the current one");this.name="StaleTransportKeyError"}},Ce=class extends Error{constructor(n,r,o,i){super(o);this.status=n;this.code=r;this.retryAfterMs=i;this.name="SealedTransportError"}};async function Wo(t,e){let n=await crypto.subtle.digest("SHA-256",m(Vo.encode(Pa),t,e));return new Uint8Array(n)}async function Jo(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=f(crypto.getRandomValues(new Uint8Array(32))),o=await t.teeAttest({nonce:r,applicationId:n.applicationId,bindTransportKey:!0,...e.includeCollateral?{includeCollateral:!0}:{}});if(!o.transportPublicKey)throw new Error("The node did not report a transport key; it predates sealed transport");let i=p(o.transportPublicKey,"transportPublicKey",32),s=n.applicationHash?p(n.applicationHash,"applicationHash",32):new Uint8Array(32),a=f(await Wo(s,i));if(!await e({quoteB64:o.quoteB64,nonce:r,reportDataSuffix:a,collateral:o.collateral}))throw new Error("The attestation did not verify, so its transport key is not trusted");return i}function Xe(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 s=await i.json();if(!s.data)throw new Error("The attestation response is malformed");return s.data}};return zo({baseUrl:t.baseUrl,transportPublicKey:()=>Jo(r,t.verify,{applicationId:t.applicationId,applicationHash:t.applicationHash}),fetch:e})}function zo(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,s=i?Promise.resolve().then(i):Promise.resolve(t.transportPublicKey);s.catch(()=>{});let a,c=async()=>{try{return await qo(o,r,await Ko(s))}catch(l){if(!(l instanceof Ye)||!i)throw l;return s=Promise.resolve().then(i),qo(o,r,await Ko(s))}},u=async()=>{let l=a??d(void 0),g=await l;if(Date.now()<g.renewAt)return[g,l];let w=d(l);return[await w,w]},d=l=>{if(a===l){let g=c();a=g,g.catch(()=>{a===g&&(a=void 0)})}return a};return async(l,g)=>{let w=new Request(l,g),x=new URL(w.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 A=[];w.headers.forEach((h,y)=>A.push([y,h]));let R={method:w.method,path:x.pathname.slice(n.length)+x.search,headers:A},I=new Uint8Array(await w.arrayBuffer()),P=async h=>{let{requestId:y,header:S,envelope:N}=await Na(h,R,I),_=await o(`${r}${Fo}`,{method:"POST",headers:{"content-type":Qe},body:N,signal:w.signal});if(_.headers.get("content-type")!==Qe)throw await Yo(_);return Oa(_,h.responseKey,S,y)},[j,M]=await u();try{return await P(j)}catch(h){if(!(h instanceof Ce)||h.code!=="unknown_session")throw h;return P(await d(M))}}}async function Ko(t){let e=await t;if(e.length!==32)throw new Error("transportPublicKey must be 32 bytes");return e}async function qo(t,e,n){try{return await Bo(t,e,n)}catch(r){if(!(r instanceof Ce)||r.code!=="busy")throw r;return await new Promise(o=>setTimeout(o,r.retryAfterMs??1e3)),Bo(t,e,n)}}async function Bo(t,e,n){let r=await Lo(n,xa),o=await t(`${e}${jo}`,{method:"POST",headers:{"content-type":Qe},body:m(new Uint8Array([sr]),n,r.message1)});if(o.headers.get("content-type")!==Qe)throw await Yo(o);let i=await _a(o,Ea);return Da(r,i)}async function Da(t,e){if(e[0]!==sr)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!==ze+4)throw new Error("The handshake reply is malformed");let i=r.slice(0,ze),s=new DataView(r.buffer,r.byteOffset).getUint32(ze,!1),[a,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:a,responseKey:c,nextRequestId:1,renewAt:Date.now()+s*1e3-Ia,header(u){let d=new Uint8Array(va);return d[0]=sr,d.set(i,1),new DataView(d.buffer).setBigUint64(1+ze,BigInt(u),!1),d}}}async function Na(t,e,n){let r=t.nextRequestId;t.nextRequestId+=1;let o=t.header(r),i=await crypto.subtle.encrypt({name:"AES-GCM",iv:Qo(r,0),additionalData:o},t.requestKey,Ua(e,n));return{requestId:r,header:o,envelope:m(o,new Uint8Array(i))}}function Qo(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 Ua(t,e){let n=Vo.encode(JSON.stringify(t)),r=new Uint8Array(4);return new DataView(r.buffer).setUint32(0,n.length,!1),m(r,n,e)}async function Oa(t,e,n,r){if(!t.body)throw new Error("The sealed response has no body");let o=Ma(t.body.getReader()),i=0,s=async()=>{let d=await o.next();if(!d)return null;let l;try{l=new Uint8Array(await crypto.subtle.decrypt({name:"AES-GCM",iv:Qo(r,i),additionalData:n},e,d))}catch{throw new Error("A sealed response frame did not open: it was not sealed by the attested node")}return i+=1,{kind:l[0],data:l.slice(1)}},a=await s();if(!a||a.kind!==Ra)throw new Error("The sealed response is malformed");let c=JSON.parse(new TextDecoder().decode(a.data));if(Ta.includes(c.status))return await o.cancel(),new Response(null,{status:c.status,headers:c.headers});let u=new ReadableStream({async pull(d){try{let l=await s();l?l.kind===Ca?d.enqueue(l.data):l.kind===Sa?(d.close(),await o.cancel()):d.error(new Error("The sealed response is malformed")):d.error(new Error("The sealed response was cut short"))}catch(l){d.error(l)}},cancel(){return o.cancel()}});return new Response(u,{status:c.status,headers:c.headers})}function Ma(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>ka)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 _a(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 Yo(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 Ye;let r=Number(t.headers.get("retry-after")),o=Number.isFinite(r)&&r>0?Math.min(r,5)*1e3:void 0;return new Ce(t.status,e,n,o)}var Ga=/^[0-9a-f]{96}$/,$a=["mrtd","rtmr0","rtmr1","rtmr2","rtmr3"];function ar(t){let e=Se(t.allowedMrtd??[],"allowedMrtd"),n=(t.allowedMeasurements??[]).map((a,c)=>{let u=`allowedMeasurements[${c}]`;return $a.map(d=>Se([a?.[d]??""],`${u}.${d}`)[0]).join()}),r=[Se(t.allowedRtmr0??[],"allowedRtmr0"),Se(t.allowedRtmr1??[],"allowedRtmr1"),Se(t.allowedRtmr2??[],"allowedRtmr2"),Se(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(a=>a.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:a,nonce:c,reportDataSuffix:u,collateral:d})=>{let l=La(a),g=d??await t.fetchCollateral?.(l);if(!g)throw new Error("The node sent no collateral for its quote, and no fetchCollateral was given to get it");let w;try{w=t.dcapVerify(l,g,Math.floor(i()/1e3))}catch(I){throw new Error(`The quote did not verify: ${I?.message??String(I)}`)}if(w.status==="Revoked"||!o.includes(w.status))throw new Error(`The platform's TCB status is ${w.status}, which is not accepted`);let x=Ha(w.report),A=[x.mrTd,x.rtMr0,x.rtMr1,x.rtMr2,x.rtMr3].map(I=>f(I));if(n.length>0&&!n.includes(A.join()))throw new Error(`The measurements (MRTD ${A[0]}, RTMR0-3 ${A.slice(1).join(", ")}) are not an image this verifier trusts`);if(e.length>0&&!e.includes(A[0]))throw new Error(`MRTD ${A[0]} is not an image this verifier trusts`);if([x.rtMr0,x.rtMr1,x.rtMr2,x.rtMr3].forEach((I,P)=>{let j=r[P];if(j.length>0&&!j.includes(f(I)))throw new Error(`RTMR${P} ${f(I)} is not one this verifier trusts`)}),f(x.reportData)!==`${c}${u}`.toLowerCase())throw new Error("The quote does not commit to this nonce and binding");return!0},{includeCollateral:!0})}function Se(t,e){return t.map(n=>{let r=n.trim().toLowerCase();if(!Ga.test(r))throw new Error(`${e} holds ${JSON.stringify(n)}, which is not a 48-byte hex measurement`);return r})}function Ha(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 La(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 Ka=["UpToDate","SWHardeningNeeded","ConfigurationNeeded","ConfigurationAndSWHardeningNeeded","OutOfDate","OutOfDateConfigurationNeeded"];function cr(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 s=o?.tag??`releases[${i}]`;if(o?.role!==void 0&&o.role!=="node")throw new Error(`${s} lists the measurements of a ${o.role}, not of a node image`);let a=o?.profiles?.[e];if(!a){let u=Object.keys(o?.profiles??{}).join(", ")||"none";throw new Error(`${s} has no profile ${JSON.stringify(e)} (it has: ${u})`)}let c=(a.allowed_tcb_statuses??["uptodate"]).map(u=>qa(u,s));return n=n===void 0?c:n.filter(u=>c.includes(u)),{mrtd:a.mrtd,rtmr0:a.rtmr0,rtmr1:a.rtmr1,rtmr2:a.rtmr2,rtmr3:a.rtmr3}});if(!n||n.length===0)throw new Error("The releases given accept no TCB status in common");return{allowedMeasurements:r,allowedTcbStatuses:n}}function qa(t,e){let n=Ka.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 Xo=[{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"]}],Zo=[{baseUrl:"https://rekor.sigstore.dev",logId:"c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d",publicKey:"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE2G2Y+2tabdTV5BcGiBIx0a9fAFwrkBbmLSGtks4L3qX6yYY0zufBnhC8Ur/iy55GhWP/9A/bY2LhC30M9+RYtw==",validFor:{start:"2021-01-12T11:53:27Z"}}];var Ba="1.2.840.10045.2.1",ja={"1.2.840.10045.3.1.7":"P-256","1.3.132.0.34":"P-384"},Fa={"P-256":32,"P-384":48},Va={"1.2.840.10045.4.3.2":"SHA-256","1.2.840.10045.4.3.3":"SHA-384"};function ei(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 a=o&127;if(a===0||a>4||i+a>n)throw new Error("it has a length this parser does not read");o=0;for(let c=0;c<a;c+=1)o=o*256+t[i+c];i+=a}let s=i+o;if(s>n)throw new Error("it is truncated");return{tag:r,bytes:t,offset:e,start:i,end:s}}function Ee(t){let e=ei(t,0,t.length);if(e.end!==t.length)throw new Error("it has trailing bytes");return e}function G(t){let e=[];for(let n=t.start;n<t.end;){let r=ei(t.bytes,n,t.end);e.push(r),n=r.end}return e}function U(t,e,n){if(!t||t.tag!==e)throw new Error(`${n} is not where it should be`);return t}function ie(t){return t.bytes.slice(t.start,t.end)}function _t(t){return t.bytes.slice(t.offset,t.end)}function ke(t){let e=ie(U(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 s of e)r=r*128+(s&127),s&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 Wa(t){let e=new TextDecoder().decode(ie(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[s,a,c,u,d]=o.slice(2).map(Number);return Date.UTC(i,s-1,a,c,u,d)}function lr(t){try{let[e,n,r,...o]=G(U(Ee(t),48,"The certificate"));if(o.length>0)throw new Error("it has fields after its signature");let i=G(U(e,48,"The signed part")),s=i[0]?.tag===160?1:0,[a,c,u,d,l,g,...w]=i.slice(s);U(a,2,"The serial number");let x=ke(G(U(n,48,"The signature algorithm"))[0]);if(ke(G(U(c,48,"The signature algorithm"))[0])!==x)throw new Error("it names two different signature algorithms");let R=Va[x];if(!R)throw new Error(`it is signed with ${x}, not ECDSA with SHA-256 or SHA-384`);let[I,P]=G(U(d,48,"The validity")).map(Wa);if(P===void 0)throw new Error("its validity is incomplete");let[j,M]=G(U(g,48,"The public key"));U(M,3,"The public key");let[h,y]=G(U(j,48,"The key algorithm"));if(ke(h)!==Ba)throw new Error("its key is not an elliptic-curve key");let S=ja[ke(y)];if(!S)throw new Error("its key is on a curve other than P-256 or P-384");let N=new Map,_=w.find(Q=>Q.tag===163);if(_){let[Q]=G(_);for(let we of G(U(Q,48,"The extensions"))){let K=G(U(we,48,"An extension"));if(K.length===3)U(K[1],1,"An extension's critical flag");else if(K.length!==2)throw new Error("it has a malformed extension");let _n=ke(K[0]);if(N.has(_n))throw new Error(`it has extension ${_n} twice`);N.set(_n,ie(U(K[K.length-1],4,"An extension value")))}}let Mn=ie(U(r,3,"The signature"));if(Mn[0]!==0)throw new Error("its signature is not a whole number of bytes");return{der:t,tbs:_t(e),signatureHash:R,signature:Mn.slice(1),issuer:_t(U(u,48,"The issuer")),subject:_t(U(l,48,"The subject")),notBefore:I,notAfter:P,spki:_t(g),curve:S,extensions:N}}catch(e){throw new Error(`The certificate is malformed: ${e.message}`)}}function ti(t){return G(U(Ee(t),48,"The list")).map(ke)}function Ja(t,e){let n=Fa[e],r=G(U(Ee(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,s)=>{let a=ie(U(i,2,"The signature"));if(a.length===0||a[0]&128)throw new Error("The signature is not an ECDSA signature");for(;a.length>1&&a[0]===0;)a=a.subarray(1);if(a.length>n)throw new Error("The signature is not an ECDSA signature");o.set(a,s*n+n-a.length)}),o}async function Gt(t,e,n,r,o){let i;try{i=Ja(r,e)}catch{return!1}let s=await crypto.subtle.importKey("spki",t,{name:"ECDSA",namedCurve:e},!1,["verify"]);return crypto.subtle.verify({name:"ECDSA",hash:n},s,i,o)}function W(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 ur(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 W(n[0][1],e)}var za="2.5.29.17",Qa="2.5.29.37",Ya="1.3.6.1.5.5.7.3.3",Xa="1.3.6.1.4.1.57264.1.8",Za="1.3.6.1.4.1.57264.1.1",ec=134,tc=12,nc=48,rc=new TextEncoder,Ie=t=>new TextDecoder().decode(t);async function ni(t,e,n,r){let{base64Signature:o,cert:i,rekorBundle:s}=ac(e),a=s.Payload;if(r!==void 0&&r.trim()!==o.trim())throw new Error("The detached signature is not the one in the bundle");let c=W(o,"The bundle signature"),u=ur(Ie(W(i,"The bundle certificate")),"The bundle certificate"),d=lr(u),l=Zo.find(P=>P.logId===a.logID.toLowerCase());if(!l)throw new Error(`The bundle names Rekor log ${a.logID}, which the Sigstore trust root does not know`);let g=rc.encode(`{"body":${JSON.stringify(a.body)},"integratedTime":${a.integratedTime},"logID":${JSON.stringify(a.logID)},"logIndex":${a.logIndex}}`);if(!await Gt(W(l.publicKey,"The Rekor key"),"P-256","SHA-256",W(s.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=a.integratedTime*1e3;if(!ii(x,l.validFor))throw new Error(`Rekor log ${l.baseUrl} was not in use at ${Ze(x)}, when the entry says it was logged`);let A=cc(a.body),R=f(new Uint8Array(await crypto.subtle.digest("SHA-256",t)));if(A.hash!==R)throw new Error("The file's SHA-256 is not the one Rekor logged: the file is not the one signed");if(!dr(W(A.signature,"The logged signature"),c))throw new Error("The bundle's signature is not the one Rekor logged");let I=ur(Ie(W(A.publicKey,"The logged certificate")),"The logged certificate");if(!dr(I,u))throw new Error("The bundle's certificate is not the one Rekor logged");if(d.curve!=="P-256"||!await Gt(d.spki,"P-256","SHA-256",c,t))throw new Error("The signature over the file does not verify with the bundle's certificate");return await oc(d,x),sc(d,n),{integratedTime:a.integratedTime}}async function oc(t,e){if(!oi(t,e))throw new Error(`The signing certificate was valid ${Ze(t.notBefore)} to ${Ze(t.notAfter)}, not at ${Ze(e)} when Rekor logged it`);let n=[];for(let r of Xo){let o=r.certChain.map(s=>lr(W(s,"A Fulcio certificate")));if(!await ri(t,o[0]))continue;let i=await ic(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 ${Ze(e)}: ${n.join("; ")}`:"The signing certificate was not issued by a Fulcio CA in the Sigstore trust root")}async function ic(t,e,n){if(!ii(n,e))return"the trust root says it was not issuing certificates then";for(let[r,o]of t.entries()){if(!oi(o,n))return`its certificate ${r} was not valid then`;let i=t[r+1]??o;if(!await ri(o,i))return`its certificate ${r} is not signed by the next`}}async function ri(t,e){return dr(t.issuer,e.subject)?Gt(e.spki,e.curve,t.signatureHash,t.signature,t.tbs):!1}function sc(t,e){let n=t.extensions.get(za);if(!n)throw new Error("The signing certificate names no identity");let r=G(U(Ee(n),nc,"The subject alternative name")),o=r.filter(u=>u.tag===ec).map(u=>Ie(ie(u)));if(o.length!==1||r.length!==1||o[0]!==e.identity)throw new Error(`The release was signed by ${JSON.stringify(o.length===1?o[0]:o)}, not by ${e.identity}`);let i=t.extensions.get(Xa),s=t.extensions.get(Za),a=i?Ie(ie(U(Ee(i),tc,"The OIDC issuer"))):s?Ie(s):void 0;if(a!==e.issuer)throw new Error(`The signing certificate's OIDC issuer is ${a===void 0?"missing":JSON.stringify(a)}, not ${e.issuer}`);let c=t.extensions.get(Qa);if(!c||!ti(c).includes(Ya))throw new Error("The signing certificate is not for code signing")}function ac(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 cc(t){let e;try{e=JSON.parse(Ie(W(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 oi(t,e){return t.notBefore<=e&&e<=t.notAfter}function ii(t,e){return Date.parse(e.start)<=t&&(e.end===void 0||t<=Date.parse(e.end))}function Ze(t){return new Date(t).toISOString()}function dr(t,e){return t.length===e.length&&t.every((n,r)=>n===e[r])}var pr=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"}),lc=["mrtd","rtmr0","rtmr1","rtmr2","rtmr3"],$t="https://cloud.calimero.network";async function ai(t,e,n={}){let r=typeof t=="string"?new TextEncoder().encode(t):t;await ni(r,e,{identity:n.identity??pr.identity,issuer:n.issuer??pr.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??{}),s=a=>lc.every(c=>/^[0-9a-f]{96}$/i.test(String(a?.[c])));if(typeof o.tag!="string"||i.length===0||!i.every(s))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 Ht(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 ci(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 Lt(t,e={}){let n=await ui(t,e.fetch??fetch);if(n===void 0)throw new Error(`${li(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 li(t){return`${t.replace(/\/+$/,"")}/admin-api/tee/info`}async function ui(t,e){let n=li(t),r=await e(n,{headers:{accept:"application/json"}});if(r.status===403&&await r.json().then(s=>s?.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 ci(o)}function Kt(t,e){return`${t.replace(/\/+$/,"")}/api/tee/node-releases/${et(e,"version")}`}async function di(t){let e=et(t.minReleaseVersion,"minReleaseVersion"),n=et(t.release?.version,"The release version"),r=await ai(t.release.publishedMrtds,t.release.bundle,{expectedVersion:n,identity:t.identity,issuer:t.issuer});if(dc(n,e)<0)throw new Error(`Release ${n} is older than the minimum trusted, ${e}`);return cr([r],{profile:t.profile})}function qt(t){return et(t.minReleaseVersion,"minReleaseVersion"),Object.assign(async n=>{let r=await di({release:await t.release(),profile:t.profile,minReleaseVersion:t.minReleaseVersion,identity:t.identity,issuer:t.issuer});return ar({dcapVerify:t.dcapVerify,fetchCollateral:t.fetchCollateral,now:t.now,...r})(n)},{includeCollateral:!0})}function uc(t){let{baseUrl:e,releaseSource:n,releaseVersion:r,applicationId:o,applicationHash:i,fetch:s,...a}=t;r!==void 0&&et(r,"releaseVersion");let c=s??((d,l)=>fetch(d,l));return Xe({baseUrl:e,verify:qt({...a,release:async()=>{let d=r===void 0?await Lt(e,{fetch:c}):await ui(e,c)??r;return typeof n=="function"?n({baseUrl:e,version:d,fetch:c}):Ht(Kt(n??$t,d),{fetch:c})}}),applicationId:o,applicationHash:i,fetch:c})}var pi=/^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/;function et(t,e){let n=typeof t=="string"?pi.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 dc(t,e){let[n,r]=si(t),[o,i]=si(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 s=r.split("."),a=i.split(".");for(let c=0;c<Math.max(s.length,a.length);c+=1){let[u,d]=[s[c],a[c]];if(u===void 0||d===void 0)return u===void 0?-1:1;let[l,g]=[/^\d+$/.test(u),/^\d+$/.test(d)],w=l&&g?Math.sign(Number(u)-Number(d)):l!==g?l?-1:1:u<d?-1:u>d?1:0;if(w!==0)return w}return 0}function si(t){let e=pi.exec(t);return[[Number(e[1]),Number(e[2]),Number(e[3])],e[4]]}var pc=new TextEncoder().encode("calimero.warrant.v2"),gc=new TextEncoder().encode("calimero.warrant.intent.v1"),gi=64,mc="00".repeat(32);async function gr(t,e){let n=new TextEncoder().encode(JSON.stringify(e));return k(gc,[new TextEncoder().encode(t),n])}async function Bt(t){let e=p(t.context,"context",32),n=p(t.authorAccount,"authorAccount",32),r=p(t.executor,"executor",32),o=p(t.appVersion??mc,"appVersion",32),i=se(t.accountHeads,"accountHeads"),s=se(t.governanceFloor,"governanceFloor"),a=await E(t.deviceSecret,t.signer,"deviceSecret"),c=p(a.publicKey,"signer.publicKey",32),u=new TextEncoder().encode(t.method),d=await gr(t.method,t.argsJson),l=C(t.nonce),g=C(t.notAfter),w=await k(pc,[e,n,c,r,o,u,d,C(i.length),...i,C(s.length),...s,l,g]),x=tt(await a.sign(w));return f(m(e,n,c,r,o,v(u.length),u,d,v(i.length),...i,v(s.length),...s,l,g,x))}function tt(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 se(t,e){let n=t??[];if(n.length>gi)throw new Error(`${e} cites ${n.length} heads, over the ${gi} a node accepts`);return n.map((r,o)=>p(r,`${e}[${o}]`,32))}var hc=new TextEncoder().encode("calimero.context-creation-warrant.v1"),fc=new TextEncoder().encode("calimero.context-creation.init.v1"),jt=256;async function mr(t){let e=new TextEncoder().encode(JSON.stringify(t));return k(fc,[e])}async function yc(t){return k(hc,[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,C(t.accountHeads.length),...t.accountHeads,C(t.governanceFloor.length),...t.governanceFloor,C(t.nonce),C(t.notAfter)])}async function Ft(t){let e=p(t.group,"group",32),n=t.seed===void 0?crypto.getRandomValues(new Uint8Array(32)):p(t.seed,"seed",32),r=p(t.authorAccount,"authorAccount",32),o=p(t.executor,"executor",32),i=p(t.applicationId,"applicationId",32),s=mi(t.serviceName,"serviceName"),a=mi(t.name,"name"),c=se(t.accountHeads,"accountHeads"),u=se(t.governanceFloor,"governanceFloor"),d=await E(t.deviceSecret,t.signer,"deviceSecret"),l=p(d.publicKey,"signer.publicKey",32),g=await mr(t.initArgs),w=await yc({group:e,seed:n,authorAccount:r,deviceKey:l,executor:o,applicationId:i,serviceName:s,name:a,initHash:g,accountHeads:c,governanceFloor:u,nonce:t.nonce,notAfter:t.notAfter}),x=tt(await d.sign(w));return{warrant:f(m(e,n,r,l,o,i,hi(s),hi(a),g,v(c.length),...c,v(u.length),...u,C(t.nonce),C(t.notAfter),x)),seed:f(n)}}function fi(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 w=n.subarray(o,o+l);return o+=l,w},s=l=>r.getUint32(i(4,l).byteOffset,!0),a=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 w=s(l);if(w>jt)throw new Error(`${l} is ${w} bytes, over the ${jt} a node accepts`);return new TextDecoder("utf-8",{fatal:!0}).decode(i(w,l))},u=l=>{let g=s(l);if(g>64)throw new Error(`${l} cites ${g} heads, over the 64 a node accepts`);return Array.from({length:g},()=>f(i(32,l)))},d={group:f(i(32,"group")),seed:f(i(32,"seed")),authorAccount:f(i(32,"authorAccount")),deviceKey:f(i(32,"deviceKey")),executor:f(i(32,"executor")),applicationId:f(i(32,"applicationId")),serviceName:c("serviceName"),name:c("name"),initHash:f(i(32,"initHash")),accountHeads:u("accountHeads"),governanceFloor:u("governanceFloor"),nonce:a("nonce"),notAfter:a("notAfter"),signature:f(i(64,"signature"))};if(o!==n.length)throw new Error(`creation warrant is ${n.length} bytes but its fields account for ${o}`);return d}function mi(t,e){if(t===void 0)return null;let n=new TextEncoder().encode(t);if(n.length>jt)throw new Error(`${e} is ${n.length} UTF-8 bytes, over the ${jt} a node accepts`);return n}function hi(t){return t===null?new Uint8Array([0]):m(new Uint8Array([1]),v(t.length),t)}var bc=new TextEncoder().encode("calimero.governance-warrant.v1"),wc=new TextEncoder().encode("calimero.governance-warrant.op.v1"),Ac={group:0,root:1};async function hr(t){return k(wc,[new Uint8Array([fr(t.kind)]),t.bytes])}async function xc(t){return k(bc,[t.scope,new Uint8Array([fr(t.kind)]),t.authorAccount,t.deviceKey,t.executor,t.opHash,C(t.accountHeads.length),...t.accountHeads,C(t.governanceFloor.length),...t.governanceFloor,C(t.nonce),C(t.notAfter)])}async function nt(t){let e=p(t.scope,"scope",32),n=p(t.authorAccount,"authorAccount",32),r=p(t.executor,"executor",32),o=se(t.accountHeads,"accountHeads"),i=se(t.governanceFloor,"governanceFloor"),s=fr(t.op.kind),a=await E(t.deviceSecret,t.signer,"deviceSecret"),c=p(a.publicKey,"signer.publicKey",32),u=await hr(t.op),d=await xc({scope:e,kind:t.op.kind,authorAccount:n,deviceKey:c,executor:r,opHash:u,accountHeads:o,governanceFloor:i,nonce:t.nonce,notAfter:t.notAfter}),l=tt(await a.sign(d));return f(m(e,new Uint8Array([s]),n,c,r,u,v(o.length),...o,v(i.length),...i,C(t.nonce),C(t.notAfter),l))}function yi(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 w=n.subarray(o,o+l);return o+=l,w},s=l=>r.getUint32(i(4,l).byteOffset,!0),a=l=>r.getBigUint64(i(8,l).byteOffset,!0),c=l=>{let g=s(l);if(g>64)throw new Error(`${l} cites ${g} heads, over the 64 a node accepts`);return Array.from({length:g},()=>f(i(32,l)))},u=()=>{let l=i(1,"kind")[0];if(l===0)return"group";if(l===1)return"root";throw new Error(`governance warrant has kind ${l}, expected 0 (group) or 1 (root)`)},d={scope:f(i(32,"scope")),kind:u(),authorAccount:f(i(32,"authorAccount")),deviceKey:f(i(32,"deviceKey")),executor:f(i(32,"executor")),opHash:f(i(32,"opHash")),accountHeads:c("accountHeads"),governanceFloor:c("governanceFloor"),nonce:a("nonce"),notAfter:a("notAfter"),signature:f(i(64,"signature"))};if(o!==n.length)throw new Error(`governance warrant is ${n.length} bytes but its fields account for ${o}`);return d}function fr(t){let e=Ac[t];if(e===void 0)throw new Error(`op kind must be 'group' or 'root', got ${String(t)}`);return e}var vc={Admin:0,Member:1,ReadOnly:2},$={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},rt={GroupCreated:0,GroupReparented:1,GroupDeleted:2,MemberJoinedOpen:7,NamespaceCreatedV2:9},Rc=new TextEncoder().encode("calimero.namespace.id.v1"),br=new Uint8Array(32),Vt=v(0);function wi(t){let e=vc[t];if(e===void 0)throw new Error(`role must be Admin, Member or ReadOnly, got ${String(t)}`);return new Uint8Array([e])}function D(t){return new Uint8Array([t])}function Pe(t,e){return{kind:"group",bytes:m(D($.MemberAdded),p(t,"member",32),wi(e))}}function Wt(t){return{kind:"group",bytes:m(D($.MemberRemoved),p(t,"member",32),br,Vt)}}function ot(t){return{kind:"group",bytes:m(D($.MemberLeft),p(t,"member",32),br,Vt)}}function Jt(t,e){return{kind:"group",bytes:m(D($.MemberRoleSet),p(t,"member",32),wi(e))}}var Cc=new TextEncoder().encode("calimero.subgroup.id.v1");async function wr(t,e,n,r){return f(await k(Cc,[p(t,"admin",32),p(e,"parentId",32),new Uint8Array([n?1:0]),p(r,"salt",32)]))}function bi(t,e){if(t.length===0)throw new Error(`${e} must not be empty`);let n=new TextEncoder().encode(t);return m(v(n.length),n)}function zt(t){return{kind:"group",bytes:m(D($.TargetApplicationSet),br,p(t.applicationId,"applicationId",32),bi(t.package,"package"),bi(t.version,"version"))}}function Te(t){if(!Number.isInteger(t)||t<0||t>4294967295)throw new Error(`capabilities must be a u32 bit mask, got ${String(t)}`);if(ce(t,O.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(D($.DefaultCapabilitiesSet),v(t))}}function Ar(t){return{kind:"root",bytes:m(D(rt.GroupCreated),p(t.groupId,"groupId",32),p(t.parentId,"parentId",32),D(t.restricted?1:0),p(t.admin,"admin",32),p(t.salt,"salt",32))}}async function De(t){let e=t.salt??f(crypto.getRandomValues(new Uint8Array(32))),n=await wr(t.admin,t.parentId,t.restricted,e);return{groupId:n,salt:e,op:Ar({...t,groupId:n,salt:e})}}function Qt(t,e){return{kind:"root",bytes:m(D(rt.GroupReparented),p(t,"childGroupId",32),p(e,"newParentId",32))}}function Yt(t){return{kind:"root",bytes:m(D(rt.GroupDeleted),p(t,"rootGroupId",32),Vt,Vt)}}async function Xt(t,e){return f(await k(Rc,[p(t,"founder",32),p(e,"salt",32)]))}function Zt(t){let e=F(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(D(rt.NamespaceCreatedV2),p(t.founder,"founder",32),e,p(t.salt,"salt",32))}}function yr(t){let e=new TextEncoder().encode(t);return m(v(e.length),e)}function xr(t){return t===void 0?D(0):m(D(1),yr(t))}function vr(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(v(n.length),...n.flatMap(([,r,o])=>[yr(o),yr(r)]))}function Sc(t,e){if(!Number.isInteger(t)||t<0||t>4294967295)throw new Error(`${e} must be a u32 bit mask, got ${String(t)}`);if(ce(t,O.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 en(t,e){return{kind:"group",bytes:m(D($.MemberCapabilitySet),p(t,"member",32),v(Sc(e,"capabilities")))}}function tn(t){return{kind:"group",bytes:m(D($.ContextDetached),p(t,"contextId",32))}}function nn(t){if(t!=="open"&&t!=="restricted")throw new Error(`mode must be open or restricted, got ${String(t)}`);return{kind:"group",bytes:m(D($.SubgroupVisibilitySet),D(t==="open"?0:1))}}function Ne(t={}){return{kind:"group",bytes:m(D($.GroupMetadataSet),xr(t.name),vr(t.data))}}function rn(t,e={}){return{kind:"group",bytes:m(D($.MemberMetadataSet),p(t,"member",32),xr(e.name),vr(e.data))}}function on(t,e={}){return{kind:"group",bytes:m(D($.ContextMetadataSet),p(t,"contextId",32),xr(e.name),vr(e.data))}}function Ai(t){if(!Number.isInteger(t)||t<1||t>255)throw new Error(`capability must be a non-zero u8, got ${String(t)}`);return D(t)}function xi(t,e,n){return{kind:"group",bytes:m(D($.ContextCapabilityGranted),p(t,"contextId",32),p(e,"member",32),Ai(n))}}function vi(t,e,n){return{kind:"group",bytes:m(D($.ContextCapabilityRevoked),p(t,"contextId",32),p(e,"member",32),Ai(n))}}function sn(t){return{kind:"root",bytes:m(D(rt.MemberJoinedOpen),p(t.member,"member",32),p(t.groupId,"groupId",32),F(t.credential,"credential"))}}var an=300,ue=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"}},kc=t=>new Promise(e=>setTimeout(e,t));function Ec(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 J=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 E(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(),s=await this.config.nonces.next(),a=this.config.ttlSeconds??an,c=await Bt({context:e,authorAccount:this.config.authorAccount,executor:o,method:n,argsJson:r,nonce:s,notAfter:BigInt(Math.floor(Date.now()/1e3))+BigInt(a),signer:i}),u=await this.json("POST",`/admin-api/contexts/${encodeURIComponent(e)}/intents`,{method:n,argsJson:r,warrant:c,authorProof:this.config.authorProof});return{rootHash:u.data.rootHash,returns:u.data.returns??null}}async 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 ue(`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 ue(`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(),s=await this.config.nonces.next(),a=this.config.ttlSeconds??an,{warrant:c}=await Ft({group:e.groupId,seed:e.seed,authorAccount:this.config.authorAccount,executor:r,applicationId:e.applicationId,serviceName:e.serviceName,name:e.name,initArgs:o,nonce:s,notAfter:BigInt(Math.floor(Date.now()/1e3))+BigInt(a),signer:i}),u=await this.json("POST",`/admin-api/groups/${encodeURIComponent(e.groupId)}/context-intents`,{warrant:c,authorProof:this.config.authorProof,initArgs:o});return{contextId:u.data.contextId,groupId:u.data.groupId,memberPublicKey:u.data.memberPublicKey}}async describeGovernance(e){return(await this.json("GET",`/admin-api/groups/${encodeURIComponent(e)}/governance-intents`)).data}async govern(e){let n=await this.describeGovernance(e.groupId);if(!n.canActOnBehalf)throw new ue(`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(),s=this.config.ttlSeconds??an,a=await nt({scope:e.groupId,op:e.op,authorAccount:this.config.authorAccount,executor:r,nonce:i,notAfter:BigInt(Math.floor(Date.now()/1e3))+BigInt(s),signer:o});return{groupId:(await this.postGovernance(e.groupId,e.op,a)).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?f(p(e.salt,"salt",32)):f(crypto.getRandomValues(new Uint8Array(32))),o=await Xt(this.config.authorAccount,r),i=Zt({founder:this.config.authorAccount,credential:this.config.authorProof,salt:r}),s=e.defaultCapabilities===void 0?void 0:Te(e.defaultCapabilities),a=e.application?zt(e.application):void 0,c=await this.authorSigner(),u=await this.config.nonces.next(),d=this.config.ttlSeconds??an,l=await nt({scope:o,op:i,authorAccount:this.config.authorAccount,executor:n,nonce:u,notAfter:BigInt(Math.floor(Date.now()/1e3))+BigInt(d),signer:c}),g=await this.postGovernance(o,i,l),w={namespaceId:g.groupId,salt:r,teeEnabled:g.teeEnabled??!1,...g.teeError?{teeError:g.teeError}:{}},x=w,A=R=>R instanceof Error?R.message:String(R);if(a)try{await this.govern({groupId:w.namespaceId,op:a}),x={...x,applicationSet:!0}}catch(R){x={...x,applicationSet:!1,applicationError:A(R)}}if(s)try{await this.govern({groupId:w.namespaceId,op:s}),x={...x,defaultCapabilitiesSet:!0}}catch(R){x={...x,defaultCapabilitiesSet:!1,defaultCapabilitiesError:A(R)}}return x}async postGovernance(e,n,r){return(await this.json("POST",`/admin-api/groups/${encodeURIComponent(e)}/governance-intents`,{warrant:r,authorProof:this.config.authorProof,op:f(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(s){if(!(s instanceof T&&s.status===429)||i>=this.rateLimitRetries)throw s;let c=Ec(s.headers);await kc(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,s=setTimeout(()=>i.abort(),this.timeoutMs),a;try{a=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 T(0,c instanceof Error?c.name:"NetworkError",`${this.baseUrl}${n}`,new Headers,c instanceof Error?c.message:String(c))}finally{clearTimeout(s)}if(!a.ok){let c=await a.text().catch(()=>"");if(a.status===400||a.status===403){let u=Ic(c);throw new ue(u,/nonce/i.test(u),a.status)}throw new T(a.status,a.statusText,`${this.baseUrl}${n}`,a.headers,c)}if(a.status!==204)return await a.json()}};function Ic(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 de=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 Pc=new TextEncoder().encode("calimero.auth.login.v1"),Ri={webOrigin:0,codeSigningId:1,cli:2};function Ci(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 Tc(t){return m(Uint8Array.from([Ri[t.kind]]),Ci(t))}function Dc(t){let e=Uint8Array.from([Ri[t.kind]]);if(t.kind==="cli")return e;let n=Ci(t);return m(e,v(n.length),n)}async function cn(t){let e=p(t.node,"node",32),n=p(t.challenge,"challenge",32),r=p(t.sessionKey,"sessionKey",32),o=await E(t.deviceSecret,t.signer,"deviceSecret"),i=p(o.publicKey,"signer.publicKey",32),s=C(t.issuedAt),a=C(t.expiresAt),c=await k(Pc,[e,Tc(t.audience),n,r,i,s,a]),u=await o.sign(c);return f(m(e,Dc(t.audience),n,r,i,s,a,u))}var Nc=300;async function Rr(){let t=f(crypto.getRandomValues(new Uint8Array(32)));return{publicKey:f(await ne(t)),secret:t}}async function Ue(t){let e=t.nodeUrl.replace(/\/+$/,""),n=t.timeoutMs??1e4,r=async(g,w)=>{let x=new AbortController,A=setTimeout(()=>x.abort(),n),R;try{let P={...w,signal:x.signal};R=t.fetch?await t.fetch(`${e}${g}`,P):await globalThis.fetch(`${e}${g}`,P)}catch(P){throw new T(0,P instanceof Error?P.name:"NetworkError",`${e}${g}`,new Headers,P instanceof Error?P.message:String(P))}finally{clearTimeout(A)}let I=await R.text().catch(()=>"");if(!R.ok)throw new T(R.status,R.statusText,`${e}${g}`,R.headers,I);return I?JSON.parse(I):{}},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 s=await Rr(),a=Math.floor(Date.now()/1e3),c=await cn({node:t.node,audience:t.audience,challenge:i,sessionKey:s.publicKey,issuedAt:a,expiresAt:a+(t.ttlSeconds??Nc),signer:await E(t.deviceSecret,t.signer,"deviceSecret")}),u=await r("/auth/token",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({auth_method:"account_proof",public_key:s.publicKey,client_name:t.clientName??e,timestamp:a,provider_data:{challenge:i,login_statement:c,account_proof:t.accountProof}})}),d=u.access_token??u.data?.access_token,l=u.refresh_token??u.data?.refresh_token;if(!d)throw new Error("the node minted no session");return{accessToken:d,refreshToken:l??"",sessionKey:s.publicKey,sessionSecret:s.secret}}var Uc=3e4;function Me(){let t=globalThis.location?.origin;return t?{kind:"webOrigin",origin:t}:{kind:"cli"}}function Oc(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 Oe=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-Uc>e?this.session.accessToken:(this.pending||(this.pending=this.loginNow().finally(()=>{this.pending=null})),(await this.pending).accessToken)}async loginNow(){let e=await Ue({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=Oc(e.accessToken),e}get events(){return this.sseClient||(this.sseClient=new q({baseUrl:this.config.nodeUrl,getAuthToken:()=>this.accessToken()})),this.sseClient}get ws(){return this.wsClient||(this.wsClient=new re({baseUrl:this.config.nodeUrl,getAuthToken:()=>this.accessToken()})),this.wsClient}close(){this.sseClient?.close(),this.wsClient?.close()}};var X=t=>new TextEncoder().encode(t),Mc=X("calimero.auth.request.v1"),_c=X("calimero.auth.request.body.v1"),Cr="X-Calimero-Proof",Gc=300;async function Sr(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"?X(t.body):t.body,i=await k(_c,[o]),s=Math.floor(t.now??Date.now()/1e3),a=s+(t.validForSeconds??Gc),c=await k(Mc,[X(e),X(n),i,C(s),C(a)]),u=await $c(c,t);if(u.length!==64)throw new Error(`the signer returned ${u.length} bytes, not a 64-byte signature`);let d=m(v(X(e).length),X(e),v(X(n).length),X(n),i,C(s),C(a),u),l=Hc(r,"credential");return f(m(l,new Uint8Array([0]),d))}async function $c(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 te(e.deviceSecret);return new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},n,t))}function Hc(t,e){let n=t.trim();if(!/^[0-9a-fA-F]*$/.test(n)||n.length%2!==0)throw new Error(`${e} is not an even-length hex string`);return p(n,e,n.length/2)}function kr(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 Sr({method:e,path:n,body:r,credential:t.credential,deviceSecret:t.deviceSecret,signer:t.signer,validForSeconds:t.validForSeconds});return{[Cr]:o}}}function Lc(t){return new URL(t).pathname}var Si=new TextEncoder().encode("calimero/presence/1");async function ki(t){let e=t===null?new Uint8Array([0]):m(new Uint8Array([1]),v(t.length),t);return new Uint8Array(await crypto.subtle.digest("SHA-256",e))}async function Er(t){return m(Si,p(t.contextId,"contextId",32),p(t.author,"author",32),C(t.seq),C(t.sentAtMs),await ki(t.state))}var Kc=2500,it=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??Kc,this.now=e.now??Date.now}async set(e,n,r=oe()){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=oe()){return Et(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(),s=await Er({contextId:e,author:r.publicKey,seq:BigInt(o),sentAtMs:BigInt(i),state:n}),a=f(await r.sign(s));try{await this.relay.presenceIntent(e,{state:n===null?null:f(n),seq:o,sentAtMs:i,signature:a,authorProof:this.relay.authorProof})}catch(c){let u=c.status;if(u===void 0||u===0||u===429||u>=500)return;throw this.refused.add(e),this.stop(e),c}}};function Ei(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 Ii(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 qc(t,e){let n=e?.nodeKey;return n?new Oe({nodeUrl:e?.nodeUrl??t.relayUrl,nodeKey:n,accountProof:e?.accountProof??t.authorProof,audience:e?.audience??Me(),signer:e?.signer?async()=>e.signer:()=>t.authorSigner(),clientName:e?.clientName,ttlSeconds:e?.ttlSeconds,fetch:e?.fetch,timeoutMs:e?.timeoutMs}):null}var pe=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 J?e.relay:new J(e.relay);if(this.relayObserver=qc(o,e.observe),this.rpcTransport=new de(o,this.relayObserver),this.relayUrl=o.relayUrl,e.proof&&(this.proofAuthorizer=kr(e.proof)),e.session){let i=e.session;this.relayAdmin=ro({baseUrl:o.relayUrl,getAuthToken:typeof i=="string"?async()=>i:i})}else if(this.proofAuthorizer){let i=this.proofAuthorizer;this.relayAdmin=xt(je({fetch:(s,a)=>globalThis.fetch(s,a),baseUrl:o.relayUrl,authorizeRequest:i}),{baseUrl:o.relayUrl})}return}this.transport="node";let{transport:n,...r}=e;this.nodeClient=new _e(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 Ei("node connection","it holds a signing key and a relay URL, not a node");return this.nodeClient}get relay(){if(!(this.rpcTransport instanceof de))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 q({baseUrl:this.relayUrl,authorize:this.proofAuthorizer})),this.proofEvents;throw Ii("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."):Ii("WebSocket events")}get ephemeral(){return this.nodeClient?this.nodeClient.ephemeral:(this.relayPresence??(this.relayPresence=new it({relay:this.relay,events:()=>this.events})),this.relayPresence)}get cloud(){if(!this.nodeClient)throw Ei("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 ln(t){return new pe(t)}var Pr="calimero.delegated.connection",Tr="calimero.delegated.credential";function Dr(){if(typeof sessionStorage>"u")return null;try{let t=sessionStorage.getItem(Pr);return t?JSON.parse(t):null}catch{return null}}function Ti(t){try{sessionStorage.setItem(Pr,JSON.stringify(t))}catch{}}function Di(){try{sessionStorage.removeItem(Pr)}catch{}}function Ni(){let t=Dr();if(t){let{account:e,credential:n,deviceSecret:r}=t;return{account:e,credential:n,deviceSecret:r}}if(typeof sessionStorage>"u")return null;try{let e=sessionStorage.getItem(Tr);if(!e)return null;let n=JSON.parse(e);return!n.account||!n.credential||!n.deviceSecret?null:n}catch{return null}}function Ui(t){try{sessionStorage.setItem(Tr,JSON.stringify(t))}catch{}}function Oi(){try{sessionStorage.removeItem(Tr)}catch{}}function Nr(t){let e=dn(t);return{next:async()=>{let n=0n;try{n=Mi(t)}catch{n=0n}try{localStorage.setItem(e,String(n+1n))}catch{}return n}}}function dn(t){return`calimero.nonce.${t}`}function Mi(t){let e=localStorage.getItem(dn(t));if(e!==null)return BigInt(e);let n=`${dn(t)}.`,r=0n;for(let o=0;o<localStorage.length;o++){let i=localStorage.key(o);if(!i?.startsWith(n))continue;let s=BigInt(localStorage.getItem(i)??"0");s>r&&(r=s)}return r}function gn(t,e,n){try{Mi(t)<=n&&localStorage.setItem(dn(t),String(n+1n))}catch{}}var _i="calimero.delegated.relay-node-key.";function ge(t){return t.replace(/\/+$/,"")}function Ur(t,e){localStorage.setItem(_i+ge(t),e.trim().toLowerCase())}function mn(t){try{let e=localStorage.getItem(_i+ge(t));return e&&/^[0-9a-f]{64}$/.test(e)?e:null}catch{return null}}function Gi(t){try{let{hostname:e}=new URL(t);return e==="localhost"||e==="127.0.0.1"||e==="[::1]"}catch{return!1}}var Bc="locked-read-only",jc="2.3.99",Ir;function Fc(t){let e=t,n=typeof e.verify=="function"?e.verify:e.default?.verify;if(typeof n!="function")throw new TypeError("@phala/dcap-qvl loaded without a verify function");return n}var Ge=class extends Error{constructor(n,r){super(`${n}: ${r instanceof Error?r.message:String(r)}`);this.step=n;this.cause=r;this.name="RelayKeyTransportError"}};async function Pi(t,e){try{return await e()}catch(n){throw n instanceof Ge?n:new Ge(t,n)}}function Vc(t){return async(e,n)=>{let r;try{r=await globalThis.fetch(e,n)}catch(o){throw t.failure=o,new Ge(`reaching ${String(e)}`,o)}return r.ok||(t.failure??(t.failure=new Error(`${String(e)} answered HTTP ${r.status}`))),r}}function Wc(t,e){return Object.assign(async r=>{let o=await Pi("loading the quote verifier",()=>(Ir??(Ir=import("@phala/dcap-qvl").then(i=>Fc(i),i=>{throw Ir=void 0,i})),Ir));return qt({dcapVerify:o,release:()=>Pi("fetching the release the relay runs",async()=>Ht(Kt($t,await Lt(t,{fetch:e})))),profile:Bc,minReleaseVersion:jc})(r)},{includeCollateral:!0})}async function hn(t){let e=mn(t);if(e)return{kind:"learned",nodeKey:e};let n={failure:null},r=Vc(n);try{let o=Gi(t),{nodeKey:i}=await Mt({relayUrl:t,allowMock:o,fetch:r,...o?{}:{verify:Wc(t,r)}});return Ur(t,i),{kind:"learned",nodeKey:i}}catch(o){return o instanceof Ge||n.failure?{kind:"unavailable",error:o}:{kind:"refused",error:o}}}async function fn(t){let e=await hn(t);return e.kind==="learned"?e.nodeKey:(console.warn("[mero-js] could not learn the relay node key from its attestation",e.error),null)}var pn=[1e3,2e3,5e3,1e4,3e4];function Jc(t,e){return new Promise(n=>{if(e?.aborted)return n();let r=setTimeout(o,t);function o(){clearTimeout(r),e?.removeEventListener("abort",o),n()}e?.addEventListener("abort",o)})}async function $i(t,e={}){let{signal:n}=e;for(let r=0;!n?.aborted;r+=1){let o=await hn(t);if(o.kind==="learned")return o.nodeKey;if(o.kind==="refused")return console.warn("[mero-js] refusing the relay's attestation; its node key stays unknown",o.error),null;let i=pn[Math.min(r,pn.length-1)];console.warn(`[mero-js] could not reach what proves the relay's node key; retrying in ${i/1e3} s`,o.error),await Jc(i,n)}return null}function zc(t){try{let e=JSON.parse(atob(t.split(".")[1].replace(/-/g,"+").replace(/_/g,"/")));return typeof e.exp=="number"?e.exp*1e3:null}catch{return null}}function Qc(t,e){let n=null,r=null;return async()=>{let o=n?zc(n):null;return n&&(o===null||o-Date.now()>3e4)?n:(r||(r=Ue({nodeUrl:t.relayUrl,node:e,deviceSecret:t.deviceSecret,accountProof:t.credential,audience:Me()}).then(i=>(n=i.accessToken,n)).catch(i=>{console.warn("[mero-js] relay login failed",i),n=null}).finally(()=>{r=null})),r)}}var un=new Map;function Hi(){un.clear()}function Yc(t){return typeof t=="object"&&t!==null&&t.status===409}function Xc(t,e){let n=t.rpc,r=ge(e),o=async i=>{let s=`${r}|${i.contextId}|${i.method}`;if(un.get(s)!=="write")try{let{returns:a}=await t.admin.queryContext(i.contextId,{method:i.method,argsJson:i.argsJson??{}});return un.set(s,"read"),{returns:a,transport:"relay"}}catch(a){Yc(a)&&un.set(s,"write")}return n.executeWithMetadata(i)};return{get kind(){return n.kind},get canSubscribe(){return n.canSubscribe},execute:async i=>(await o(i)).returns,executeWithMetadata:o,migrateMyEntries:i=>n.migrateMyEntries(i),countMyPending:i=>n.countMyPending(i)}}function Zc(t){return new q({baseUrl:t,authorize:async()=>({}),fetch:(e,n)=>new Promise((r,o)=>{let i=()=>o(Object.assign(new Error("the stream was closed before the relay was attested"),{name:"AbortError"}));if(n?.signal?.aborted)return i();n?.signal?.addEventListener("abort",i,{once:!0})})})}function el(t,e){let n=e.session?Xc(t,e.relayUrl):null,r=null;return new Proxy(t,{get(o,i){if(i==="rpc"&&n)return n;if(!e.attested){if(i==="canSubscribe")return!1;if(i==="events")return r??(r=Zc(e.relayUrl));if(i==="close")return()=>{r?.close(),o.close()}}let s=Reflect.get(o,i,o);return typeof s=="function"?s.bind(o):s}})}function yn(t,e){if(!t.relayUrl)return null;let n=mn(t.relayUrl),r=ln({transport:"relay",relay:{relayUrl:t.relayUrl,authorAccount:t.account,authorProof:t.credential,deviceSecret:t.deviceSecret,nonces:Nr(t.relayUrl)},proof:{credential:t.credential,deviceSecret:t.deviceSecret},session:n?Qc({...t,relayUrl:t.relayUrl},n):void 0,observe:n?{nodeKey:n}:void 0});return el(r,{relayUrl:t.relayUrl,session:n!==null,attested:n!==null||Gi(t.relayUrl)})}var Li="calimero.delegated.relays.";function B(t){try{let e=localStorage.getItem(Li+t),n=e?JSON.parse(e):{};return{namespaces:n.namespaces??{},contexts:n.contexts??{}}}catch{return{namespaces:{},contexts:{}}}}function Or(t,e){try{localStorage.setItem(Li+t,JSON.stringify(e))}catch{}}function me(t,e,n){let r=B(t),o=ge(e);n.namespaceId&&(r.namespaces[n.namespaceId]=o),n.contextId&&(r.contexts[n.contextId]=o),Or(t,r)}function Ki(t,e){return B(t).contexts[e]??null}function bn(t,e){return e.executorAccount||!t?.executorAccount||!t.relayUrl||!e.relayUrl||ge(t.relayUrl)!==ge(e.relayUrl)?e:{...e,executorAccount:t.executorAccount}}function $e(t){let e=B(t.account),n=[t.relayUrl,...Object.values(e.namespaces),...Object.values(e.contexts)].filter(r=>typeof r=="string"&&r.length>0).map(ge);return[...new Set(n)]}async function qi(t){let e=[],n=B(t.account);for(let r of $e(t))try{if(!await fn(r))continue;let o=yn({...t,relayUrl:r},null);if(!o)continue;let{contexts:i}=await o.admin.getContexts();for(let s of i??[])e.push({...s,relayUrl:r}),n.contexts[s.id]=r}catch(o){console.warn(`[mero-js] could not list contexts on ${r}`,o)}return Or(t.account,n),e}async function Bi(t){var o,i;let e=[],n=new Set,r=B(t.account);for(let s of $e(t))try{if(!await fn(s))continue;let a=yn({...t,relayUrl:s},null);if(!a)continue;for(let c of await a.admin.listNamespaces())n.has(c.namespaceId)||(n.add(c.namespaceId),e.push({...c,relayUrl:s}),(o=r.namespaces)[i=c.namespaceId]??(o[i]=s))}catch(a){console.warn(`[mero-js] could not list namespaces on ${s}`,a)}return Or(t.account,r),e}function An(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 st(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 tl(t){return{getWarrantNonce:(e,n)=>t.client.getWarrantNonceAsAuthor(e,t.authorProof)}}var wn=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 nl(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??An(1),r=t.onLookupFailure??"throw",o=null,i=null,s=async()=>{let a=await Promise.allSettled(e.map(d=>d.getWarrantNonce(t.contextId,t.authorDeviceKey))),c=null,u=!1;for(let d of a){if(d.status!=="fulfilled")continue;let l=d.value;if(l.kind==="exhausted"){u=!0;continue}(c===null||l.nextNonce>c)&&(c=l.nextNonce)}if(c===null&&u)throw new wn(t.contextId,t.authorDeviceKey);if(c===null){let d=a.find(g=>g.status==="rejected"),l=d&&d.status==="rejected"?d.reason:void 0;if(r==="local"){o=0n;return}throw l instanceof Error?l:new Error(`no node could answer where the warrant-nonce sequence stands: ${String(l)}`)}o=c,await n.advanceTo?.(c)};return{async next(){o===null&&(i??(i=s().finally(()=>{i=null})),await i);let a=await n.next(),c=o!==null&&o>a?o:a;return o=c+1n,c},async advanceTo(a){(o===null||a>o)&&(o=a),await n.advanceTo?.(a)}}}async function ji(t){if(!t.sessionToken&&!t.googleIdToken)throw new Error("connectCloud needs either a sessionToken or a googleIdToken");let e=await E(t.deviceSecret,t.signer,"deviceSecret"),n=new H({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=ol(r,t.namespaceId),i=await n.getNamespaceRelays(o.namespaceId),s=Mr(i);if(!s)throw new Error(il(o,i));let a=new J({relayUrl:s.relayUrl,executorAccount:s.executorAccount,authorAccount:t.authorAccount,authorProof:t.authorProof,signer:e,nonces:t.nonces??sl(e.publicKey),ttlSeconds:t.ttlSeconds,fetch:t.seal?Xe({baseUrl:s.relayUrl,verify:t.seal,fetch:t.fetch}):t.fetch,timeoutMs:t.timeoutMs});return{cloud:n,relay:a,namespaceId:o.namespaceId,namespace:o,relayInfo:s,execute:(c,u,d)=>a.execute(c,u,d),client:new pe({transport:"relay",relay:a,observe:{nodeKey:t.relayNodeKey??s.nodeKey,audience:t.observeAudience,fetch:t.fetch,timeoutMs:t.timeoutMs}})}}async function rl(t){let{root:e,authorAccount:n,...r}=t,o=await E(r.deviceSecret,r.signer,"deviceSecret"),i=await Y(e),a=await new H({cloudBaseUrl:t.cloudBaseUrl,onSession:t.onSession,fetch:t.fetch,timeoutMs:t.timeoutMs}).signInWithAccount(i.signer);return ji({...r,deviceSecret:void 0,signer:o,sessionToken:a.sessionToken,authorAccount:n??i.accountId})}function ol(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 il(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 sl(t){let e=`mero-js:warrant-nonce:${t}`;try{return st(e)}catch{return An(1)}}var al=new TextEncoder().encode("calimero.mdma.routing-read.v1\0");async function Fi(t,e){p(e,"deviceSecret",32);let n=await te(e),r=m(al,new TextEncoder().encode(t)),o=new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},n,r));return cl(o)}async function xn(t,e){return{"X-Calimero-Credential":e.credential,"X-Calimero-Nonce":t.nonce,"X-Calimero-Signature":await Fi(t.nonce,e.deviceSecret)}}function cl(t){let e="";for(let n of t)e+=String.fromCharCode(n);return btoa(e)}var ll="https://cloud.calimero.network";function Wi(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??ll);return e.searchParams.set("link-account",t.accountId),e.searchParams.set("callback-url",t.returnTo),e.toString()}function ul(t){throw window.location.assign(Wi(t)),new Error("redirecting to the cloud to authorise this link")}function dl(t=window.location){let e=new URLSearchParams(t.hash.replace(/^#/,"")),n=e.get("error");if(n)throw Vi(),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:(Vi(),{grant:r,account:o})}function Vi(){typeof history>"u"||!history.replaceState||history.replaceState(null,"",location.pathname+location.search)}async function pl(t){let e=await Y(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 H({cloudBaseUrl:t.cloudBaseUrl,fetch:t.fetch}).linkAccountWithGrant({grant:t.grant,signer:e.signer})}var gl="enrol-device",ml="enrol-kem",hl="callback-url",fl="state";function Qi(t){zi(t.devicePublicKey,"devicePublicKey"),zi(t.kemPublicKey,"kemPublicKey"),xl(t.returnTo),Al(t.returnTo);let e=new URL(t.walletUrl);return e.searchParams.set(gl,t.devicePublicKey),e.searchParams.set(ml,t.kemPublicKey),e.searchParams.set(hl,t.returnTo),t.state&&e.searchParams.set(fl,t.state),e.toString()}function yl(t){throw window.location.assign(Qi(t)),new Error("redirecting to the wallet to approve this device")}function bl(t=window.location){let e=new URLSearchParams(t.hash.replace(/^#/,"")),n=e.get("error");if(n)throw Ji(),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;Ji();let s=e.get("state");return{credential:r,account:o,device:i,...s?{state:s}:{}}}function Ji(){typeof history>"u"||!history.replaceState||history.replaceState(null,"",location.pathname+location.search)}async function wl(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 Pt(t.credential);if(e.signPublicKey!==he(t.devicePublicKey))throw new Error(`this credential certifies device key ${e.signPublicKey}, but this app holds ${he(t.devicePublicKey)} \u2014 it would sign with a key the certificate does not cover`);if(t.kemPublicKey!==void 0&&e.kemPublicKey!==he(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!==he(t.account))throw new Error(`the wallet reported account ${he(t.account)}, but the credential names ${e.account}`);if(e.device!==he(t.device))throw new Error(`the wallet reported device ${he(t.device)}, but the credential names ${e.device}`);return{credential:t.credential,account:e.account,device:e.device,certificate:e}}function zi(t,e){if(!/^[0-9a-f]{64}$/.test(t))throw new Error(`${e} must be 64 lowercase hex characters`)}function he(t){return t.trim().toLowerCase()}function Yi(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 Al(t){Yi(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 xl(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}`)}function dt(t){if(!t)return null;let e=t.trim().toLowerCase(),n=e.startsWith("0x")?e.slice(2):e;return n.length>0?n:null}function Rl(t){let e=[];for(let n of t??[])try{let r=new URL(n);(r.protocol==="http:"||r.protocol==="https:")&&e.push(n.replace(/\/+$/,""))}catch{}return e}function Cl(t,e){if(e.size===0)return!0;let n=dt(t.account);return n!==null&&e.has(n)}async function vn(t){let e=t.cloud??new H({cloudBaseUrl:t.cloudBaseUrl,routingCredential:{credential:t.credential,deviceSecret:t.deviceSecret}}),n,r;try{let l=await e.getNamespaceRouting(t.namespaceId);n=l.nodes,r=l.servable}catch(l){return{ok:!1,step:"admitters-lookup",reason:`The cloud could not be asked which nodes serve namespace ${t.namespaceId}: ${l instanceof Error?l.message:String(l)}. Nothing is known about the invitation yet \u2014 this is the lookup failing, not the invitation.`}}if(n.length===0){let[l]=Rl(t.admitterAddrs);if(l){let g=(t.admitters??[]).map(dt).filter(w=>w!==null);return{ok:!0,relayUrl:l,admitUrl:`${l}/admin-api/namespaces/${t.namespaceId}/admit`,admitterAccount:g.length===1?g[0]:null,peerId:null,writable:!0,stale:!1,via:"invitation"}}return{ok:!1,step:"no-nodes",reason:"The cloud lists no nodes serving this namespace, so there is no hosted node to be admitted through. The namespace has no fleet assignment \u2014 whoever invited you is running their own node, and admission has to go through a node the cloud routes to."}}let o=new Set((t.admitters??[]).map(dt).filter(l=>l!==null)),i=n.filter(l=>Cl(l,o));if(i.length===0)return{ok:!1,step:"not-invited",reason:`${n.length} node${n.length===1?"":"s"} serve this namespace, but your invitation names none of them. The signed admitter list is a snapshot from when the invitation was minted, so a node assigned since is healthy and will still refuse the claim. Ask for a fresh invitation.`};let s=i.filter(l=>l.canAdmit),a=s.length>0?s:i,c=s.length===0||!r,u=a.filter(l=>typeof l.relayUrl=="string"&&l.relayUrl.length>0);if(u.length===0)return{ok:!1,step:"no-relay-url",reason:"A node your invitation names can admit you, but the cloud knows no address for it yet, so there would be nothing to connect through afterwards. Try again shortly."};let d=u.find(l=>l.canExecute)??u.find(l=>l.fresh)??u[0];return{ok:!0,relayUrl:d.relayUrl,admitUrl:d.admitUrl??`${d.relayUrl.replace(/\/+$/,"")}/admin-api/namespaces/${t.namespaceId}/admit`,admitterAccount:d.account,peerId:d.peerId,writable:d.canExecute,stale:!d.fresh||c,via:"cloud"}}var Rn=1440*60,Gr={Admin:0,Member:1,ReadOnly:2};function pt(t){let e=t.admitters??[];return m(_r(t.inviter_identity,"inviter_identity"),_r(t.group_id,"group_id"),C(t.expiration_timestamp),_r(t.secret_salt,"secret_salt"),new Uint8Array([t.invited_role]),v(e.length),...e.map((n,r)=>p(n,`admitters[${r}]`,32)))}async function $r(t){return new Uint8Array(await crypto.subtle.digest("SHA-256",pt(t)))}function Hr(t){return[...new Set(t.filter(n=>n.role==="Admin").map(n=>n.identity.toLowerCase()))].sort()}async function Cn(t){let e=await E(t.deviceSecret,t.signer,"deviceSecret"),n=p(e.publicKey,"signer.publicKey",32),r=p(t.groupId,"groupId",32);p(t.inviterAccount,"inviterAccount",32);let o=[...t.admitters??[]].map(g=>g.trim().toLowerCase());if(o.length===0){if(!t.members)throw new Error("name the admitters, or pass the group members to default them to its admins: an invitation with no admitters is claimable by broadcast");if(o=Hr(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,w)=>p(g,`admitters[${w}]`,32));let i=t.invitedRole??Gr.Member;if(![0,1,2].includes(i))throw new Error(`invitedRole must be 0 (Admin), 1 (Member) or 2 (ReadOnly), got ${i}`);let s=t.now??Math.floor(Date.now()/1e3),a=Math.min(t.validForSecs??Rn,Rn);if(!Number.isInteger(a)||a<=0)throw new Error(`validForSecs must be a positive whole number, got ${t.validForSecs}`);let c=t.nonce??crypto.getRandomValues(new Uint8Array(32));if(c.length!==32)throw new Error(`nonce must be 32 bytes, got ${c.length}`);let u={inviter_identity:Array.from(n),group_id:Array.from(r),expiration_timestamp:s+a,secret_salt:Array.from(c),invited_role:i,admitters:o},d=await e.sign(await $r(u));if(d.length!==64)throw new Error(`signer returned ${d.length} bytes, expected a 64-byte Ed25519 signature`);let l={invitation:u,inviter_signature:f(d),inviter_account:t.inviterAccount.trim().toLowerCase()};return t.admitterAddrs?.length&&(l.admitter_addrs=[...t.admitterAddrs]),t.applicationId&&(l.application_id=Array.from(p(t.applicationId,"applicationId",32))),t.appKey&&(l.app_key=Array.from(p(t.appKey,"appKey",32))),l}function _r(t,e){if(t.length!==32)throw new Error(`${e} must be 32 bytes, got ${t.length}`);return new Uint8Array(t)}var Lr=22,Sl=new TextEncoder().encode("calimero.namespace.v1"),kl=0,Xi={GroupCreated:0,GroupReparented:1,GroupDeleted:2,AdminChanged:3,PolicyUpdated:4,MemberJoined:5,KeyDelivery:6,MemberJoinedOpen:7,MemberJoinedAt:8,NamespaceCreatedV2:9,MemberJoinedViaTeeAttestation:10};function Zi(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 es(t){let e=new TextEncoder().encode(t);return m(v(e.length),e)}function Sn(t){let e=t.invitation,n=t.admitter_addrs??[];return m(pt(e),es(t.inviter_signature),t.inviter_account?m(new Uint8Array([1]),p(t.inviter_account,"inviter_account",32)):new Uint8Array([0]),v(n.length),...n.map(es),Zi(t.application_id,"application_id"),Zi(t.app_key,"app_key"))}async function kn(t){let e=t.parentOpHashes??[],n=p(t.credential,"credential",t.credential.length/2),r=BigInt(t.invitation.invitation.expiration_timestamp??0)!==0n,o=t.joinedAt??BigInt(Math.floor(Date.now()/1e3)),i=r?m(new Uint8Array([Xi.MemberJoinedAt]),p(t.member,"member",32),Sn(t.invitation),C(o),n):m(new Uint8Array([Xi.MemberJoined]),p(t.member,"member",32),Sn(t.invitation),n),s=m(new Uint8Array([kl]),i),a=await E(t.deviceSecret,t.signer,"deviceSecret"),c=p(a.publicKey,"signer.publicKey",32),u=m(new Uint8Array([Lr]),p(t.namespaceId,"namespaceId",32),v(e.length),...e.map((g,w)=>p(g,`parentOpHashes[${w}]`,32)),c,C(t.nonce),s),d=await a.sign(m(Sl,u)),l=new Uint8Array([0]);return f(m(u,d,l))}function El(t,e){let n=e?`: ${e}`:"";switch(t){case 400:return`The node refused the join as malformed (400)${n}. The signature covers the invitation exactly as sent, so an edited or re-serialised invitation fails here \u2014 as does a namespace id that is not the invitation's own group.`;case 403:return`The node refused to carry this join (403)${n}. Either it is not in the invitation's signed admitters list \u2014 being live and listed by the cloud is not the same thing \u2014 or the invitation itself was rejected as expired or not the inviter\u2019s to issue.`;case 409:return`That node holds no device of its own, so it cannot endorse anyone (409)${n}. Another admitter from the same invitation would work.`;default:return`The join was not published (HTTP ${t})${n}.`}}function Il(t){let e=st(`calimero.delegated.joinnonce.${t}`);return()=>e.next()}function ts(t){return t.replace(/\/+$/,"")}async function En(t){let{account:e,credential:n,deviceSecret:r}=t.credential,o;try{o=await kn({namespaceId:t.namespaceId,member:e,invitation:t.invitation,credential:n,deviceSecret:r,nonce:await(t.deps?.nonce??Il(e))()})}catch(l){return{ok:!1,step:"sign",reason:`The join op could not be signed, so nothing was sent: ${l instanceof Error?l.message:String(l)}`}}let i={invitation:t.invitation,signedOp:o},s=t.admitUrl??`${ts(t.nodeUrl)}/admin-api/namespaces/${t.namespaceId}/admit`,a=t.deps?.fetch??fetch,c;try{c=await a(s,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify(i)})}catch(l){return{ok:!1,step:"admit",reason:`The admitter at ${t.nodeUrl} could not be reached: ${l instanceof Error?l.message:String(l)}. The invitation is untouched \u2014 this is the node being unreachable, not a refusal.`}}let u=await c.text();if(!c.ok)return{ok:!1,step:"admit",status:c.status,reason:El(c.status,u)};let d=!1;try{d=(u?JSON.parse(u):{}).data?.published===!0}catch{d=!1}return{ok:!0,published:d,session:{relayUrl:ts(t.nodeUrl),account:e,credential:n,deviceSecret:r}}}async function In(t){let e=t.deps?.resolve??vn,n=t.deps?.join??En,r=null,o=t.nodeUrl,i;if(!o){let a=await e({namespaceId:t.namespaceId,admitters:t.invitation.invitation.admitters,admitterAddrs:t.invitation.admitter_addrs,credential:t.credential.credential,deviceSecret:t.credential.deviceSecret,cloudBaseUrl:t.cloudBaseUrl});if(a.ok===!1)return a;r=a,o=a.relayUrl,i=a.admitUrl}let s=await n({nodeUrl:o,admitUrl:i,namespaceId:t.namespaceId,invitation:t.invitation,credential:t.credential,deps:{fetch:t.deps?.fetch,nonce:t.deps?.nonce}});return s.ok===!1?s:{ok:!0,published:s.published,relay:r,session:s.session}}async function ns(t,e,n,r){let i=await(r.bootstrap??In)({namespaceId:e,invitation:n,credential:{account:t.account,credential:t.credential,deviceSecret:t.deviceSecret},cloudBaseUrl:r.cloudBaseUrl});if(i.ok===!1)throw Object.assign(new Error(i.reason),{step:i.step,...i.status!==void 0?{status:i.status}:{}});return i.session.relayUrl&&me(t.account,i.session.relayUrl,{namespaceId:e}),r.onJoined(bn(t,i.session)),{namespaceId:e}}function rs(t){let e=new TextEncoder().encode(t),n=new Uint8Array(4+e.length);return new DataView(n.buffer).setUint32(0,e.length,!0),n.set(e,4),n}async function Kr(t,e){let n=rs(t),r=rs(e),o=new Uint8Array(n.length+r.length);o.set(n,0),o.set(r,n.length);let i=await crypto.subtle.digest("SHA-256",o);return Array.from(new Uint8Array(i),s=>s.toString(16).padStart(2,"0")).join("")}function Pl(t,e){let[n,r]=[t,e].map(o=>o.split(/[.-]/).map(i=>Number.parseInt(i,10)||0));for(let o=0;o<Math.max(n.length,r.length);o++)if((n[o]??0)!==(r[o]??0))return(n[o]??0)>(r[o]??0);return!1}function gt(t){return t.filter(e=>!e.yanked&&typeof e.appVersion=="string"&&e.appVersion.length>0).reduce((e,n)=>!e||Pl(n.appVersion,e.appVersion)?n:e,void 0)}async function mt(t,e,n=globalThis.fetch){let r=`${t.replace(/\/+$/,"")}/api/v2/bundles?package=${encodeURIComponent(e)}`,o=await n(r,{headers:{Accept:"application/json"}});if(!o.ok)throw new Error(`the registry has no ${e} (HTTP ${o.status})`);let i=await o.json();return Array.isArray(i)?i:[]}async function os(t,e,n={}){let o=(await mt(t,e,n.fetch)).filter(c=>!c.yanked),i=[...new Set(o.map(c=>c.signerId).filter(c=>typeof c=="string"&&c.length>0))];if(i.length>1)throw new Error(`the registry lists ${e} under more than one publisher (${i.join(", ")}): refusing to guess which application it is`);let s=gt(o);if(!s)throw new Error(`the registry lists no version of ${e}`);let a=s.signerId;if(!a)throw new Error(`the registry names no publisher for ${e} ${s.appVersion}`);return{applicationId:await Kr(e,a),signerId:a,version:s.appVersion}}function is(t,e){return{next:async()=>Tl(t,e)}}function Tl(t,e){let n=`calimero.governance-nonce.${t}.${e}`,r=0n;try{r=BigInt(localStorage.getItem(n)??"0")}catch{}let o=[r+1n,BigInt(Date.now())].reduce((i,s)=>i>s?i:s);try{localStorage.setItem(n,String(o))}catch{}return o}function ss(t,e){let n=B(t.account).namespaces[e]??t.relayUrl;if(!n)throw new Error("no relay is known for this namespace, so there is nowhere to send this");return n.replace(/\/+$/,"")}function Dl(t){return!t||t.length===0?{}:JSON.parse(new TextDecoder().decode(Uint8Array.from(t)))}function Pn(t,e,n,r){return new J({relayUrl:e,authorAccount:t.account,authorProof:t.credential,deviceSecret:t.deviceSecret,nonces:n,fetch:r})}async function ht(t,e,n={}){let r=ss(t,e.namespaceId),o=0n,i=await Pn(t,r,{next:async()=>o},n.fetch).createContext({groupId:e.groupId??e.namespaceId,applicationId:e.applicationId,serviceName:e.serviceName,seed:e.contextSeed,initArgs:Dl(e.initializationParams),name:e.name});return gn(r,i.contextId,o),me(t.account,r,{namespaceId:e.namespaceId,contextId:i.contextId}),{contextId:i.contextId}}async function ye(t,e,n={}){let r=ss(t,e.namespaceId);return Pn(t,r,is(r,e.group),n.fetch).govern({groupId:e.group,op:e.op})}async function as(t,e,n={}){let{groupId:r}=await ye(t,{namespaceId:e.namespaceId,group:e.namespaceId,op:(await De({parentId:e.namespaceId,restricted:!0,admin:t.account})).op},n);for(let i of e.members)await ye(t,{namespaceId:e.namespaceId,group:r,op:Pe(i,"Member")},n);let{contextId:o}=await ht(t,{...e,groupId:r},n);return{contextId:o,groupId:r}}async function Dn(t,e={},n={}){let o=$e(t).map(l=>l.replace(/\/+$/,""))[0];if(!o)throw new Error("no relay is known for this account, so there is nowhere to found a namespace");let i=Object.entries(B(t.account).namespaces).find(([,l])=>l.replace(/\/+$/,"")===o)?.[0],s=t.executorAccount&&t.relayUrl&&t.relayUrl.replace(/\/+$/,"")===o?t.executorAccount:null;if(!s&&!i)throw new Error("the executor account of this relay is not known: join a namespace on it first, or connect with the relay's executor account (the cloud shows it beside the relay)");let a=s??(await Pn(t,o,is(o,i),n.fetch).describeGovernance(i)).executorAccount,c=BigInt(Date.now()),u=await Pn(t,o,{next:async()=>c++},n.fetch).foundNamespace({executorAccount:a,...e.defaultCapabilities!==void 0?{defaultCapabilities:e.defaultCapabilities}:{},...e.application?{application:e.application}:{}});try{localStorage.setItem(`calimero.governance-nonce.${o}.${u.namespaceId}`,String(c))}catch{}if(me(t.account,o,{namespaceId:u.namespaceId}),e.application&&u.applicationSet!==!0)throw new Error(`founded ${u.namespaceId} but could not give it its application: ${u.applicationError??"unknown reason"}`);let d=u.teeEnabled?await Ul(t,u.namespaceId,u.salt,o,n):{haEnabled:!1,haError:`the relay did not attest the founding, so no fleet node could be admitted for HA${u.teeError?`: ${u.teeError}`:""}`};return{namespaceId:u.namespaceId,teeEnabled:u.teeEnabled,...d}}var Nn="link this account to your cloud user in the wallet so invitees can find this namespace",Tn={account_not_linked:Nn,account_linked_to_several_users:"this account is linked to more than one cloud user, so the cloud cannot tell whose plan hosts the namespace: unlink it from all but one in the wallet",ha_request_pending:"another namespace of this account is still waiting to be hosted; the cloud hosts one new namespace at a time without a cloud sign-in. Sign in to the cloud and turn off hosting for the waiting namespace, or wait until it is hosted",unknown_relay:"the cloud does not run the relay this namespace was founded on, so it cannot host it",relay_not_dialable:"the relay this namespace was founded on has not reported its address to the cloud yet; try enabling hosting again shortly"};function Nl(t){try{let e=JSON.parse(t.bodyText??""),n=e?.detail?.namespace_id??e?.namespace_id;return typeof n=="string"&&/^[0-9a-f]{64}$/i.test(n)?n.toLowerCase():null}catch{return null}}async function Ul(t,e,n,r,o){try{return await new H({cloudBaseUrl:o.cloudBaseUrl,fetch:o.fetch}).enableHaAsAccount({namespaceId:e,salt:n,accountId:t.account,credential:t.credential,deviceSecret:t.deviceSecret,relayUrl:r}),{haEnabled:!0}}catch(i){if(i instanceof fe)return{haEnabled:!1,haError:Nn};if(i instanceof z&&Tn[i.code]){let s=i.code==="ha_request_pending"?Nl(i):null,a=Tn[i.code];return{haEnabled:!1,haError:s?`${a} (waiting: ${s})`:a}}return{haEnabled:!1,haError:i instanceof Error?i.message:String(i)}}}async function He(t,e,n=globalThis.fetch){let r=gt(await mt(t,e,n));if(!r)throw new Error(`the registry lists no version of ${e}`);return r.appVersion}var cs="calimero.delegated.group-namespace.",qr=new Map;function ls(t){let e={};try{e=JSON.parse(localStorage.getItem(cs+t)??"{}")}catch{}return{...e,...qr.get(t)}}function ft(t,e,n){qr.set(t,{...qr.get(t),[e]:n});try{let r=ls(t);r[e]=n,localStorage.setItem(cs+t,JSON.stringify(r))}catch{}}function yt(t,e){return B(t.account).namespaces[e]?e:ls(t.account)[e]}function us(t,e){let n=yt(t,e);if(!n)throw new Error(`the namespace of group ${e} is not known to this account: it can manage only groups in namespaces it joined or subgroups it created`);return n}async function Un(t,e,n){return ye(t,{namespaceId:us(t,e),group:e,op:n})}async function On(t,e,n){let r=us(t,e);return ye(t,{namespaceId:r,group:r,op:n})}var be=class extends Error{constructor(n){super(`${n} is not available for an account: it needs a node`);this.method=n;this.name="NotForAccountError"}},Le=class extends Error{constructor(n){super(`${n} needs a relay, and this account has none yet: join from an invitation first`);this.method=n;this.name="NoRelayError"}},Ke=class extends Error{constructor(n,r){super(r==="not-hosted"?`nobody could claim an invitation to ${n} yet: the namespace is not hosted in the cloud and has no relay in it, so an invitee with no node has no relay to be admitted through. Link this account to your cloud user in the wallet and enable HA for the namespace, then invite.`:`nobody could claim an invitation to ${n}: the cloud routes to none of the relays or admins it would name as admitters`);this.namespaceId=n;this.reason=r;this.name="InvitationNotClaimableError"}},ds={listNamespaces:async()=>[],listNamespacesForApplication:async()=>[],getContexts:async()=>({contexts:[]})},Ol=new Set(["upgradeGroup","retryGroupUpgrade","abortMigration","installApplication","installDevApplication","uninstallApplication","generateContextIdentity","deleteContext","leaveContext","createContextAlias","createApplicationAlias","createDeviceAlias","deleteContextAlias","deleteApplicationAlias","deleteDeviceAlias","lookupContextAlias","lookupApplicationAlias","lookupDeviceAlias","listContextAliases","listApplicationAliases","listDeviceAliases","deleteNamespace","createGroupInvitation","joinGroup","setTeeAdmissionPolicy","getTeeAdmissionPolicy","deleteBlob","listAccountDevices","revokeAccountDevice"]);function Ml(t){if(!(t instanceof Error))return!1;let e=t.status;return(e===void 0||e===409)&&/signer [0-9a-f]+ is a direct member/i.test(t.message)}function ps(t,e={}){let{session:n,read:r,app:o}=t,i=e.govern?.group??Un,s=e.govern?.root??On,a=e.createContext??ht,c=e.found??Dn,u=e.latestVersion??He,d=e.signInvitation??Cn,l=e.join,g=e.routing;async function w(h,y){if(!l)throw new be("joinNamespace without a join handler");return l(h,y.invitation)}let x=()=>{if(r===null)throw new Le("this call");return r};async function A(h){if(yt(n,h))return;let y=await x().getGroupInfo(h);ft(n.account,h,y.namespaceId??h)}let R=async(h,y,S)=>(await A(y),i(h,y,S)),I=async(h,y,S)=>(await A(y),s(h,y,S));async function P(h){try{return await I(n,h,sn({member:n.account,groupId:h,credential:n.credential})),!0}catch(y){if(Ml(y))return!1;throw y}}async function j(h,y){let S=y??String(await x().getContextGroup(h)),{members:N}=await x().listGroupMembers(S);return N.some(_=>_.identity.toLowerCase()===n.account.toLowerCase())}let M={async listNamespacesForApplication(h){return(await x().listNamespaces()).filter(y=>y.targetApplicationId===h)},async getNodeIdentity(){return{accountId:n.account,deviceId:null,publicKey:"",deviceCertified:!0}},async createNamespace(h){if(!o.packageName)throw new be("createNamespace without a packageName");let y=o.packageVersion??await u(o.registryUrl??"https://apps.calimero.network",o.packageName),{namespaceId:S,haEnabled:N,haError:_}=await c(n,{defaultCapabilities:231,application:{applicationId:h.applicationId,package:o.packageName,version:y}});return h.name&&await R(n,S,Ne({name:h.name})),{namespaceId:S,haEnabled:N,..._!==void 0?{haError:_}:{}}},async createGroupInNamespace(h,y={}){let{op:S}=await De({parentId:h,restricted:y.visibility!=="open",admin:n.account}),{groupId:N}=await I(n,h,S);return ft(n.account,N,h),y.groupName&&await R(n,N,Ne({name:y.groupName})),{groupId:N}},async addGroupMembers(h,y){for(let S of y.members)await R(n,h,Pe(S.identity,S.role??"Member"))},async removeGroupMembers(h,y){for(let S of y.members)await R(n,h,Wt(S))},async setGroupMetadata(h,y){await R(n,h,Ne(y))},async setMemberMetadata(h,y,S){await R(n,h,rn(y,S))},async setContextMetadata(h,y,S){await R(n,h,on(y,S))},async setDefaultCapabilities(h,y){await R(n,h,Te(y.defaultCapabilities))},async setSubgroupVisibility(h,y){await R(n,h,nn(y.subgroupVisibility==="open"?"open":"restricted"))},async setMemberCapabilities(h,y,S){await R(n,h,en(y,S.capabilities))},async deleteGroup(h){return await I(n,h,Yt(h)),{isDeleted:!0}},async reparentGroup(h,y){return await I(n,h,Qt(h,y.newParentId)),{reparented:!0}},async leaveGroup(h){await R(n,h,ot(n.account))},async leaveNamespace(h){await R(n,h,ot(n.account))},async getContextIdentitiesOwned(h){return{identities:await j(h)?[n.account]:[]}},async joinContext(h){return await P(String(await x().getContextGroup(h))),{contextId:h,memberPublicKey:n.account}},async createContext(h){let S=(await x().getGroupInfo(h.groupId)).namespaceId??h.groupId,{contextId:N}=await a(n,{namespaceId:S,groupId:h.groupId,applicationId:h.applicationId,serviceName:h.serviceName,contextSeed:h.contextSeed,name:h.name,initializationParams:h.initializationParams});return{contextId:N,memberPublicKey:n.account,groupId:h.groupId}},async createNamespaceInvitation(h){let[{members:y},S]=await Promise.all([x().listGroupMembers(h),x().getGroupInfo(h)]),N=y.filter(Q=>Q.role==="RelayTee").map(Q=>Q.identity.toLowerCase()),_;if(g){let Q=new Set(N.length>0?N:y.filter(K=>K.role==="Admin").map(K=>K.identity.toLowerCase())),we=null;try{we=(await g(h)).nodes}catch{}if(we!==null){if(we.length===0){if(N.length===0||!n.relayUrl)throw new Ke(h,"not-hosted");_=[n.relayUrl]}else if(!we.some(K=>K.account!==null&&Q.has(K.account.toLowerCase())))throw new Ke(h,"no-named-node")}}return{invitation:await d({groupId:h,inviterAccount:n.account,deviceSecret:n.deviceSecret,...N.length>0?{admitters:N}:{},..._?{admitterAddrs:_}:{},members:y,applicationId:S.targetApplicationId,appKey:S.appKey})}},async syncGroup(h){return{groupId:h,synced:!0}},async syncContext(){},joinNamespace:w,async updateMemberRole(h,y,S){await R(n,h,Jt(y,S.role))},async joinSubgroupInheritance(h){return{groupId:h,memberPublicKey:n.account,wasInherited:await P(h)}},async detachContextFromGroup(h,y){await R(n,h,tn(y))}};return r===null?new Proxy({},{get(h,y){if(typeof y=="string")return y==="getNodeIdentity"?M.getNodeIdentity:y==="joinNamespace"?w:y in ds?ds[y]:async()=>{throw new Le(y)}}}):new Proxy(r,{get(h,y,S){return typeof y=="string"&&y in M?M[y]:typeof y=="string"&&Ol.has(y)?async()=>{throw new be(y)}:Reflect.get(h,y,S)}})}function gs(t,e={}){let{admin:n,app:r}=t,o=e.latestVersion??He;async function i(a){let{apps:c}=await n.listApplications();if(c.some(l=>l.id===a))return;if(!r.packageName)throw new Error(`application ${a} is not installed on this node, and no packageName is set to install it`);let u=r.packageVersion??await o(r.registryUrl??"https://apps.calimero.network",r.packageName),{applicationId:d}=await n.installApplication({package:r.packageName,version:u});if(d!==a)throw new Error(`installed ${r.packageName}@${u} as ${d}, not ${a}`)}let s={async createNamespace(a){return await i(a.applicationId),n.createNamespace(a)}};return new Proxy(n,{get(a,c,u){return typeof c=="string"&&c in s?s[c]:Reflect.get(a,c,u)}})}var _l="https://manager.cloud.calimero.network";function Br(t,e){return typeof t.can_execute=="boolean"?t.can_execute:e}function jr(t){return typeof t.tee_role=="string"&&t.tee_role!==""?t.tee_role:null}function Mr(t){return t.find(e=>e.canExecute&&e.relayUrl!==null&&e.executorAccount!==null)??null}var Gl=/^[0-9a-f]{64}$/;function $l(t){return typeof t=="string"&&Gl.test(t)?t:null}var z=class extends T{constructor(n,r,o,i,s,a){super(r,o,i,s,a);this.code=n;this.name="AccountHaRefusedError"}},fe=class extends z{constructor(){super(...arguments);this.name="AccountNotLinkedError"}};fe.CODE="account_not_linked";var at=class extends z{constructor(){super(...arguments);this.name="AccountLinkedToSeveralUsersError"}};at.CODE="account_linked_to_several_users";var ct=class extends z{constructor(){super(...arguments);this.name="HaRequestPendingError"}};ct.CODE="ha_request_pending";var lt=class extends z{constructor(){super(...arguments);this.name="UnknownRelayError"}};lt.CODE="unknown_relay";var ut=class extends z{constructor(){super(...arguments);this.name="RelayNotDialableError"}};ut.CODE="relay_not_dialable";var ms={409:[fe,at,ct],422:[lt,ut]};function Hl(t){if(t)try{let e=JSON.parse(t);if(typeof e?.error=="string")return e.error;if(typeof e?.detail=="string")return e.detail;let n=e?.detail?.error;if(typeof n=="string")return n}catch{}}var Ll="x-mdma-session-refresh",Kl="x-mdma-session-expires",H=class{constructor(e={}){this.session=null;this.baseUrl=(e.cloudBaseUrl||_l).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 Y(e),{nonce:o}=await this.getAccountLoginChallenge();return this.submitAccountLogin({rootPublicKey:r,nonce:o,signature:await Nt({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,s=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:s,teeRole:jr(r),canExecute:Br(r,s&&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 Mr(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,s=r.fresh===!0,a=r.authorship_ready===!0;return{peerId:String(r.peer_id??""),account:o,relayUrl:i,admitUrl:r.admit_url??null,status:String(r.status??""),fresh:s,canAdmit:r.can_admit===!0,authorshipReady:a,teeRole:jr(r),canExecute:Br(r,a&&i!==null&&o!==null&&s)}}),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 xn(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 xn(n,this.routingCredential)})).relays??[]).map(o=>({peerId:String(o.peer_id??""),relayUrl:o.relay_url??null,fresh:o.fresh===!0,executorAccount:$l(o.executor_account),assigned:o.assigned===!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(s=>{let a=s;return{namespaceId:String(a.namespace_id??""),status:String(a.status??""),authorshipReady:a.authorship_ready===!0,teeRole:jr(a),fresh:a.fresh===!0,confirmedAt:a.confirmed_at??null,lastSeenAt:a.last_seen_at??null}});return{peerId:String(n.peer_id??""),relayUrl:r,executorAccount:o,canExecute:Br(n,r!==null&&o!==null&&i.some(s=>s.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 enableHaAsAccount(e){let n=await zn({namespaceId:e.namespaceId,accountId:e.accountId,salt:e.salt,credential:e.credential,deviceSecret:e.deviceSecret,signer:e.signer,ttlMs:e.ttlMs,relayUrl:e.relayUrl}),r=e.accountId.toLowerCase(),o=e.namespaceId.toLowerCase();try{return await this.request("POST",`/api/cloud/accounts/${encodeURIComponent(r)}/namespaces/${encodeURIComponent(o)}/enable-ha`,{body:{ownership_proof:n},anonymous:!0})}catch(i){if(i instanceof T&&ms[i.status]){let s=Hl(i.bodyText),a=ms[i.status].find(c=>c.CODE===s);if(a&&s)throw new a(s,i.status,i.statusText,i.url,i.headers,i.bodyText)}throw i}}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 Y(e),{nonce:i}=await this.getAccountLinkChallenge();return this.submitAccountLink({accountId:o,rootPublicKey:r,nonce:i,signature:await Je({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"),s=o.get("account"),a=o.get("error"),c={};return i&&(c.grant=i),s&&(c.accountId=s),a&&(c.error=a),c}async linkAccountWithGrant(e){let{signer:n,publicKey:r,accountId:o}=await Dt(e.rootSecret,e.signer),i=await this.request("POST","/api/cloud/accounts/link",{body:{grant:e.grant,root_public_key:r,signature:await Je({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,s=setTimeout(()=>i.abort(),this.timeoutMs),a;try{a=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 T(0,c instanceof Error?c.name:"NetworkError",`${this.baseUrl}${n}`,new Headers,c instanceof Error?c.message:String(c))}finally{clearTimeout(s)}if(this.adoptRollingRefresh(a),!a.ok){let c=await a.text().catch(()=>{});throw new T(a.status,a.statusText,`${this.baseUrl}${n}`,a.headers,c)}if(!(r.parse==="none"||a.status===204))return await a.json()}adoptRollingRefresh(e){let n=e.headers.get(Ll);if(!n||!this.session)return;let r=e.headers.get(Kl),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 vl(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 s of r){if(typeof s!="string")continue;let a=s.trim();if(!a.startsWith("/"))continue;let c=a.endsWith(o)?a:`${a}${o}`;i.includes(c)||i.push(c)}return i}function ql(t){if(t)return typeof t=="function"?t:Ct(t)}var Bl="mero-js:token-refresh";function jl(){let e=globalThis.navigator?.locks;return e&&typeof e.request=="function"?e:null}function Fr(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 _e=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=ql(this.config.requestProof);this.httpClient=Ae({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=Xr(this.httpClient,{baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||"",timeoutMs:this.config.timeoutMs}),this.adminClient=xt(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 Ve({httpClient:this.httpClient})),this.rpcClient}get events(){return this.sseClient||(this.sseClient=new q({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 We({httpClient:this.httpClient,sse:this.events})),this.ephemeralClient}get cloud(){return this.cloudClient||(this.cloudClient=new H(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 re({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:Fr(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=jl();return n?n.request(Bl,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:Fr(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||Fr(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 jn(e)}static buildAuthLoginUrl(e,n){return Fn(e,n)}};function Fl(t){return new _e(t)}var Vr=class{constructor(){this.tokens=null}getTokens(){return this.tokens}setTokens(e){this.tokens=e}clear(){this.tokens=null}},Vl="mero-tokens",Wr=class{constructor(e=Vl){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 Wl=new TextEncoder().encode("calimero.account.owner-op.v1"),Jl=new TextEncoder().encode("calimero.account.owner-op.body.v1"),zl=new TextEncoder().encode("calimero.account.genesis.v1"),Ql=2,Jr={transferOwnership:0,adminChanged:1,groupDelete:2,teeAdmissionPolicy:3,teeAuthoringPolicy:4,teeReleaseAdmissionPolicy:5},qe={GroupDelete:14,TransferOwnership:21,TeeAuthoringPolicySet:33,TeeAdmissionPolicySetV2:37,TeeReleaseAdmissionPolicySetV2:38,RootGuarded:42},fs={AdminChanged:3,RootGuarded:12},Yl={replica:0,relay:1},Xl=new TextEncoder;function L(t){return new Uint8Array([t])}function ys(t){let e=Xl.encode(t);return m(v(e.length),e)}function Z(t){return m(v(t.length),...t.map(ys))}function bs(t){return L(t?1:0)}function ws(t){let e=Yl[t??"replica"];if(e===void 0)throw new Error(`mode must be replica or relay, got ${String(t)}`);return L(e)}function As(t){return{kind:"transferOwnership",plane:"group",bytes:m(L(qe.TransferOwnership),p(t,"newOwner",32))}}function xs(){return{kind:"groupDelete",plane:"group",bytes:L(qe.GroupDelete)}}function vs(t){return{kind:"adminChanged",plane:"root",bytes:m(L(fs.AdminChanged),p(t,"newAdmin",32))}}function Rs(t){return{kind:"teeAuthoringPolicy",plane:"group",bytes:m(L(qe.TeeAuthoringPolicySet),Z(t))}}function Cs(t){return{kind:"teeAdmissionPolicy",plane:"group",bytes:m(L(qe.TeeAdmissionPolicySetV2),Z(t.allowedMrtd),Z(t.allowedRtmr0),Z(t.allowedRtmr1),Z(t.allowedRtmr2),Z(t.allowedRtmr3),Z(t.allowedTcbStatuses),bs(t.acceptMock),ws(t.mode))}}function Ss(t){let e=t.minReleaseVersion===void 0?L(0):m(L(1),ys(t.minReleaseVersion));return{kind:"teeReleaseAdmissionPolicy",plane:"group",bytes:m(L(qe.TeeReleaseAdmissionPolicySetV2),Z(t.allowedProfiles),e,Z(t.allowedTcbStatuses),bs(t.acceptMock),ws(t.mode))}}async function zr(t){return k(Jl,[t])}async function Qr(t){return k(Wl,[p(t.account,"account",32),p(t.namespaceId,"namespaceId",32),p(t.groupId,"groupId",32),L(ks(t.kind)),t.opDigest,C(t.counter),v(t.keyEpoch)])}function ks(t){let e=Jr[t];if(e===void 0)throw new Error(`unknown owner-op kind ${String(t)}`);return e}var hs=132;async function Es(t){let e=await ne(t.rootSecret),n=m(L(Ql),e),r=f(await k(zl,[n])),o=t.keyEpoch??0,i=(t.chain??[]).map((d,l)=>{let g=F(d,`chain[${l}]`);if(g.length!==hs)throw new Error(`chain[${l}] must be a ${hs}-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 s=await zr(t.op.bytes),a=await Qr({account:r,namespaceId:t.namespaceId,groupId:t.groupId,kind:t.op.kind,opDigest:s,counter:t.counter,keyEpoch:o}),c=await te(t.rootSecret),u=new Uint8Array(await crypto.subtle.sign("Ed25519",c,a));return f(m(n,v(i.length),...i,p(r,"account",32),p(t.namespaceId,"namespaceId",32),p(t.groupId,"groupId",32),L(ks(t.op.kind)),s,C(t.counter),v(o),u))}function Is(t,e){let n=t.plane==="group"?qe.RootGuarded:fs.RootGuarded;return m(L(n),t.bytes,F(e,"rootProof"))}var Ps=[2428,2429,2528,2529],Zl="localhost",eu=2e3;function Ts(t){return`http://${Zl}:${t}`}function Ds(t,e){let n=t.endsWith("/")?t:`${t}/`;return new URL(e,n).toString()}async function Ns(t,e={}){let{timeoutMs:n=eu,signal:r}=e;if(r?.aborted)return!1;let o=new AbortController,i=()=>o.abort(),s=r;s&&s.addEventListener("abort",i,{once:!0});let a=setTimeout(()=>o.abort(),n);try{let c=Ds(t,"admin-api/health"),u=await fetch(c,{method:"GET",signal:o.signal});if(!u.ok)return!1;try{let d=await u.json(),l=d?.data?.status!==void 0?d?.data?.status:d?.status;return l===void 0?!0:typeof l=="string"&&l.toLowerCase()==="alive"}catch{return!0}}catch{return!1}finally{clearTimeout(a),s&&s.removeEventListener("abort",i)}}async function tu(t={}){let{ports:e=Ps,timeoutMs:n,signal:r}=t;return(await Promise.all(e.map(async i=>{let s=Ts(i);return await Ns(s,{timeoutMs:n,signal:r})?s:null}))).filter(i=>i!==null)}export{yo as ACCOUNT_HA_AUDIENCE,fo as ACCOUNT_OWNERSHIP_AUDIENCE,z as AccountHaRefusedError,at as AccountLinkedToSeveralUsersError,fe as AccountNotLinkedError,le as AdminApiClient,ae as AuthApiClient,ee as AuthRevokedError,O as CAPABILITIES,xu as CAPABILITY_PRESETS,H as CloudClient,Ps as DEFAULT_LOCAL_NODE_PORTS,$t as DEFAULT_RELEASE_MIRROR,We as EphemeralClient,jo as HANDSHAKE_PATH,Nn as HA_ACCOUNT_NOT_LINKED_MESSAGE,Tn as HA_REFUSAL_MESSAGES,T as HTTPError,ct as HaRequestPendingError,Gr as INVITED_ROLE,ue as IntentRefusedError,Ke as InvitationNotClaimableError,Wr as LocalStorageTokenStore,Rn as MAX_INVITATION_VALIDITY_SECS,Vr as MemoryTokenStore,pe as MeroClient,_e as MeroJs,pr as NODE_RELEASE_SIGNER,Le as NoRelayError,be as NotForAccountError,Jr as OWNER_OP_KIND,Si as PRESENCE_DOMAIN,pn as RELAY_NODE_KEY_RETRY_MS,Cr as REQUEST_PROOF_HEADER,J as RelayClient,ut as RelayNotDialableError,Oe as RelayObserver,it as RelayPresenceClient,de as RelayTransport,Ve as RpcClient,St as RpcError,Qe as SEALED_CONTENT_TYPE,Fo as SEALED_PATH,Lr as SIGNED_NAMESPACE_OP_SCHEMA_VERSION,Ce as SealedTransportError,q as SseClient,Ye as StaleTransportKeyError,lt as UnknownRelayError,wn as WarrantNonceExhaustedError,At as WarrantNonceRouteUnavailableError,Be as WebHttpClient,re as WsClient,Tt as accountForRoot,V as accountForRootPublicKey,So as accountRootFromPhrase,er as accountRootFromSecret,Eo as accountRootSignerFromPhrase,vs as adminChangedOp,vl as admitterAddrsFromNetworkStatus,Kr as applicationIdForBundle,hn as attemptRelayNodeKey,Ot as attestKeyBinding,Mt as attestRelayNodeKey,tl as authorNonceLookup,ul as beginCloudLink,yl as beginDeviceEnrolment,In as bootstrapFromInvitation,Fn as buildAuthLoginUrl,yn as buildDelegatedClient,Yi as callbackIsForeign,Rt as callerProof,vu as capMask,Ru as capNames,bn as carryExecutorAccount,qn as classifyError,Oi as clearDelegatedCredential,Di as clearDelegatedSession,Wi as cloudLinkUrl,Kt as cloudNodeReleaseUrl,Gn as combineSignals,Fs as compareSemver,pl as completeCloudLink,wl as completeDeviceEnrolment,ji as connectCloud,rl as connectCloudWithAccount,xi as contextCapabilityGrantedOp,vi as contextCapabilityRevokedOp,tn as contextDetachedOp,on as contextMetadataSetOp,ps as createAccountAdmin,ko as createAccountRootSigner,ro as createAdminApiClient,xt as createAdminApiClientFromHttpClient,Xe as createAttestedSealedFetch,wu as createAuthApiClient,Xr as createAuthApiClientFromHttpClient,Lu as createBrowserAdminApiClient,yu as createBrowserAuthApiClient,Ae as createBrowserHttpClient,ht as createDelegatedContext,as as createDelegatedPrivateContext,je as createHttpClient,st as createLocalStorageNonceSource,An as createMemoryNonceSource,ln as createMeroClient,Fl as createMeroJs,gs as createNodeAdmin,Ku as createNodeAdminApiClient,bu as createNodeAuthApiClient,bt as createNodeHttpClient,kr as createProofAuthorizer,Ct as createProofSigner,ar as createQuoteVerifier,nl as createRecoveringNonceSource,$s as createRetryableMethod,zo as createSealedFetch,uc as createSignedReleaseSealedFetch,qt as createSignedReleaseVerifier,$n as createTimeoutSignal,Hn as createUniversalHttpClient,wr as createdSubgroupId,mr as creationInitHash,Hr as defaultAdmitters,Me as defaultAudience,Te as defaultCapabilitiesSetOp,ye as delegatedGovernance,It as deviceCertPayload,Qi as deviceEnrolmentUrl,Yn as deviceScopePayload,tu as discoverLocalNodes,pt as encodeGroupInvitation,Sn as encodeSignedInvitation,Jo as fetchAttestedTransportKey,Ht as fetchNodeRelease,Lt as fetchNodeReleaseVersion,mt as fetchRegistryBundles,Hi as forgetMethodKinds,Dn as foundDelegatedNamespace,Xt as foundedNamespaceId,Co as generateAccountRoot,Rr as generateSessionKey,Un as governGroup,On as governRoot,hr as governanceOpHash,Ar as groupCreatedOp,xs as groupDeleteOp,Yt as groupDeletedOp,$r as groupInvitationHash,Ne as groupMetadataSetOp,Qt as groupReparentedOp,ce as hasCap,Mu as hexEncodeUtf8,gr as intentHash,qs as isSettled,ns as joinAsAccount,En as joinWithNode,oe as jsonCodec,$e as knownRelays,He as latestPublishedVersion,$i as learnRelayNodeKey,qi as listDelegatedContexts,Bi as listDelegatedNamespaces,Ts as localNodeUrl,Ue as login,gn as markContextNonceSpent,Pe as memberAddedOp,en as memberCapabilitySetOp,sn as memberJoinedOpenOp,ot as memberLeftOp,rn as memberMetadataSetOp,Wt as memberRemovedOp,Jt as memberRoleSetOp,wo as mintDeviceId,Zt as namespaceCreatedOp,yt as namespaceOfGroup,Ds as nodeEndpoint,ci as nodeReleaseVersionFromImage,dt as normaliseAccount,zr as ownerOpDigest,Qr as ownerOpSigningPayload,jn as parseAuthCallback,fi as parseCreationWarrant,Qn as parseDeviceCredential,yi as parseGovernanceWarrant,eo as parseWarrantNonce,Nr as persistedNonces,Ur as pinRelayNodeKey,Er as presenceStatementBytes,Ns as probeNodeHealth,dl as readCloudLinkCallback,Ni as readDelegatedCredential,Dr as readDelegatedSession,bl as readEnrolmentCallback,mn as readPinnedRelayNodeKey,B as readRelayMap,Zr as redeemInvitation,Ki as relayForContext,ft as rememberGroupNamespace,me as rememberRelay,nr as reportDataOf,Vn as requestBodyHash,os as resolveApplicationIdFromRegistry,vn as resolveRelayFromInvitation,fn as resolveRelayNodeKey,Y as resolveRoot,Dt as resolveRootPair,Is as rootGuardedOpBytes,xn as routingProofHeaders,Ui as saveDelegatedCredential,Ti as saveDelegatedSession,gt as selectLatestBundle,Iu as shouldRetain,zn as signAccountHaClaim,Je as signAccountLink,Nt as signAccountLogin,na as signAccountOwnershipClaim,Ft as signCreationWarrant,xo as signDeviceCert,vo as signDeviceScope,nt as signGovernanceWarrant,Cn as signGroupInvitation,cn as signLoginStatement,kn as signMemberJoinOp,Es as signOwnerOpProof,vt as signRequest,Sr as signRequestProof,Fi as signRoutingChallenge,Bt as signWarrant,Lc as signedPath,uo as signerFromCryptoKey,xe as signerFromSecret,ki as stateHash,De as subgroupCreation,nn as subgroupVisibilitySetOp,Et as subscribePresence,zt as targetApplicationSetOp,Cs as teeAdmissionPolicyOp,Rs as teeAuthoringPolicyOp,Ss as teeReleaseAdmissionPolicyOp,As as transferOwnershipOp,Wo as transportKeyBinding,di as trustSignedRelease,cr as trustedMeasurementsFromReleases,Pt as verifyDeviceCredential,ai as verifySignedNodeRelease,Ln as withCap,wt as withRetry,Cu as withoutCap};
3
3
  //# sourceMappingURL=index.browser.mjs.map