@calimero-network/mero-js 22.1.0 → 22.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -5
- package/dist/cloud/cloud-client.d.ts +44 -14
- package/dist/cloud/cloud-client.js +82 -37
- package/dist/cloud/connect.d.ts +2 -1
- package/dist/cloud/connect.js +23 -12
- package/dist/index.browser.mjs +2 -2
- package/dist/index.browser.mjs.map +3 -3
- package/dist/index.cjs +113 -45
- package/dist/index.cjs.map +2 -2
- package/dist/index.mjs +113 -45
- package/dist/index.mjs.map +2 -2
- package/dist/sealed/release.d.ts +16 -4
- package/dist/sealed/release.js +35 -5
- package/package.json +1 -1
package/dist/index.browser.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
function _e(n){let e=n.filter(Boolean);if(e.length===0)return;let t=AbortSignal;if(typeof t.any=="function")try{return t.any(e)}catch{}let r=new AbortController,s=i=>{r.abort(i.target.reason);for(let a of e)a.removeEventListener("abort",s)};for(let i of e){if(i.aborted)return AbortSignal.abort(i.reason);i.addEventListener("abort",s,{once:!0})}return r.signal}function qe(n){if(typeof AbortSignal.timeout=="function")return AbortSignal.timeout(n);let e=new AbortController;return setTimeout(()=>{e.abort(new DOMException("Timeout","TimeoutError"))},n),e.signal}var Mn=new Set(["token_reuse","token_revoked"]);function Nn(n){if(n)try{let e=JSON.parse(n),t=e?.error;if(typeof t=="string"&&t.trim()!=="")return t;let r=t?.message;if(typeof r=="string"&&r.trim()!=="")return r;let s=e?.detail;if(typeof s=="string"&&s.trim()!=="")return s}catch{}}var v=class extends Error{constructor(t,r,s,i,a){let o=Nn(a)??(t===0&&a?.trim()?a.trim():void 0);super(o?`HTTP ${t} ${r}: ${o}`:`HTTP ${t} ${r}`);this.status=t;this.statusText=r;this.url=s;this.headers=i;this.bodyText=a;this.name="HTTPError";this.explanation=o}toJSON(){return{status:this.status,statusText:this.statusText,url:this.url,headers:yt(this.headers),bodyText:this.bodyText}}},_=class extends v{constructor(t,r,s,i,a,o){super(r,s,i,a,o);this.reason=t;this.name="AuthRevokedError";this.message=`Authentication revoked (${t}): HTTP ${r} ${s}`}};function yt(n){let e={};return n.forEach((t,r)=>{e[r]=t}),e}function _n(n){try{return new URL(n).pathname}catch{let e=n.indexOf("?");return e===-1?n:n.slice(0,e)}}var ee=class{constructor(e){this.transport=e;this.refreshTokenPromise=null;this.onTokenRefreshPromise=null}async get(e,t){return this.request(e,{...t,method:"GET"})}async post(e,t,r){return this.request(e,{...r,method:"POST",body:t?JSON.stringify(t):void 0,headers:{"Content-Type":"application/json",...r?.headers}})}async put(e,t,r){return this.request(e,{...r,method:"PUT",body:t?JSON.stringify(t):void 0,headers:{"Content-Type":"application/json",...r?.headers}})}async delete(e,t){return this.request(e,{...t,method:"DELETE"})}async patch(e,t,r){return this.request(e,{...r,method:"PATCH",body:t?JSON.stringify(t):void 0,headers:{"Content-Type":"application/json",...r?.headers}})}async head(e,t){let r=await this.makeRequest(e,{...t,method:"HEAD",parse:"response"});return{headers:yt(r.headers),status:r.status}}async request(e,t){return this.makeRequest(e,t)}async makeRequest(e,t,r=0,s){let a=this.buildUrl(e),o=s??Date.now(),c=this.createAbortSignal(t),l=await this.buildHeaders(t?.headers),p;l instanceof Headers?(p={},l.forEach((g,R)=>{p[R]=g})):p=l;let d={method:t?.method||"GET",headers:p},m=t?.body instanceof ReadableStream||typeof t?.body=="object"&&t?.body!==null&&"getReader"in t.body&&!(t.body instanceof Blob);(t?.body!==void 0&&!m||t?.body!==void 0&&m&&r===0)&&(d.body=t.body);let f;if(r>0&&s!==void 0){let g=t?.timeoutMs||this.transport.timeoutMs;if(g){let R=Date.now()-o,C=Math.max(0,g-R);f=this.createAbortSignal({...t,timeoutMs:C})}else f=this.createAbortSignal(t)}else f=c;if(f&&(d.signal=f),this.transport.credentials!==void 0&&(d.credentials=this.transport.credentials),t?.mode!==void 0&&(d.mode=t.mode),t?.cache!==void 0&&(d.cache=t.cache),t?.redirect!==void 0&&(d.redirect=t.redirect),t?.referrer!==void 0&&(d.referrer=t.referrer),t?.referrerPolicy!==void 0&&(d.referrerPolicy=t.referrerPolicy),t?.integrity!==void 0&&(d.integrity=t.integrity),t?.keepalive!==void 0&&(d.keepalive=t.keepalive),this.transport.getProof){let g=await this.transport.getProof({method:d.method??"GET",path:_n(a),body:d.body});g&&(p["X-Calimero-Proof"]=g)}try{let g=await this.transport.fetch(a,d);if(!g.ok){let R=await this.getBodyText(g),C=new v(g.status,g.statusText,a,g.headers,R),A=g.headers.get("x-auth-error");if((g.status===401||g.status===403)&&A&&Mn.has(A)){if(this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,this.transport.onAuthRevoked)try{await this.transport.onAuthRevoked()}catch{}throw new _(A,g.status,g.statusText,a,g.headers,R)}let x=t?.signal?.aborted===!0;if(g.status===401&&this.transport.refreshToken&&A==="token_expired"&&r<1&&!m&&!x)try{let T=this.refreshTokenPromise;T||(T=this.transport.refreshToken(),this.refreshTokenPromise=T);let H=await T;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 E=this.onTokenRefreshPromise;E||(E=this.transport.onTokenRefresh(H),this.onTokenRefreshPromise=E),await E,this.refreshTokenPromise=null,this.onTokenRefreshPromise=null;let N=t?.timeoutMs||this.transport.timeoutMs;if(N&&s!==void 0){let B=Date.now()-o;if(N-B<=0)throw C}return this.makeRequest(e,t,r+1,o)}catch(T){throw this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,T instanceof Error&&T.message.includes("onTokenRefresh")?T:C}throw C}return this.parseResponse(g,t?.parse)}catch(g){throw g instanceof v||g instanceof Error&&g.message.includes("onTokenRefresh")?g:new v(0,"Network Error",a,new Headers,g instanceof Error?g.message:"Unknown error")}}buildUrl(e){if(e.startsWith("http://")||e.startsWith("https://"))return e;let t=this.transport.baseUrl;return e.startsWith("/")?`${t.endsWith("/")?t.slice(0,-1):t}${e}`:`${t.endsWith("/")?t:`${t}/`}${e}`}createAbortSignal(e){let t=[];this.transport.defaultAbortSignal&&t.push(this.transport.defaultAbortSignal),e?.signal&&t.push(e.signal);let r=e?.timeoutMs||this.transport.timeoutMs;return r&&t.push(qe(r)),t.length>0?_e(t):void 0}async buildHeaders(e){let t={...this.transport.defaultHeaders};if(this.transport.getAuthToken)try{let r=await this.transport.getAuthToken();r&&r.trim()!==""&&(t.Authorization=`Bearer ${r}`)}catch{}return e&&(e instanceof Headers?e.forEach((r,s)=>{t[s]=r}):Array.isArray(e)?e.forEach(([r,s])=>{t[r]=s}):Object.assign(t,e)),t}async parseResponse(e,t){switch(t){case"text":return await e.text();case"blob":return await e.blob();case"arrayBuffer":return await e.arrayBuffer();case"response":return e;default:{let r=await e.text();if(!r)return null;try{return JSON.parse(r)}catch{throw new Error(`Expected a JSON response (status ${e.status}) but body was not JSON: ${r.slice(0,200)}`)}}}}async getBodyText(e){try{let t=await e.text();return t.length>65536?t.slice(0,65536)+"...":t}catch{return""}}};function He(n){return new ee(n)}function F(n){let e={fetch:(t,r)=>n.fetch?n.fetch(t,r):globalThis.fetch(t,r),baseUrl:n.baseUrl,getAuthToken:n.getAuthToken,getProof:n.getProof,onTokenRefresh:n.onTokenRefresh,refreshToken:n.refreshToken,onAuthRevoked:n.onAuthRevoked,defaultHeaders:n.defaultHeaders,timeoutMs:n.timeoutMs,credentials:n.credentials,defaultAbortSignal:n.defaultAbortSignal};return He(e)}function ge(n){let e=n.fetch??globalThis.fetch;if(!e)throw new Error("No fetch implementation available. Please provide a fetch implementation (e.g., undici.fetch) or use Node.js 18+ which has native fetch support.");let r={fetch:e===globalThis.fetch?(s,i)=>globalThis.fetch(s,i):(s,i)=>e(s,i),baseUrl:n.baseUrl,getAuthToken:n.getAuthToken,getProof:n.getProof,onTokenRefresh:n.onTokenRefresh,refreshToken:n.refreshToken,onAuthRevoked:n.onAuthRevoked,defaultHeaders:n.defaultHeaders,timeoutMs:n.timeoutMs,credentials:n.credentials,defaultAbortSignal:n.defaultAbortSignal};return He(r)}function Ge(n){return typeof window<"u"?F(n):ge(n)}function qn(n,e){if(e<=0)return!1;let r=n?.name;if(r==="TimeoutError")return!0;if(r==="AbortError")return!1;let s=n;if("status"in s&&typeof s.status=="number"){let i=s.status;return i>=500||i===429}return r==="TypeError"}function Hn(n){let t=250*Math.pow(2,n-1),r=(Math.random()-.5)*.4*t;return Math.max(0,t+r)}async function me(n,e={}){let{attempts:t=3}=e,r;for(let s=1;s<=t;s++)try{return await n(s)}catch(i){if(r=i,!qn(r,t-s))throw r;let a=Hn(s),l=r.headers?.get?.("Retry-After");if(l){let p=parseInt(l,10);if(!isNaN(p))a=Math.max(a,p*1e3);else{let d=new Date(l);if(!isNaN(d.getTime())){let m=Math.max(0,d.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 Gn(n,e={}){return async(...t)=>me(()=>n(...t),e)}var G=class{constructor(e){this.httpClient=e}async getHealth(){let e=await this.httpClient.get("/auth/health");if(!e.data)throw new Error("Health response data is null");return e.data}async getIdentity(){let e=await this.httpClient.get("/admin/identity");if(!e.data)throw new Error("Identity response data is null");return e.data}async getProviders(){let e=await this.httpClient.get("/auth/providers");if(!e.data)throw new Error("Providers response data is null");return e.data}async getLoginPage(){return this.httpClient.get("/auth/login",{parse:"text"})}async generateTokens(e){return this.httpClient.post("/auth/token",e)}async refreshToken(e){return this.httpClient.post("/auth/refresh",e)}async generateMockTokens(e){return this.httpClient.post("/auth/mock-token",e)}async validateToken(e){try{let t=await this.validateTokenGet(e);return{valid:t.status===200,headers:t.headers,status:t.status}}catch{return{valid:!1,headers:{},status:401}}}async validateTokenGet(e){let t=await this.httpClient.head("/auth/validate",{headers:{Authorization:`Bearer ${e}`}});return{status:t.status,headers:t.headers}}async revokeTokens(e){let t=await this.httpClient.post("/admin/revoke",e);if(!t.data)throw new Error("Revoke tokens response data is null");return t.data}async listRootKeys(){let e=await this.httpClient.get("/admin/keys");if(!e.data)throw new Error("Root keys response data is null");return e.data}async createRootKey(e){let t=await this.httpClient.post("/admin/keys",e);if(!t.data)throw new Error("Create root key response data is null");return t.data}async deleteRootKey(e){return this.httpClient.delete(`/admin/keys/${e}`)}async listClientKeys(){let e=await this.httpClient.get("/admin/keys/clients");if(!e.data)throw new Error("Client keys response data is null");return e.data}async generateClientKey(e){return this.httpClient.post("/admin/client-key",e)}async deleteClientKey(e,t){return this.httpClient.delete(`/admin/keys/${e}/clients/${t}`)}async getKeyPermissions(e){return this.httpClient.get(`/admin/keys/${e}/permissions`)}async updateKeyPermissions(e,t){return this.httpClient.put(`/admin/keys/${e}/permissions`,{add:t.add,remove:t.remove})}};var te=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 Js(n){let e=new te;return new G(e)}function zs(n){let e=new te;return new G(e)}function Qs(n){let e=new te;return new G(e)}function bt(n,e){return new G(n)}var ne={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};function Oe(n,e){let t=e>>>0;return(n&t)>>>0===t}function Le(n,e){return(n|e)>>>0}function Xs(n,e){return(n&~e)>>>0}var On={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 Ln(n){switch(n){case 0:return"unreachable";case 400:return"invalid";case 401:return"unauthorized";case 403:return"forbidden";case 404:return"not-found";case 409:return"conflict";case 410:return"gone";case 413:return"too-large";case 429:return"rate-limited";case 503:case 504:return"unavailable"}return n>=500&&n<600?"server":n>=400&&n<500?"invalid":"unknown"}function $n(n){if(!n||typeof n!="object")return;let e=n;for(let t of[e.status,e.response?.status,e.statusCode])if(typeof t=="number"&&Number.isFinite(t))return t}function $e(n,e="Request failed"){if(typeof n=="string")return n.trim()||e;if(!n||typeof n!="object")return e;let t=n;for(let r of[t.explanation,t.response?.data?.error,t.response?.data?.message,t.data?.message,t.error,t.message])if(typeof r=="string"&&r.trim())return r;return e}function Be(n){let e=$n(n),t;return e!==void 0?t=Ln(e):n instanceof TypeError?t="unreachable":t="unknown",{kind:t,status:e,retryable:On[t],message:$e(n)}}function Bn(n){return n.status!=="failed"||!n.retryable}function ni(n){return!Bn(n)}function Kn(n){let e=n.toLowerCase();return e.includes("invitation has expired")||e.includes("invitation expired")||/\binvitation for group .+? expired at \d+/.test(e)?"expired":e.includes("malformed")||e.includes("does not match namespace_id")||e.includes("invalid invitation")||/\binvitation for group .+? is invalid:/.test(e)?"invalid":null}function jn(n,e){let{kind:t,status:r}=Be(n),s=Kn(e);return r===401?{reason:"signed-out",retryable:!0}:r===400?{reason:s??"invalid",retryable:!1}:r===410?{reason:"expired",retryable:!1}:r===403?{reason:"refused",retryable:!1}:r===409?{reason:s??"refused",retryable:!1}:t==="unavailable"?{reason:"no-one-online",retryable:!0}:t==="unreachable"?{reason:"node-unreachable",retryable:!0}:s?{reason:s,retryable:!1}:{reason:"unknown",retryable:!0}}async function wt(n,e){let{namespaceId:t,invitation:r,teamName:s}=n,i=null;try{await e.join(t,r)}catch(p){i=p}let a=null;try{a=(await e.memberships()).includes(t)}catch{a=null}if(i===null)return{status:"joined",namespaceId:t,teamName:s};if(a===!0)return{status:"already-member",namespaceId:t,teamName:s};let o=$e(i,"Could not join. Check the invitation."),{reason:c,retryable:l}=jn(i,o);return{status:"failed",namespaceId:t,message:o,reason:c,retryable:l}}function u(n){return n?.data}function Vn(n,e){let[t,r]=Rt(n),[s,i]=Rt(e),a=t.split("."),o=s.split("."),c=Math.max(a.length,o.length);for(let m=0;m<c;m++){let f=At(a[m]??"0",o[m]??"0");if(f!==0)return f}if(r===void 0&&i===void 0)return 0;if(r===void 0)return 1;if(i===void 0)return-1;let l=r.split("."),p=i.split("."),d=Math.max(l.length,p.length);for(let m=0;m<d;m++){if(m>=l.length)return-1;if(m>=p.length)return 1;let f=At(l[m],p[m]);if(f!==0)return f}return 0}function Rt(n){let e=n.split("+",1)[0],t=e.indexOf("-");return t===-1?[e,void 0]:[e.slice(0,t),e.slice(t+1)]}function At(n,e){let t=/^\d+$/.test(n),r=/^\d+$/.test(e);if(t&&r){let s=Number(n)-Number(e);return s<0?-1:s>0?1:0}return t?-1:r?1:n<e?-1:n>e?1:0}async function Fn(n,e,t){return me(async()=>{let r=await fetch(n,{signal:AbortSignal.timeout(1e4)});if(!r.ok){let s=new Error(`registry ${e} fetch failed (${r.status}) for ${t}`);throw s.status=r.status,s}return r},{attempts:3})}var O=class{constructor(e){this.httpClient=e}async healthCheck(){return u(await this.httpClient.get("/admin-api/health"))}async readinessCheck(){return u(await this.httpClient.get("/admin-api/ready"))}async isAuthed(){return this.httpClient.get("/admin-api/is-authed")}async installApplication(e){return u(await this.httpClient.post("/admin-api/install-application",e))}async getRegistryVersions(e,t){let r=new URL("/api/v2/bundles",new URL(e).origin);r.searchParams.set("package",t);let i=await(await Fn(r.toString(),"versions",t)).json();return(Array.isArray(i)?i:[]).map(a=>a.appVersion).filter(a=>typeof a=="string").sort((a,o)=>Vn(o,a))}async installDevApplication(e){return u(await this.httpClient.post("/admin-api/install-dev-application",e))}async uninstallApplication(e){return u(await this.httpClient.delete(`/admin-api/applications/${e}`))}async listApplications(){return u(await this.httpClient.get("/admin-api/applications"))}async getApplication(e){return u(await this.httpClient.get(`/admin-api/applications/${e}`))}async listApplicationVersions(e){return u(await this.httpClient.get(`/admin-api/applications/${e}/versions`))}async getApplicationAbi(e,t){let r=t?`?service_name=${encodeURIComponent(t)}`:"";return u(await this.httpClient.get(`/admin-api/applications/${e}/abi${r}`))}async listPackages(){let e=await this.httpClient.get("/admin-api/packages");return e?.data??e}async listPackageVersions(e){let t=await this.httpClient.get(`/admin-api/packages/${encodeURIComponent(e)}/versions`);return t?.data??t}async getLatestPackageVersion(e){return this.httpClient.get(`/admin-api/packages/${encodeURIComponent(e)}/latest`)}async createContext(e){let t={...e,initializationParams:e.initializationParams??[]};return u(await this.httpClient.post("/admin-api/contexts",t))}async deleteContext(e){return u(await this.httpClient.delete(`/admin-api/contexts/${e}`))}async getContexts(){return u(await this.httpClient.get("/admin-api/contexts"))}async getContext(e){return u(await this.httpClient.get(`/admin-api/contexts/${e}`))}async getContextsForApplication(e){return u(await this.httpClient.get(`/admin-api/contexts/for-application/${e}`))}async generateContextIdentity(){return u(await this.httpClient.post("/admin-api/identity/context",{}))}async getContextIdentities(e){return u(await this.httpClient.get(`/admin-api/contexts/${e}/identities`))}async getContextIdentitiesOwned(e){return u(await this.httpClient.get(`/admin-api/contexts/${e}/identities-owned`))}async joinContext(e){return u(await this.httpClient.post(`/admin-api/contexts/${e}/join`,{}))}async getContextGroup(e){return u(await this.httpClient.get(`/admin-api/contexts/${e}/group`))}async getContextStorage(e){return u(await this.httpClient.get(`/admin-api/contexts/${e}/storage`))}async syncContext(e){let t=e?`/admin-api/contexts/sync/${e}`:"/admin-api/contexts/sync";await this.httpClient.post(t,{})}async resyncContext(e,t={}){return await this.httpClient.post(`/admin-api/contexts/${e}/resync`,t)??{contextId:e,resyncStarted:!0}}async inviteSpecializedNode(e){return u(await this.httpClient.post("/admin-api/contexts/invite-specialized-node",e))}async updateContextApplication(e,t){await this.httpClient.post(`/admin-api/contexts/${e}/application`,t)}async getContextsWithExecutorsForApplication(e){let t=await this.httpClient.get(`/admin-api/contexts/with-executors/for-application/${e}`);return Array.isArray(t)?t:t?.contexts??t?.data??[]}async uploadBlob(e){let t=new URLSearchParams;e.hash&&t.set("hash",e.hash),e.contextId&&t.set("context_id",e.contextId);let r=t.toString(),s=r?`/admin-api/blobs?${r}`:"/admin-api/blobs",i=u(await this.httpClient.request(s,{method:"PUT",body:e.data,headers:{"Content-Type":"application/octet-stream"}}));return{blobId:i.blob_id,size:i.size}}async deleteBlob(e){let t=await this.httpClient.delete(`/admin-api/blobs/${e}`);return{blobId:t.blob_id,deleted:t.deleted}}async listBlobs(){return{blobs:u(await this.httpClient.get("/admin-api/blobs")).blobs.map(t=>({blobId:t.blob_id,size:t.size}))}}blobPath(e,t){if(!t?.contextId)return`/admin-api/blobs/${e}`;let r=new URLSearchParams({context_id:t.contextId});return`/admin-api/blobs/${e}?${r.toString()}`}async getBlob(e,t){return this.httpClient.get(this.blobPath(e,t),{parse:"arrayBuffer"})}async getBlobInfo(e,t){let{headers:r}=await this.httpClient.head(this.blobPath(e,t)),s=Number(r["content-length"]);return{blobId:r["x-blob-id"]??e,size:Number.isFinite(s)?s:0,hash:r["x-blob-hash"],mimeType:r["x-blob-mime-type"],source:r["x-blob-source"]}}async createContextAlias(e){return u(await this.httpClient.post("/admin-api/alias/create/context",{alias:e.alias,contextId:e.contextId}))}async createApplicationAlias(e){return u(await this.httpClient.post("/admin-api/alias/create/application",{alias:e.alias,applicationId:e.applicationId}))}async lookupContextAlias(e){return u(await this.httpClient.post(`/admin-api/alias/lookup/context/${encodeURIComponent(e)}`,{}))}async lookupApplicationAlias(e){return u(await this.httpClient.post(`/admin-api/alias/lookup/application/${encodeURIComponent(e)}`,{}))}async deleteContextAlias(e){return u(await this.httpClient.post(`/admin-api/alias/delete/context/${encodeURIComponent(e)}`,{}))}async deleteApplicationAlias(e){return u(await this.httpClient.post(`/admin-api/alias/delete/application/${encodeURIComponent(e)}`,{}))}async listContextAliases(){return u(await this.httpClient.get("/admin-api/alias/list/context"))}async listApplicationAliases(){return u(await this.httpClient.get("/admin-api/alias/list/application"))}async createDeviceAlias(e){return u(await this.httpClient.post("/admin-api/alias/create/device",{alias:e.alias,deviceId:e.deviceId}))}async lookupDeviceAlias(e){return u(await this.httpClient.post(`/admin-api/alias/lookup/device/${encodeURIComponent(e)}`,{}))}async deleteDeviceAlias(e){return u(await this.httpClient.post(`/admin-api/alias/delete/device/${encodeURIComponent(e)}`,{}))}async listDeviceAliases(){return u(await this.httpClient.get("/admin-api/alias/list/device"))}async listNamespaces(){return u(await this.httpClient.get("/admin-api/namespaces"))}async getNamespace(e){return u(await this.httpClient.get(`/admin-api/namespaces/${e}`))}async getNodeIdentity(){return u(await this.httpClient.get("/admin-api/identity"))}async getNamespaceIdentity(e){let t=await this.getNodeIdentity();return{namespaceId:e,publicKey:t.publicKey,account:t.accountId}}async performIntent(e,t){return u(await this.httpClient.post(`/admin-api/contexts/${e}/intents`,t))}async queryContext(e,t){return u(await this.httpClient.post(`/admin-api/contexts/${e}/query`,t))}async getIntentRelay(e){return u(await this.httpClient.get(`/admin-api/contexts/${e}/intents`))}async listNamespacesForApplication(e){return u(await this.httpClient.get(`/admin-api/namespaces/for-application/${e}`))}async createNamespace(e){return u(await this.httpClient.post("/admin-api/namespaces",e))}async deleteNamespace(e){return u(await this.httpClient.request(`/admin-api/namespaces/${e}`,{method:"DELETE",body:"{}",headers:{"Content-Type":"application/json"}}))}async createNamespaceInvitation(e,t){return u(await this.httpClient.post(`/admin-api/namespaces/${e}/invite`,t??{}))}async admitJoin(e,t){return u(await this.httpClient.post(`/admin-api/namespaces/${e}/admit`,t,{timeoutMs:65e3}))}async joinNamespace(e,t){let r=u(await this.httpClient.post(`/admin-api/namespaces/${e}/join`,t,{timeoutMs:65e3}));return r&&r.namespaceId===void 0&&r.groupId!==void 0?{...r,namespaceId:r.groupId}:r}async redeemInvitation(e,t,r={}){let{groupName:s,teamName:i}=r;return wt({namespaceId:e,invitation:t,teamName:i},{join:async()=>{await this.joinNamespace(e,s===void 0?{invitation:t}:{invitation:t,groupName:s})},memberships:async()=>(await this.listNamespaces()??[]).map(a=>a.namespaceId)})}async createGroupInNamespace(e,t){return u(await this.httpClient.post(`/admin-api/namespaces/${e}/groups`,t??{}))}async listNamespaceGroups(e){return u(await this.httpClient.get(`/admin-api/namespaces/${e}/groups`))}async initAccountPairing(e){return u(await this.httpClient.post("/admin-api/account/pair-init",e))}async completeAccountPairing(e){return u(await this.httpClient.post("/admin-api/account/pair-complete",e))}async relinkAccountDevice(e,t){return u(await this.httpClient.post(`/admin-api/account/devices/${e}/relink`,t??{}))}async rescopeAccountDevice(e,t){return u(await this.httpClient.put(`/admin-api/account/devices/${encodeURIComponent(e)}/scope`,t))}async signWithAccountRoot(e){return u(await this.httpClient.post("/admin-api/account/sign-with-root",e))}async labelAccountDevice(e,t){return u(await this.httpClient.put(`/admin-api/account/devices/${encodeURIComponent(e)}/label`,t))}async listAccountDevices(){return(await this.httpClient.get("/admin-api/account/devices")).devices}async listAccountApplications(){return(await this.httpClient.get("/admin-api/account/applications")).applications}async revokeAccountDevice(e,t){return u(await this.httpClient.post(`/admin-api/namespaces/${e}/account/revoke`,t))}async getGroupInfo(e){return u(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 u(await this.httpClient.request(`/admin-api/groups/${e}`,{method:"DELETE",body:"{}",headers:{"Content-Type":"application/json"}}))}async listGroupMembers(e){let t=await this.httpClient.get(`/admin-api/groups/${e}/members`);if(!Array.isArray(t?.members)){let r=String(e).replace(/[\r\n\t\s]/g,"").slice(0,64);throw new Error(`Invalid listGroupMembers response for group ${r}: missing or non-array \`members\` field`)}return t}async listMemberDevices(e,t={}){let r=new URLSearchParams;t.offset!==void 0&&r.set("offset",String(t.offset)),t.limit!==void 0&&r.set("limit",String(t.limit));let s=r.toString(),i=`/admin-api/groups/${e}/member-devices${s?`?${s}`:""}`;return this.httpClient.get(i)}async sealToAccount(e,t,r){return u(await this.httpClient.post(`/admin-api/groups/${e}/accounts/${t}/seal`,r))}async listGroupContexts(e){return u(await this.httpClient.get(`/admin-api/groups/${e}/contexts`))}async addGroupMembers(e,t){await this.httpClient.post(`/admin-api/groups/${e}/members`,t)}async removeGroupMembers(e,t){await this.httpClient.post(`/admin-api/groups/${e}/members/remove`,t)}async updateMemberRole(e,t,r){await this.httpClient.put(`/admin-api/groups/${e}/members/${t}/role`,r)}async getMemberCapabilities(e,t){return u(await this.httpClient.get(`/admin-api/groups/${e}/members/${t}/capabilities`))}async setMemberCapabilities(e,t,r){await this.httpClient.put(`/admin-api/groups/${e}/members/${t}/capabilities`,r)}async setDefaultCapabilities(e,t){await this.httpClient.put(`/admin-api/groups/${e}/settings/default-capabilities`,t)}async openToDelegatedExecution(e){let t=await this.getDefaultCapabilities(e);if(Oe(t,ne.CAN_AUTHOR_ON_BEHALF))return{changed:!1,defaultCapabilities:t};let r=Le(t,ne.CAN_AUTHOR_ON_BEHALF);return await this.setDefaultCapabilities(e,{defaultCapabilities:r}),{changed:!0,defaultCapabilities:r}}async grantAuthorship(e,t){let{capabilities:r}=await this.getMemberCapabilities(e,t);if(Oe(r,ne.CAN_AUTHOR_ON_BEHALF))return{changed:!1,capabilities:r};let s=Le(r,ne.CAN_AUTHOR_ON_BEHALF);return await this.setMemberCapabilities(e,t,{capabilities:s}),{changed:!0,capabilities:s}}async setSubgroupVisibility(e,t){await this.httpClient.put(`/admin-api/groups/${e}/settings/subgroup-visibility`,t)}async setTeeAdmissionPolicy(e,t){await this.httpClient.put(`/admin-api/groups/${e}/settings/tee-admission-policy`,t)}async getTeeAdmissionPolicy(e){let t=await this.httpClient.get(`/admin-api/groups/${e}/settings/tee-admission-policy`);return t.data??t}async setTeeAuthoringPolicy(e,t){await this.httpClient.put(`/admin-api/groups/${e}/settings/tee-authoring-policy`,t)}async disableTeeAuthoringPolicy(e){await this.httpClient.delete(`/admin-api/groups/${e}/settings/tee-authoring-policy`)}async setGroupMetadata(e,t){await this.httpClient.put(`/admin-api/groups/${e}/metadata`,t)}async getGroupMetadata(e){return(await this.httpClient.get(`/admin-api/groups/${e}/metadata`))?.data??null}async setMemberMetadata(e,t,r){await this.httpClient.put(`/admin-api/groups/${e}/members/${t}/metadata`,r)}async getMemberMetadata(e,t){return(await this.httpClient.get(`/admin-api/groups/${e}/members/${t}/metadata`))?.data??null}async setContextMetadata(e,t,r){await this.httpClient.put(`/admin-api/groups/${e}/contexts/${t}/metadata`,r)}async getContextMetadata(e,t){return(await this.httpClient.get(`/admin-api/groups/${e}/contexts/${t}/metadata`))?.data??null}async syncGroup(e){return u(await this.httpClient.post(`/admin-api/groups/${e}/sync`,{}))}async upgradeGroup(e,t){return u(await this.httpClient.post(`/admin-api/groups/${e}/upgrade`,t))}async getGroupUpgradeStatus(e){return u(await this.httpClient.get(`/admin-api/groups/${e}/upgrade/status`))}async getMigrationStatus(e){let t=encodeURIComponent(e);return this.httpClient.get(`/admin-api/groups/${t}/migration-status`)}async getCascadeStatus(e){let t=encodeURIComponent(e);return u(await this.httpClient.get(`/admin-api/groups/${t}/cascade-status`))}async retryGroupUpgrade(e){return u(await this.httpClient.post(`/admin-api/groups/${e}/upgrade/retry`,{}))}async reparentGroup(e,t){let r=await this.httpClient.post(`/admin-api/groups/${e}/reparent`,t);return r?.data??r}async listSubgroups(e){let t=await this.httpClient.get(`/admin-api/groups/${e}/subgroups`);return t.subgroups??t.data??[]}async detachContextFromGroup(e,t){await this.httpClient.post(`/admin-api/groups/${e}/contexts/${t}/remove`,{})}async createGroupInvitation(e,t){return u(await this.httpClient.post(`/admin-api/groups/${e}/invite`,t??{}))}async joinGroup(e){return u(await this.httpClient.post("/admin-api/groups/join",e))}async joinSubgroupInheritance(e){return u(await this.httpClient.post(`/admin-api/groups/${e}/join-via-inheritance`,{}))}async getTeeInfo(){return u(await this.httpClient.get("/admin-api/tee/info"))}async teeAttest(e){return u(await this.httpClient.post("/admin-api/tee/attest",e))}async teeVerifyQuote(e){return u(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 u(await this.httpClient.post("/admin-api/groups",e))}async leaveGroup(e){await this.httpClient.post(`/admin-api/groups/${e}/leave`,{})}async leaveContext(e){await this.httpClient.post(`/admin-api/contexts/${e}/leave`,{})}async leaveNamespace(e){await this.httpClient.post(`/admin-api/namespaces/${e}/leave`,{})}async issueOwnershipProof(e,t){return this.httpClient.post(`/admin-api/groups/${e}/issue-ownership-proof`,t)}async issueNamespaceOwnershipProof(e,t){return this.httpClient.post(`/admin-api/groups/${e}/issue-namespace-ownership-proof`,t)}async setMemberAutoFollow(e,t,r){await this.httpClient.put(`/admin-api/groups/${e}/members/${t}/auto-follow`,r)}async abortMigration(e){return this.httpClient.post(`/admin-api/groups/${e}/migration/abort`,{})}};function li(n){return Array.from(new TextEncoder().encode(n),e=>e.toString(16).padStart(2,"0")).join("")}function mi(n){return new O(F(n))}function hi(n){return new O(ge(n))}function fi(n){return new O(Ge(n))}function xt(n,e){return new O(n)}function Ke(n){try{let e=n.indexOf("#");if(e===-1)return null;let t=n.substring(e+1),r=new URLSearchParams(t),s=r.get("access_token");return s?{accessToken:s,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 je(n,e){let t=new URLSearchParams;return t.set("callback-url",e.callbackUrl),e.permissions&&e.permissions.length>0&&t.set("permissions",e.permissions.join(",")),t.set("mode",e.mode),e.packageName&&(t.set("package-name",e.packageName),e.packageVersion&&t.set("package-version",e.packageVersion),e.registryUrl&&t.set("registry-url",e.registryUrl)),`${n.replace(/\/+$/,"")}/auth/login?${t.toString()}`}var Ct=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,112,4,34,4,32]);function k(n){let e=new Uint8Array(4);return new DataView(e.buffer).setUint32(0,n,!0),e}function b(n){return Array.from(n,e=>e.toString(16).padStart(2,"0")).join("")}function y(n,e,t){let r=n.trim();if(!/^[0-9a-fA-F]*$/.test(r)||r.length!==t*2)throw new Error(`${e} must be ${t*2} hex characters, got ${r.length}`);let s=new Uint8Array(t);for(let i=0;i<t;i+=1)s[i]=Number.parseInt(r.slice(i*2,i*2+2),16);return s}function he(n,e){let t=n.trim();if(!/^[0-9a-fA-F]*$/.test(t)||t.length%2!==0)throw new Error(`${e} must be an even number of hex characters`);let r=new Uint8Array(t.length/2);for(let s=0;s<r.length;s+=1)r[s]=Number.parseInt(t.slice(s*2,s*2+2),16);return r}function S(n){let e=new Uint8Array(8);return new DataView(e.buffer).setBigUint64(0,BigInt(n),!0),e}function h(...n){let e=new Uint8Array(n.reduce((r,s)=>r+s.length,0)),t=0;for(let r of n)e.set(r,t),t+=r.length;return e}async function U(n,e){let t=[S(n.length),n];for(let r of e)t.push(S(r.length),r);return new Uint8Array(await crypto.subtle.digest("SHA-256",h(...t)))}async function I(n){let e=y(n,"deviceSecret",32),t=h(Ct,e);try{return await crypto.subtle.importKey("pkcs8",t,{name:"Ed25519"},!1,["sign"])}catch(r){let s=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`"+s)}}async function P(n){let e=y(n,"deviceSecret",32),t=h(Ct,e),r=await crypto.subtle.importKey("pkcs8",t,{name:"Ed25519"},!0,["sign"]),i=(await crypto.subtle.exportKey("jwk",r)).x;return Uint8Array.from(atob(i.replace(/-/g,"+").replace(/_/g,"/")),a=>a.charCodeAt(0))}var Wn=new TextEncoder().encode("calimero.auth.request.v1"),Jn=new TextEncoder().encode("calimero.auth.request.body.v1");function vt(n){let e=new TextEncoder().encode(n);return h(k(e.length),e)}async function Ve(n=new Uint8Array(0)){let e=typeof n=="string"?new TextEncoder().encode(n):n;return U(Jn,[e])}async function fe(n){let e=await I(n.signerSecret),t=await Ve(n.body),r=S(n.issuedAt),s=S(n.expiresAt),i=new TextEncoder,a=await U(Wn,[i.encode(n.method),i.encode(n.path),t,r,s]),o=new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},e,a));return b(h(vt(n.method),vt(n.path),t,r,s,o))}function ye(n){let e=he(n.credential,"credential"),t=he(n.request,"request signature"),r=n.session===void 0?new Uint8Array([0]):h(new Uint8Array([1]),he(n.session,"session statement"));return b(h(e,r,t))}function zn(n){if(n==null)return new Uint8Array(0);if(typeof n=="string"||n instanceof Uint8Array)return n;if(n instanceof ArrayBuffer)return new Uint8Array(n);if(ArrayBuffer.isView(n))return new Uint8Array(n.buffer,n.byteOffset,n.byteLength);throw new Error(`a request-carried proof cannot commit to a ${n?.constructor?.name??typeof n} body: pass a string or bytes, or use a session for this call`)}function be(n){let e=n.ttlSeconds??120,t=n.now??(()=>Math.floor(Date.now()/1e3));return async r=>{let s=t();return ye({credential:n.credential,session:n.session,request:await fe({method:r.method,path:r.path,body:zn(r.body),issuedAt:s,expiresAt:s+e,signerSecret:n.signerSecret})})}}var we=class extends Error{constructor(e,t,r,s){super(t),this.name="RpcError",this.code=e,this.data=r,this.type=s}};async function Fe(n,e,t){let r=await n.post("/jsonrpc",{jsonrpc:"2.0",id:1,method:e,params:t});if(r.error){let s=r.error;throw new we(s.code??-1,s.message??s.type??"RPC error",s.data,s.type)}return r.result}var re=class{constructor(e){this.httpClient=e.httpClient}async execute(e){let t=await Fe(this.httpClient,"execute",{contextId:e.contextId,method:e.method,argsJson:e.argsJson??{}});return t&&"output"in t?t.output:t}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 Qn=new Set(["MigrationStarted","MigrationProgress","CascadeProgress","MigrationCompleted"]);function kt(n){return n.type!==void 0&&Qn.has(n.type)}var Yn=new Set(["token_reuse","token_revoked"]),Xn=new Set([401,403]);function St(n){let e=n.headers.get("x-auth-error");return!e||!Xn.has(n.status)?null:Yn.has(e)?e:null}var W=class{constructor(e){this.sessionId=null;this.abortController=null;this.reconnectTimer=null;this.subscribedContextIds=new Set;this.subscribedGroupIds=new Set;this.closed=!1;this.listeners={connect:[],event:[],error:[]};this.baseUrl=e.baseUrl.replace(/\/+$/,""),this.getAuthToken=e.getAuthToken,this.reconnectDelayMs=e.reconnectDelayMs??3e3,this.fetchImpl=(t,r)=>e.fetch?e.fetch(t,r):globalThis.fetch(t,r)}on(e,t){let r=e;if(r in this.listeners){let s=this.listeners[r];s.includes(t)||s.push(t)}}off(e,t){let r=e;if(r in this.listeners){let s=this.listeners[r],i=s.indexOf(t);i!==-1&&s.splice(i,1)}}onAppVersionChanged(e){let t=r=>{if(r.type!=="AppVersionChanged")return;let s=r.data;e({contextId:r.contextId,fromVersion:s?.fromVersion,toVersion:s?.toVersion})};return this.on("event",t),()=>this.off("event",t)}onMigrationEvent(e){let t=r=>{kt(r)&&e(r)};return this.on("event",t),()=>this.off("event",t)}emit(e,t){let r=e;if(r in this.listeners)for(let s of this.listeners[r])try{s(t)}catch{}}async connect(){if(!(this.abortController&&!this.closed)){this.closed=!1,this.abortController=new AbortController;try{let e=await this.getAuthToken(),t=`${this.baseUrl}/sse`,r=await this.fetchImpl(t,{headers:{Authorization:`Bearer ${e}`,Accept:"text/event-stream"},signal:this.abortController.signal});if(!r.ok){let s=St(r),i=await r.text().catch(()=>{});throw s?new _(s,r.status,r.statusText,t,r.headers,i):new v(r.status,r.statusText,t,r.headers,i)}if(!r.body)throw new Error("SSE response has no body");this.readStream(r.body).catch(s=>{if(this.closed)return;let i=s instanceof Error?s:new Error(String(s));this.emit("error",i),this.scheduleReconnect()})}catch(e){if(this.closed)return;let t=e instanceof Error?e:new Error(String(e));if(this.emit("error",t),t instanceof _)return;this.scheduleReconnect()}}}async readStream(e){let t=e.getReader(),r=new TextDecoder,s="";try{for(;;){let{done:i,value:a}=await t.read();if(i)break;s+=r.decode(a,{stream:!0});let o=s.split(`
|
|
2
|
-
`);s=o.pop()??"";for(let c of o)if(c.startsWith("data:")){let l=c.slice(5).trim();l&&this.handleMessage(l)}}if(s+=r.decode(),s.startsWith("data:")){let i=s.slice(5).trim();i&&this.handleMessage(i)}}catch(i){if(this.closed)return;let a=i instanceof Error?i:new Error(String(i));this.emit("error",a)}this.closed||this.scheduleReconnect()}handleMessage(e){try{let t=JSON.parse(e);if(t.type==="connect"&&t.session_id){this.sessionId=t.session_id,this.emit("connect",t.session_id),(this.subscribedContextIds.size>0||this.subscribedGroupIds.size>0)&&this.sendSubscription("subscribe",{contextIds:[...this.subscribedContextIds],groupIds:[...this.subscribedGroupIds]});return}if(!t.result)return;let r=t.result.data;if(Array.isArray(r))try{let s=new Uint8Array(r),i=new TextDecoder().decode(s);r=JSON.parse(i)}catch{}if(t.result.contextId){this.emit("event",{contextId:t.result.contextId,type:t.result.type,data:r});return}t.result.groupId&&this.emit("event",{groupId:t.result.groupId,type:t.result.type,data:r})}catch{}}async subscribe(e){let t=Array.isArray(e)?{contextIds:e}:e,r=(t.contextIds??[]).filter(i=>!this.subscribedContextIds.has(i)),s=(t.groupIds??[]).filter(i=>!this.subscribedGroupIds.has(i));for(let i of t.contextIds??[])this.subscribedContextIds.add(i);for(let i of t.groupIds??[])this.subscribedGroupIds.add(i);(r.length>0||s.length>0)&&this.sessionId&&await this.sendSubscription("subscribe",{contextIds:r,groupIds:s})}async unsubscribe(e){let t=Array.isArray(e)?{contextIds:e}:e,r=(t.contextIds??[]).filter(i=>this.subscribedContextIds.has(i)),s=(t.groupIds??[]).filter(i=>this.subscribedGroupIds.has(i));for(let i of t.contextIds??[])this.subscribedContextIds.delete(i);for(let i of t.groupIds??[])this.subscribedGroupIds.delete(i);(r.length>0||s.length>0)&&this.sessionId&&await this.sendSubscription("unsubscribe",{contextIds:r,groupIds:s})}async sendSubscription(e,t){try{let r=await this.getAuthToken(),s={};t.contextIds&&t.contextIds.length>0&&(s.contextIds=t.contextIds),t.groupIds&&t.groupIds.length>0&&(s.groupIds=t.groupIds);let i=await this.fetchImpl(`${this.baseUrl}/sse/subscription`,{method:"POST",headers:{Authorization:`Bearer ${r}`,"Content-Type":"application/json"},body:JSON.stringify({id:this.sessionId,method:e,params:s})});if(!i.ok){let a=St(i),o=await i.text().catch(()=>{});this.emit("error",a?new _(a,i.status,i.statusText,`${this.baseUrl}/sse/subscription`,i.headers,o):new v(i.status,i.statusText,`${this.baseUrl}/sse/subscription`,i.headers,o))}}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 Re=class Re{constructor(e){this.ws=null;this.closed=!1;this.reconnectAttempt=0;this.reconnectTimer=null;this.subscribedContextIds=new Set;this.subscribedGroupIds=new Set;this.listeners={connect:[],event:[],error:[]};this.baseUrl=e.baseUrl.replace(/\/+$/,""),this.getAuthToken=e.getAuthToken}on(e,t){let r=e;if(r in this.listeners){let s=this.listeners[r];s.includes(t)||s.push(t)}}off(e,t){let r=e;if(r in this.listeners){let s=this.listeners[r],i=s.indexOf(t);i!==-1&&s.splice(i,1)}}emit(e,t){let r=e;if(r in this.listeners)for(let s of this.listeners[r])try{s(t)}catch{}}async connect(){if(!(this.ws&&(this.ws.readyState===0||this.ws.readyState===1))){this.closed=!1;try{let e=await this.getAuthToken();if(!e)throw new Error("No authentication token available for WebSocket connection");let t=this.baseUrl.replace(/^http/,"ws");this.ws=new WebSocket(`${t}/ws?token=${encodeURIComponent(e)}`),this.ws.onopen=()=>{this.reconnectAttempt=0,this.emit("connect"),this.resubscribeAfterReconnect()},this.ws.onmessage=r=>{this.handleMessage(r.data)},this.ws.onerror=()=>{this.emit("error",new Error("WebSocket error"))},this.ws.onclose=()=>{this.closed||this.scheduleReconnect()}}catch(e){if(this.closed)return;let t=e instanceof Error?e:new Error(String(e));this.emit("error",t),this.scheduleReconnect()}}}handleMessage(e){if(typeof e=="string")try{let t=JSON.parse(e);if(!t.result)return;let r=t.result.data;if(Array.isArray(r))try{let s=new Uint8Array(r),i=new TextDecoder().decode(s);r=JSON.parse(i)}catch{}if(t.result.contextId){this.emit("event",{contextId:t.result.contextId,type:t.result.type,data:r});return}t.result.groupId&&this.emit("event",{groupId:t.result.groupId,type:t.result.type,data:r})}catch{}}subscribe(e){let t=Array.isArray(e)?{contextIds:e}:e;for(let r of t.contextIds??[])this.subscribedContextIds.add(r);for(let r of t.groupIds??[])this.subscribedGroupIds.add(r);this.ws&&this.ws.readyState===1&&this.sendMessage({id:null,method:"subscribe",params:this.buildSubscriptionParams(t.contextIds??[],t.groupIds??[])})}unsubscribe(e){let t=Array.isArray(e)?{contextIds:e}:e;for(let r of t.contextIds??[])this.subscribedContextIds.delete(r);for(let r of t.groupIds??[])this.subscribedGroupIds.delete(r);this.ws&&this.ws.readyState===1&&this.sendMessage({id:null,method:"unsubscribe",params:this.buildSubscriptionParams(t.contextIds??[],t.groupIds??[])})}resubscribeAfterReconnect(){this.subscribedContextIds.size===0&&this.subscribedGroupIds.size===0||this.sendMessage({id:null,method:"subscribe",params:this.buildSubscriptionParams([...this.subscribedContextIds],[...this.subscribedGroupIds])})}buildSubscriptionParams(e,t){let r={};return e.length>0&&(r.contextIds=e),t.length>0&&(r.groupIds=t),r}sendMessage(e){this.ws&&this.ws.readyState===1&&this.ws.send(JSON.stringify(e))}scheduleReconnect(){if(this.closed)return;this.reconnectTimer&&clearTimeout(this.reconnectTimer);let e=Math.min(1e3*Math.pow(2,this.reconnectAttempt),Re.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()}};Re.MAX_BACKOFF_MS=3e4;var J=Re;function Ae(){return{encode(n){return Array.from(new TextEncoder().encode(JSON.stringify(n)))},decode(n){return JSON.parse(new TextDecoder().decode(new Uint8Array(n)))}}}var se=class{constructor(e){this.httpClient=e.httpClient,this.sse=e.sse}async set(e,t,r=Ae()){await Fe(this.httpClient,"set_ephemeral",{contextId:e,state:r.encode(t)})}subscribe(e,t,r=Ae()){let s=i=>{let a=i;if(a.type!=="Ephemeral"||a.contextId!==e)return;let o=a.data;if(!o?.author)return;let c=!!o.removed,l={author:o.author,state:c||o.state===void 0?void 0:r.decode(o.state),removed:c};o.ageMs!==void 0&&(l.ageMs=o.ageMs),t(l)};return this.sse.on("event",s),this.sse.connect().catch(()=>{}),this.sse.subscribe([e]).catch(()=>{}),()=>{this.sse.off("event",s)}}};var Zn=new TextEncoder().encode("calimero.device.cert.v1"),Tt=new TextEncoder().encode("calimero.account.genesis.v1"),er=new TextEncoder().encode("calimero.device.id.v1"),We=2;async function Et(n,e){if(e.length!==16)throw new Error(`nonce must be 16 bytes, got ${e.length}`);let t=y(n,"account",32);return b(await U(er,[t,e]))}async function Je(n){return U(Zn,[y(n.account,"account",32),y(n.device,"device",32),y(n.signPublicKey,"signPublicKey",32),y(n.kemPublicKey,"kemPublicKey",32),k(n.keyEpoch),k(n.deviceEpoch)])}function It(n){return h(new Uint8Array([We]),n.rootPublicKey,k(0),y(n.account,"account",32),y(n.device,"device",32),y(n.signPublicKey,"signPublicKey",32),y(n.kemPublicKey,"kemPublicKey",32),k(n.keyEpoch),k(n.deviceEpoch),n.signature)}async function Pt(n){let e=await P(n.rootSecret),t=b(await U(Tt,[h(new Uint8Array([We]),e)])),r=0,s=await Je({account:t,device:n.device,signPublicKey:n.signPublicKey,kemPublicKey:n.kemPublicKey,keyEpoch:r,deviceEpoch:n.deviceEpoch}),i=await I(n.rootSecret),a=new Uint8Array(await crypto.subtle.sign("Ed25519",i,s)),o=It({rootPublicKey:e,account:t,device:n.device,signPublicKey:n.signPublicKey,kemPublicKey:n.kemPublicKey,keyEpoch:r,deviceEpoch:n.deviceEpoch,signature:a});return b(o)}async function xe(n){let e=await P(n);return b(await U(Tt,[h(new Uint8Array([We]),e)]))}var ze=["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 tr=new TextEncoder().encode("calimero.mdma.account-link.v1\0"),nr=new TextEncoder().encode("calimero.mdma.account-login.v1\0"),ie=256,Dt=ie/32,Qe=(ie+Dt)/11;async function Ut(){let n=crypto.getRandomValues(new Uint8Array(ie/8));return Nt(b(n),await sr(n))}async function Mt(n){let e=rr(n);return Nt(b(await ir(e)),e.join(" "))}async function L(n){return y(n,"secret",32),{secret:n,publicKey:b(await P(n)),accountId:await xe(n)}}async function oe(n){if(!n.nonce)throw new Error("nonce is required to sign an account link");let e=await I(n.rootSecret),t=new Uint8Array(await crypto.subtle.sign("Ed25519",e,h(tr,new TextEncoder().encode(n.nonce))));return Ht(t)}async function Ce(n){if(!n.nonce)throw new Error("nonce is required to sign an account login");let e=await I(n.rootSecret),t=new Uint8Array(await crypto.subtle.sign("Ed25519",e,h(nr,new TextEncoder().encode(n.nonce))));return Ht(t)}async function Nt(n,e){return{...await L(n),phrase:e}}function rr(n){let e=n.normalize("NFKD").toLowerCase().trim().split(/\s+/),t=e[0]===""?0:e.length;if(t!==Qe)throw new Error(`recovery phrase must be ${Qe} words, got ${t}`);return e}async function sr(n){let e=qt(n)+await _t(n),t=[];for(let r=0;r<Qe;r+=1){let s=Number.parseInt(e.slice(r*11,r*11+11),2);t.push(ze[s])}return t.join(" ")}async function ir(n){let e="";for(let r of n){let s=ze.indexOf(r);if(s<0)throw new Error(`"${r}" is not a word in the recovery phrase list`);e+=s.toString(2).padStart(11,"0")}let t=new Uint8Array(ie/8);for(let r=0;r<t.length;r+=1)t[r]=Number.parseInt(e.slice(r*8,r*8+8),2);if(e.slice(ie)!==await _t(t))throw new Error("recovery phrase checksum failed \u2014 check for a mistyped or transposed word");return t}async function _t(n){let e=new Uint8Array(await crypto.subtle.digest("SHA-256",n));return qt(e).slice(0,Dt)}function qt(n){let e="";for(let t of n)e+=t.toString(2).padStart(8,"0");return e}function Ht(n){let e="";for(let t of n)e+=String.fromCharCode(t);return btoa(e)}var or=new TextEncoder().encode("calimero.mdma.routing-read.v1\0");async function Gt(n,e){y(e,"deviceSecret",32);let t=await I(e),r=h(or,new TextEncoder().encode(n)),s=new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},t,r));return ar(s)}async function ve(n,e){return{"X-Calimero-Credential":e.credential,"X-Calimero-Nonce":n.nonce,"X-Calimero-Signature":await Gt(n.nonce,e.deviceSecret)}}function ar(n){let e="";for(let t of n)e+=String.fromCharCode(t);return btoa(e)}var cr="https://cloud.calimero.network",lr="x-mdma-session-refresh",ur="x-mdma-session-expires",$=class{constructor(e={}){this.session=null;this.baseUrl=(e.cloudBaseUrl||cr).replace(/\/+$/,""),this.onSession=e.onSession;let t=e.fetch;this.fetchImpl=t?(r,s)=>t(r,s):(r,s)=>globalThis.fetch(r,s),this.timeoutMs=e.timeoutMs??1e4,this.routingCredential=e.routingCredential,e.sessionToken&&(this.session={sessionToken:e.sessionToken,expiresAt:0,user:{email:""}})}getSession(){return this.session}isSignedIn(){return this.session!==null}async signInWithGoogle(e){let t=await this.request("POST","/api/auth/google",{body:{id_token:e},anonymous:!0});return this.adoptSession(t)}async signInWithAccount(e){let t=await L(e),{nonce:r}=await this.getAccountLoginChallenge();return this.submitAccountLogin({rootPublicKey:t.publicKey,nonce:r,signature:await Ce({rootSecret:e,nonce:r})})}async getAccountLoginChallenge(){let e=await this.request("GET","/api/auth/account/challenge",{anonymous:!0});return{nonce:e.nonce,expiresAtMs:e.expires_at_ms}}async submitAccountLogin(e){let t=await this.request("POST","/api/auth/account",{body:{root_public_key:e.rootPublicKey,nonce:e.nonce,signature:e.signature},anonymous:!0});return this.adoptSession(t)}async refreshSession(){let e=await this.request("POST","/api/auth/refresh");return this.adoptSession(e)}async signOut(){try{this.session&&await this.request("POST","/api/auth/logout",{parse:"none"})}finally{this.session=null,this.notifySession(null)}}async getMyNamespaces(){return(await this.request("GET","/api/cloud/me/namespaces")).map(t=>({namespaceId:String(t.namespace_id??t.group_id??""),groupId:String(t.group_id??t.namespace_id??""),haStatus:String(t.ha_status??"none"),haEnabledAt:t.ha_enabled_at??null,contexts:Array.isArray(t.contexts)?t.contexts:[],fleetReplicas:t.fleet_replicas}))}async getNamespaceRelays(e){return((await this.request("GET",`/api/cloud/me/namespaces/${encodeURIComponent(e)}/relays`)).relays??[]).map(r=>({peerId:String(r.peer_id??""),relayUrl:r.relay_url??null,executorAccount:r.executor_account??null,status:String(r.status??""),authorshipReady:r.authorship_ready===!0,lastSeenAt:r.last_seen_at??null,confirmedAt:r.confirmed_at??null}))}async findExecutingRelay(e){return(await this.getNamespaceRelays(e)).find(r=>r.authorshipReady&&r.relayUrl!==null&&r.executorAccount!==null)??null}async getNamespaceRouting(e){let t=await this.request("GET",`/api/cloud/namespaces/${encodeURIComponent(e)}/admitters`,{anonymous:!0,headers:await this.routingProof(e)});return{namespaceId:String(t.namespace_id??e),nodes:(t.admitters??[]).map(r=>({peerId:String(r.peer_id??""),account:r.account??null,relayUrl:r.relay_url??null,admitUrl:r.admit_url??null,status:String(r.status??""),fresh:r.fresh===!0,canAdmit:r.can_admit===!0,authorshipReady:r.authorship_ready===!0,canExecute:r.can_execute===!0})),servable:t.servable===!0,writable:t.writable===!0}}async getRoutingChallenge(e){let t=await this.request("GET",`/api/cloud/namespaces/${encodeURIComponent(e)}/challenge`,{anonymous:!0});return{namespaceId:String(t.namespace_id??e),nonce:String(t.nonce??""),expiresAtMs:Number(t.expires_at_ms??0)}}async routingProof(e){if(!this.routingCredential)return;let t=await this.getRoutingChallenge(e);return ve(t,this.routingCredential)}async getAccountRelaysChallenge(e){let t=await this.request("GET",`/api/cloud/accounts/${encodeURIComponent(e)}/challenge`,{anonymous:!0});return{accountId:String(t.account_id??e),nonce:String(t.nonce??""),expiresAtMs:Number(t.expires_at_ms??0)}}async getAccountRelays(e){if(!this.routingCredential)throw new Error("getAccountRelays needs a routingCredential: construct the client with the device certificate and its signing secret, since this read is proven by the device, not by a session.");let t=await this.getAccountRelaysChallenge(e);return((await this.request("GET",`/api/cloud/accounts/${encodeURIComponent(e)}/relays`,{anonymous:!0,headers:await ve(t,this.routingCredential)})).relays??[]).map(s=>({peerId:String(s.peer_id??""),relayUrl:s.relay_url??null,fresh:s.fresh===!0}))}async findAdmitter(e,t){let{nodes:r}=await this.getNamespaceRouting(e),s=t&&t.length>0?new Set(t.map(i=>i.toLowerCase())):null;return r.find(i=>i.canAdmit&&(s===null||i.account!==null&&s.has(i.account.toLowerCase())))??null}async getMyMachines(){return((await this.request("GET","/api/cloud/me/machines")).machines??[]).map(t=>({peerId:String(t.peer_id??""),relayUrl:t.relay_url??null,executorAccount:t.executor_account??null,canExecute:t.can_execute===!0,namespaces:(Array.isArray(t.namespaces)?t.namespaces:[]).map(r=>{let s=r;return{namespaceId:String(s.namespace_id??""),status:String(s.status??""),authorshipReady:s.authorship_ready===!0,fresh:s.fresh===!0,confirmedAt:s.confirmed_at??null,lastSeenAt:s.last_seen_at??null}})}))}async claimNamespace(e,t){await this.request("POST","/api/cloud/namespaces/claim",{body:{namespace_id:e,ownership_proof:t}})}async enableNamespaceHa(e,t={}){let r=t.admitterAddrs===void 0?{}:{admitter_addrs:[...t.admitterAddrs]};return this.request("POST",`/api/cloud/namespaces/${encodeURIComponent(e)}/enable-ha`,{body:r})}async disableNamespaceHa(e){return this.request("POST",`/api/cloud/namespaces/${encodeURIComponent(e)}/disable-ha`,{body:{}})}async getMyNode(){return(await this.request("GET","/api/cloud/me/node")).node??null}enableHA(e){let t=new URLSearchParams({group_id:e.groupId,context_id:e.contextId});e.redirectUrl&&t.set("redirect_url",e.redirectUrl),window.open(`${this.baseUrl}/enable-ha?${t.toString()}`)}disableHA(e){let t=new URLSearchParams({group_id:e.groupId,context_id:e.contextId});e.redirectUrl&&t.set("redirect_url",e.redirectUrl),window.open(`${this.baseUrl}/disable-ha?${t.toString()}`)}async linkAccount(e){let t=await L(e),{nonce:r}=await this.getAccountLinkChallenge();return this.submitAccountLink({accountId:t.accountId,rootPublicKey:t.publicKey,nonce:r,signature:await oe({rootSecret:e,nonce:r})})}async getAccountLinkChallenge(){let e=await this.request("GET","/api/cloud/me/accounts/challenge");return{nonce:e.nonce,expiresAtMs:e.expires_at_ms??null}}async submitAccountLink(e){let t=await this.request("POST","/api/cloud/me/accounts",{body:{account_id:e.accountId,root_public_key:e.rootPublicKey,nonce:e.nonce,signature:e.signature}});return{accountId:String(t.account_id??e.accountId),linkedAt:t.linked_at??null,alreadyLinked:t.already_linked===!0}}static accountLinkHandoff(e){let t=e.portalUrl.replace(/\/+$/,""),r=new URLSearchParams({"link-account":e.accountId,"callback-url":e.callbackUrl});return{url:`${t}/?${r.toString()}`,accountId:e.accountId}}static readAccountLinkCallback(e){let t=e??(typeof window>"u"?"":window.location.href);if(!t)return{};let r;try{r=new URL(t).hash}catch{return{}}let s=new URLSearchParams(r.replace(/^#/,"")),i=s.get("grant"),a=s.get("account"),o=s.get("error"),c={};return i&&(c.grant=i),a&&(c.accountId=a),o&&(c.error=o),c}async linkAccountWithGrant(e){let t=await L(e.rootSecret),r=await this.request("POST","/api/cloud/accounts/link",{body:{grant:e.grant,root_public_key:t.publicKey,signature:await oe({rootSecret:e.rootSecret,nonce:e.grant})},anonymous:!0});return{accountId:String(r.account_id??t.accountId),linkedAt:r.linked_at??null,alreadyLinked:r.already_linked===!0}}async getMyAccounts(){let e=await this.request("GET","/api/cloud/me/accounts");return{accounts:(e.accounts??[]).map(t=>({accountId:String(t.account_id??""),linkedAt:t.linked_at??null,hasRecoveryEnvelope:t.has_recovery_envelope===!0})),limit:e.limit??null}}adoptSession(e){return this.session={sessionToken:e.session_token,expiresAt:e.expires_at,user:e.user},this.notifySession(this.session),this.session}async notifySession(e){try{await this.onSession?.(e)}catch{}}async request(e,t,r={}){if(!r.anonymous&&!this.session)throw new Error("Not signed in to Calimero Cloud: call signInWithGoogle() or construct the client with a sessionToken");let s={...r.headers,Accept:"application/json"};r.body!==void 0&&(s["Content-Type"]="application/json"),!r.anonymous&&this.session&&(s.Authorization=`Bearer ${this.session.sessionToken}`);let i=new AbortController,a=setTimeout(()=>i.abort(),this.timeoutMs),o;try{o=await this.fetchImpl(`${this.baseUrl}${t}`,{method:e,headers:s,body:r.body===void 0?void 0:JSON.stringify(r.body),signal:i.signal})}catch(c){throw new v(0,c instanceof Error?c.name:"NetworkError",`${this.baseUrl}${t}`,new Headers,c instanceof Error?c.message:String(c))}finally{clearTimeout(a)}if(this.adoptRollingRefresh(o),!o.ok){let c=await o.text().catch(()=>{});throw new v(o.status,o.statusText,`${this.baseUrl}${t}`,o.headers,c)}if(!(r.parse==="none"||o.status===204))return await o.json()}adoptRollingRefresh(e){let t=e.headers.get(lr);if(!t||!this.session)return;let r=e.headers.get(ur),s=Number(r);this.session={sessionToken:t,expiresAt:Number.isFinite(s)&&s>0?s:this.session.expiresAt,user:this.session.user},this.notifySession(this.session)}};function pr(n){let e=n&&typeof n=="object"?n.data??n:void 0;if(!e||typeof e!="object")return[];let t=e.localPeerId,r=e.externalAddrs;if(typeof t!="string"||!t||!Array.isArray(r))return[];let s=`/p2p/${t}`,i=[];for(let a of r){if(typeof a!="string")continue;let o=a.trim();if(!o.startsWith("/"))continue;let c=o.endsWith(s)?o:`${o}${s}`;i.includes(c)||i.push(c)}return i}function dr(n){if(n)return typeof n=="function"?n:be(n)}var gr="mero-js:token-refresh";function mr(){let e=globalThis.navigator?.locks;return e&&typeof e.request=="function"?e:null}function Ye(n,e){try{let t=n.split(".");if(t.length===3){let r=t[1].replace(/-/g,"+").replace(/_/g,"/");for(;r.length%4;)r+="=";let s=JSON.parse(atob(r));if(typeof s.exp=="number")return s.exp*1e3}}catch{}return e}var ke=class{constructor(e){this.tokenData=null;this.refreshPromise=null;this.rpcClient=null;this.sseClient=null;this.wsClient=null;this.wsWarned=!1;this.config={timeoutMs:1e4,...e},this.tokenStore=e.tokenStore??null,this.tokenStore&&(this.tokenData=this.tokenStore.getTokens());let t=typeof window<"u"&&"__TAURI_INTERNALS__"in window,r=dr(this.config.requestProof);this.httpClient=F({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 s=>{this.tokenData&&(this.tokenData.access_token=s,this.tokenStore?.setTokens(this.tokenData))},onAuthRevoked:async()=>{this.clearToken();try{await this.config.onAuthRevoked?.()}catch{}},timeoutMs:this.config.timeoutMs,credentials:this.config.requestCredentials??(t?"omit":void 0)}),this.authClient=bt(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 re({httpClient:this.httpClient})),this.rpcClient}get events(){return this.sseClient||(this.sseClient=new W({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 se({httpClient:this.httpClient,sse:this.events})),this.ephemeralClient}get cloud(){return this.cloudClient||(this.cloudClient=new $(this.config.cloud??{})),this.cloudClient}get ws(){return this.wsWarned||(this.wsWarned=!0,console.warn("[mero-js] WsClient is experimental. Use mero.events (SSE) for production.")),this.wsClient||(this.wsClient=new J({baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||""})),this.wsClient}async authenticate(e){let t=e||this.config.credentials;if(!t)throw new Error("No credentials provided for authentication");try{let r={auth_method:"user_password",public_key:t.username,client_name:"mero-js-sdk",permissions:["admin"],timestamp:Math.floor(Date.now()/1e3),provider_data:{username:t.username,password:t.password}},s=await this.authClient.generateTokens(r),i=s.data.access_token;return this.tokenData={access_token:i,refresh_token:s.data.refresh_token,expires_at:Ye(i,Date.now()+36e5)},this.tokenStore?.setTokens(this.tokenData),this.tokenData}catch(r){throw new Error(`Authentication failed: ${r instanceof Error?r.message:"Unknown error"}`)}}async getValidToken(){return this.tokenData}async performTokenRefresh(){if(this.refreshPromise)return this.refreshPromise;let e=this.tokenData?.access_token,t=this.withRefreshLock(()=>this.performTokenRefreshLocked(e));this.refreshPromise=t;try{return await t}finally{this.refreshPromise===t&&(this.refreshPromise=null)}}withRefreshLock(e){let t=mr();return t?t.request(gr,e):e()}async performTokenRefreshLocked(e){let t=this.tokenStore?.getTokens()??null;if(t?.refresh_token&&(this.tokenData=t,e&&t.access_token!==e))return t;if(!this.tokenData?.refresh_token)throw new Error("No refresh token available");try{let r=await this.authClient.refreshToken({access_token:this.tokenData.access_token,refresh_token:this.tokenData.refresh_token}),s=r.data.access_token;return this.tokenData={access_token:s,refresh_token:r.data.refresh_token,expires_at:Ye(s,Date.now()+36e5)},this.tokenStore?.setTokens(this.tokenData),this.tokenData}catch(r){throw new Error(`Token refresh failed: ${r instanceof Error?r.message:"Unknown error"}`)}}clearToken(){this.refreshPromise=null,this.tokenData=null,this.tokenStore?.clear()}isAuthenticated(){return this.tokenData!==null}setTokenData(e){let t=e.expires_at||Ye(e.access_token,Date.now()+36e5);this.tokenData={...e,expires_at:t},this.tokenStore?.setTokens(this.tokenData)}getTokenData(){return this.tokenData}close(){this.sseClient?.close(),this.wsClient?.close()}static parseAuthCallback(e){return Ke(e)}static buildAuthLoginUrl(e,t){return je(e,t)}};function hr(n){return new ke(n)}var Xe=class{constructor(){this.tokens=null}getTokens(){return this.tokens}setTokens(e){this.tokens=e}clear(){this.tokens=null}},fr="mero-tokens",Ze=class{constructor(e=fr){this.key=e}getTokens(){try{if(typeof localStorage>"u")return null;let e=localStorage.getItem(this.key);if(!e)return null;let t=JSON.parse(e);return t&&t.access_token&&t.refresh_token?{access_token:t.access_token,refresh_token:t.refresh_token,expires_at:typeof t.expires_at=="number"?t.expires_at:Date.now()+36e5}:null}catch{return null}}setTokens(e){try{if(typeof localStorage>"u")return;localStorage.setItem(this.key,JSON.stringify(e))}catch{}}clear(){try{if(typeof localStorage>"u")return;localStorage.removeItem(this.key)}catch{}}};var yr=new TextEncoder().encode("calimero.warrant.v2"),br=new TextEncoder().encode("calimero.warrant.intent.v1"),Ot=64,wr="00".repeat(32);async function et(n,e){let t=new TextEncoder().encode(JSON.stringify(e));return U(br,[new TextEncoder().encode(n),t])}async function Se(n){let e=y(n.context,"context",32),t=y(n.authorAccount,"authorAccount",32),r=y(n.executor,"executor",32),s=y(n.appVersion??wr,"appVersion",32),i=Lt(n.accountHeads,"accountHeads"),a=Lt(n.governanceFloor,"governanceFloor"),o=await I(n.deviceSecret),c=await P(n.deviceSecret),l=new TextEncoder().encode(n.method),p=await et(n.method,n.argsJson),d=S(n.nonce),m=S(n.notAfter),f=await U(yr,[e,t,c,r,s,l,p,S(i.length),...i,S(a.length),...a,d,m]),g=new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},o,f));return b(h(e,t,c,r,s,k(l.length),l,p,k(i.length),...i,k(a.length),...a,d,m,g))}function Lt(n,e){let t=n??[];if(t.length>Ot)throw new Error(`${e} cites ${t.length} heads, over the ${Ot} a node accepts`);return t.map((r,s)=>y(r,`${e}[${s}]`,32))}var Rr=300,Te=class extends Error{constructor(t,r,s){super(`relay refused the intent (HTTP ${s}): ${t}`);this.reason=t;this.retryable=r;this.status=s;this.name="IntentRefusedError"}},ae=class{constructor(e){this.config=e,this.baseUrl=e.relayUrl.replace(/\/+$/,""),this.executorAccount=e.executorAccount;let t=e.fetch;this.fetchImpl=t?(r,s)=>t(r,s):(r,s)=>globalThis.fetch(r,s),this.timeoutMs=e.timeoutMs??1e4}async describe(e){let t=await this.json("GET",`/admin-api/contexts/${encodeURIComponent(e)}/intents`);return this.executorAccount=t.data.executorAccount,t.data}async execute(e,t,r={}){let s=this.executorAccount??(await this.describe(e)).executorAccount,i=await this.config.nonces.next(),a=this.config.ttlSeconds??Rr,o=await Se({context:e,authorAccount:this.config.authorAccount,executor:s,method:t,argsJson:r,nonce:i,notAfter:BigInt(Math.floor(Date.now()/1e3))+BigInt(a),deviceSecret:this.config.deviceSecret}),c=await this.json("POST",`/admin-api/contexts/${encodeURIComponent(e)}/intents`,{method:t,argsJson:r,warrant:o,authorProof:this.config.authorProof});return{rootHash:c.data.rootHash,returns:c.data.returns??null}}async json(e,t,r){let s={Accept:"application/json"};r!==void 0&&(s["Content-Type"]="application/json");let i=new AbortController,a=setTimeout(()=>i.abort(),this.timeoutMs),o;try{o=await this.fetchImpl(`${this.baseUrl}${t}`,{method:e,headers:s,body:r===void 0?void 0:JSON.stringify(r),signal:i.signal})}catch(c){throw new v(0,c instanceof Error?c.name:"NetworkError",`${this.baseUrl}${t}`,new Headers,c instanceof Error?c.message:String(c))}finally{clearTimeout(a)}if(!o.ok){let c=await o.text().catch(()=>"");if(o.status===400||o.status===403){let l=Ar(c);throw new Te(l,/nonce/i.test(l),o.status)}throw new v(o.status,o.statusText,`${this.baseUrl}${t}`,o.headers,c)}return await o.json()}};function Ar(n){if(!n)return"no reason given";try{let e=JSON.parse(n);for(let t of[e.error,e.message])if(typeof t=="string"&&t)return t}catch{}return n}function tt(n=1){let e=BigInt(n);if(e<1n)throw new Error("nonce sequence starts at 1");return{next(){let t=e;return e+=1n,Promise.resolve(t)}}}function nt(n,e){let t=e??globalThis.localStorage;if(!t)throw new Error("no localStorage in this runtime: pass a storage implementation, or use createMemoryNonceSource for a process that owns its whole sequence");return{next(){let r=t.getItem(n),s=0n;if(r!==null&&r!=="")try{let a=BigInt(r);a>0n&&(s=a)}catch{s=0n}let i=s+1n;return t.setItem(n,i.toString()),Promise.resolve(i)}}}var xr="Noise_NK_25519_AESGCM_SHA256",rt=32,Cr=16,vr=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,110,4,34,4,32]),it=class n{constructor(e){this.k=null;this.n=0;this.ck=e,this.h=e}static async initialize(){let e=new TextEncoder().encode(xr),t=new Uint8Array(32);return t.set(e),new n(t)}async mixHash(e){this.h=await Sr(h(this.h,e))}async mixKey(e){let[t,r]=await Kt(this.ck,e);this.ck=t,this.k=await crypto.subtle.importKey("raw",r,"AES-GCM",!1,["encrypt","decrypt"]),this.n=0}async encryptAndHash(e){if(!this.k)throw new Error("Noise: no cipher key yet");let t=new Uint8Array(await crypto.subtle.encrypt({name:"AES-GCM",iv:Bt(this.n),additionalData:this.h},this.k,e));return this.n+=1,await this.mixHash(t),t}async decryptAndHash(e){if(!this.k)throw new Error("Noise: no cipher key yet");let t=new Uint8Array(await crypto.subtle.decrypt({name:"AES-GCM",iv:Bt(this.n),additionalData:this.h},this.k,e));return this.n+=1,await this.mixHash(e),t}split(){return Kt(this.ck,new Uint8Array)}};async function jt(n,e,t){let r=await it.initialize();await r.mixHash(e),await r.mixHash(n);let s=await kr(t);return await r.mixHash(s.publicKey),await r.mixKey(await $t(s.privateKey,n)),{message1:h(s.publicKey,await r.encryptAndHash(new Uint8Array)),async finish(a){if(a.length<rt+Cr)throw new Error("Noise: message 2 is too short");let o=a.slice(0,rt);return await r.mixHash(o),await r.mixKey(await $t(s.privateKey,o)),{payload:await r.decryptAndHash(a.slice(rt)),split:await r.split()}}}}async function kr(n){if(!n){let r;try{r=await crypto.subtle.generateKey({name:"X25519"},!0,["deriveBits"])}catch(i){throw new Error(`Sealed transport needs WebCrypto with X25519, which this runtime lacks (${i?.name??"no crypto.subtle"}). Current browsers and Node have it; in React Native, install react-native-quick-crypto as the global crypto.`)}let s=new Uint8Array(await crypto.subtle.exportKey("raw",r.publicKey));return{privateKey:r.privateKey,publicKey:s}}let e=await crypto.subtle.importKey("pkcs8",h(vr,n),{name:"X25519"},!0,["deriveBits"]),t=await crypto.subtle.exportKey("jwk",e);return{privateKey:e,publicKey:Tr(t.x)}}async function $t(n,e){let t=await crypto.subtle.importKey("raw",e,{name:"X25519"},!1,[]);return new Uint8Array(await crypto.subtle.deriveBits({name:"X25519",public:t},n,256))}function Bt(n){let e=new Uint8Array(12);return new DataView(e.buffer).setBigUint64(4,BigInt(n),!1),e}async function Sr(n){return new Uint8Array(await crypto.subtle.digest("SHA-256",n))}async function st(n,e){let t=await crypto.subtle.importKey("raw",n,{name:"HMAC",hash:"SHA-256"},!1,["sign"]);return new Uint8Array(await crypto.subtle.sign("HMAC",t,e))}async function Kt(n,e){let t=await st(n,e),r=await st(t,new Uint8Array([1])),s=await st(t,h(r,new Uint8Array([2])));return[r,s]}function Tr(n){let e=n.replace(/-/g,"+").replace(/_/g,"/"),t=atob(e+"=".repeat((4-e.length%4)%4));return Uint8Array.from(t,r=>r.charCodeAt(0))}var Jt="/sealed/v2/handshake",zt="/sealed/v2",le="application/vnd.calimero.sealed",ot=2,Er=new TextEncoder().encode("calimero/sealed-http/v2"),ce=16,Ir=1+ce+8,Pr=0,Dr=1,Ur=2,Mr=1+64*1024+16,Nr=1024,_r=6e4,qr="calimero.tee-attest.transport-key.v1",Hr=[101,204,205,304],Qt=new TextEncoder,ue=class extends Error{constructor(){super("The node no longer holds the attested transport key; attest again for the current one");this.name="StaleTransportKeyError"}},z=class extends Error{constructor(t,r,s,i){super(s);this.status=t;this.code=r;this.retryAfterMs=i;this.name="SealedTransportError"}};async function Yt(n,e){let t=await crypto.subtle.digest("SHA-256",h(Qt.encode(qr),n,e));return new Uint8Array(t)}async function Xt(n,e,t={}){if(t.applicationId===void 0!=(t.applicationHash===void 0))throw new Error("applicationId and applicationHash are given together or not at all");let r=b(crypto.getRandomValues(new Uint8Array(32))),s=await n.teeAttest({nonce:r,applicationId:t.applicationId,bindTransportKey:!0,...e.includeCollateral?{includeCollateral:!0}:{}});if(!s.transportPublicKey)throw new Error("The node did not report a transport key; it predates sealed transport");let i=y(s.transportPublicKey,"transportPublicKey",32),a=t.applicationHash?y(t.applicationHash,"applicationHash",32):new Uint8Array(32),o=b(await Yt(a,i));if(!await e({quoteB64:s.quoteB64,nonce:r,reportDataSuffix:o,collateral:s.collateral}))throw new Error("The attestation did not verify, so its transport key is not trusted");return i}function pe(n){let e=n.fetch??((s,i)=>fetch(s,i)),t=`${n.baseUrl.replace(/\/+$/,"")}/admin-api/tee/attest`,r={async teeAttest(s){let i=await e(t,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(s)});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 Zt({baseUrl:n.baseUrl,transportPublicKey:()=>Xt(r,n.verify,{applicationId:n.applicationId,applicationHash:n.applicationHash}),fetch:e})}function Zt(n){let e=new URL(n.baseUrl),t=e.pathname.replace(/\/+$/,""),r=`${e.origin}${t}`,s=n.fetch??((d,m)=>fetch(d,m)),i=typeof n.transportPublicKey=="function"?n.transportPublicKey:void 0,a=i?Promise.resolve().then(i):Promise.resolve(n.transportPublicKey);a.catch(()=>{});let o,c=async()=>{try{return await Ft(s,r,await Vt(a))}catch(d){if(!(d instanceof ue)||!i)throw d;return a=Promise.resolve().then(i),Ft(s,r,await Vt(a))}},l=async()=>{let d=o??p(void 0),m=await d;if(Date.now()<m.renewAt)return[m,d];let f=p(d);return[await f,f]},p=d=>{if(o===d){let m=c();o=m,m.catch(()=>{o===m&&(o=void 0)})}return o};return async(d,m)=>{let f=new Request(d,m),g=new URL(f.url);if(g.origin!==e.origin||!g.pathname.startsWith(`${t}/`))throw new Error(`Refusing to send ${g.href} outside the sealed node at ${n.baseUrl}`);let R=[];f.headers.forEach((E,N)=>R.push([N,E]));let C={method:f.method,path:g.pathname.slice(t.length)+g.search,headers:R},A=new Uint8Array(await f.arrayBuffer()),x=async E=>{let{requestId:N,header:B,envelope:K}=await Or(E,C,A),j=await s(`${r}${zt}`,{method:"POST",headers:{"content-type":le},body:K,signal:f.signal});if(j.headers.get("content-type")!==le)throw await tn(j);return $r(j,E.responseKey,B,N)},[T,H]=await l();try{return await x(T)}catch(E){if(!(E instanceof z)||E.code!=="unknown_session")throw E;return x(await p(H))}}}async function Vt(n){let e=await n;if(e.length!==32)throw new Error("transportPublicKey must be 32 bytes");return e}async function Ft(n,e,t){try{return await Wt(n,e,t)}catch(r){if(!(r instanceof z)||r.code!=="busy")throw r;return await new Promise(s=>setTimeout(s,r.retryAfterMs??1e3)),Wt(n,e,t)}}async function Wt(n,e,t){let r=await jt(t,Er),s=await n(`${e}${Jt}`,{method:"POST",headers:{"content-type":le},body:h(new Uint8Array([ot]),t,r.message1)});if(s.headers.get("content-type")!==le)throw await tn(s);let i=await Kr(s,Nr);return Gr(r,i)}async function Gr(n,e){if(e[0]!==ot)throw new Error("The handshake reply is malformed");let t;try{t=await n.finish(e.slice(1))}catch{throw new Error("The handshake reply did not open: it did not come from the attested node")}let{payload:r,split:s}=t;if(r.length!==ce+4)throw new Error("The handshake reply is malformed");let i=r.slice(0,ce),a=new DataView(r.buffer,r.byteOffset).getUint32(ce,!1),[o,c]=await Promise.all([crypto.subtle.importKey("raw",s[0],"AES-GCM",!1,["encrypt"]),crypto.subtle.importKey("raw",s[1],"AES-GCM",!1,["decrypt"])]);return s[0].fill(0),s[1].fill(0),{requestKey:o,responseKey:c,nextRequestId:1,renewAt:Date.now()+a*1e3-_r,header(l){let p=new Uint8Array(Ir);return p[0]=ot,p.set(i,1),new DataView(p.buffer).setBigUint64(1+ce,BigInt(l),!1),p}}}async function Or(n,e,t){let r=n.nextRequestId;n.nextRequestId+=1;let s=n.header(r),i=await crypto.subtle.encrypt({name:"AES-GCM",iv:en(r,0),additionalData:s},n.requestKey,Lr(e,t));return{requestId:r,header:s,envelope:h(s,new Uint8Array(i))}}function en(n,e){let t=new Uint8Array(12),r=new DataView(t.buffer);return r.setBigUint64(0,BigInt(n),!1),r.setUint32(8,e,!1),t}function Lr(n,e){let t=Qt.encode(JSON.stringify(n)),r=new Uint8Array(4);return new DataView(r.buffer).setUint32(0,t.length,!1),h(r,t,e)}async function $r(n,e,t,r){if(!n.body)throw new Error("The sealed response has no body");let s=Br(n.body.getReader()),i=0,a=async()=>{let p=await s.next();if(!p)return null;let d;try{d=new Uint8Array(await crypto.subtle.decrypt({name:"AES-GCM",iv:en(r,i),additionalData:t},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:d[0],data:d.slice(1)}},o=await a();if(!o||o.kind!==Pr)throw new Error("The sealed response is malformed");let c=JSON.parse(new TextDecoder().decode(o.data));if(Hr.includes(c.status))return await s.cancel(),new Response(null,{status:c.status,headers:c.headers});let l=new ReadableStream({async pull(p){try{let d=await a();d?d.kind===Dr?p.enqueue(d.data):d.kind===Ur?(p.close(),await s.cancel()):p.error(new Error("The sealed response is malformed")):p.error(new Error("The sealed response was cut short"))}catch(d){p.error(d)}},cancel(){return s.cancel()}});return new Response(l,{status:c.status,headers:c.headers})}function Br(n){let e=new Uint8Array,t=async r=>{for(;e.length<r;){let{done:s,value:i}=await n.read();if(s)return!1;e=h(e,i)}return!0};return{async next(){if(!await t(4))return null;let r=new DataView(e.buffer,e.byteOffset).getUint32(0,!1);if(r>Mr)throw await n.cancel(),new Error("The sealed response is malformed: a frame is larger than the node sends");if(!await t(4+r))return null;let s=e.slice(4,4+r);return e=e.slice(4+r),s},cancel:()=>n.cancel()}}async function Kr(n,e){if(!n.body)return new Uint8Array;let t=n.body.getReader(),r=new Uint8Array;for(;;){let{done:s,value:i}=await t.read();if(s)return r;if(r=h(r,i),r.length>e)throw await t.cancel(),new Error("The handshake reply is malformed: it is too long")}}async function tn(n){let e,t=`Sealed request refused: HTTP ${n.status}`;try{let i=await n.json();e=i?.error?.code,i?.error?.message&&(t=`Sealed request refused: ${i.error.message}`)}catch{}if(e==="stale_transport_key")return new ue;let r=Number(n.headers.get("retry-after")),s=Number.isFinite(r)&&r>0?Math.min(r,5)*1e3:void 0;return new z(n.status,e,t,s)}async function jr(n){if(!n.sessionToken&&!n.googleIdToken)throw new Error("connectCloud needs either a sessionToken or a googleIdToken");let e=new $({cloudBaseUrl:n.cloudBaseUrl,sessionToken:n.sessionToken,onSession:n.onSession,fetch:n.fetch,timeoutMs:n.timeoutMs});!n.sessionToken&&n.googleIdToken&&await e.signInWithGoogle(n.googleIdToken);let t=await e.getMyNamespaces(),r=Vr(t,n.namespaceId),s=await e.getNamespaceRelays(r.namespaceId),i=s.find(o=>o.authorshipReady&&o.relayUrl!==null&&o.executorAccount!==null)??null;if(!i)throw new Error(Fr(r,s));let a=new ae({relayUrl:i.relayUrl,executorAccount:i.executorAccount,authorAccount:n.authorAccount,authorProof:n.authorProof,deviceSecret:n.deviceSecret,nonces:n.nonces??await Wr(n.deviceSecret),ttlSeconds:n.ttlSeconds,fetch:n.seal?pe({baseUrl:i.relayUrl,verify:n.seal,fetch:n.fetch}):n.fetch,timeoutMs:n.timeoutMs});return{cloud:e,relay:a,namespaceId:r.namespaceId,namespace:r,relayInfo:i,execute:(o,c,l)=>a.execute(o,c,l)}}function Vr(n,e){if(e){let t=n.find(r=>r.namespaceId===e);if(!t)throw new Error(`this account owns no namespace ${e}; it owns: ${n.map(r=>r.namespaceId).join(", ")||"(none)"}`);return t}if(n.length===0)throw new Error("this account owns no namespaces in the cloud: claim one first, then enable HA on it so a relay is assigned");if(n.length>1)throw new Error(`this account owns ${n.length} namespaces \u2014 pass namespaceId to say which: ${n.map(t=>t.namespaceId).join(", ")}`);return n[0]}function Fr(n,e){if(e.length===0)return n.haStatus==="enabled"?`namespace ${n.namespaceId} has HA enabled but no relay has been assigned to it yet \u2014 retry shortly`:`namespace ${n.namespaceId} has no relays: enable HA on it in the cloud to have an attested node assigned`;let t=e.filter(r=>!r.authorshipReady);return t.length===e.length?`every relay on namespace ${n.namespaceId} is waiting for the authorship grant: an admin of the namespace must grant CAN_AUTHOR_ON_BEHALF to ${t.map(r=>r.executorAccount??r.peerId).join(", ")||"the relay account"} \u2014 with AdminClient.grantAuthorship(namespaceId, account) for these relays, and AdminClient.openToDelegatedExecution(namespaceId) so relays assigned later need no further op`:`namespace ${n.namespaceId} has ${e.length} relay(s), but none reported both a URL and an executor account yet \u2014 retry shortly`}async function Wr(n){let e=`mero-js:warrant-nonce:${b(await P(n))}`;try{return nt(e)}catch{return tt(1)}}var Jr=/^[0-9a-f]{96}$/,zr=["mrtd","rtmr0","rtmr1","rtmr2","rtmr3"];function at(n){let e=Q(n.allowedMrtd??[],"allowedMrtd"),t=(n.allowedMeasurements??[]).map((o,c)=>{let l=`allowedMeasurements[${c}]`;return zr.map(p=>Q([o?.[p]??""],`${l}.${p}`)[0]).join()}),r=[Q(n.allowedRtmr0??[],"allowedRtmr0"),Q(n.allowedRtmr1??[],"allowedRtmr1"),Q(n.allowedRtmr2??[],"allowedRtmr2"),Q(n.allowedRtmr3??[],"allowedRtmr3")];if(n.allowedMeasurements!==void 0&&t.length===0)throw new Error("allowedMeasurements is empty, so no quote would ever be accepted");if(t.length===0){if(e.length===0)throw new Error("No image is trusted: give allowedMeasurements, or allowedMrtd with allowedRtmr1-3");if(r.slice(1).some(o=>o.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 s=n.allowedTcbStatuses??["UpToDate"],i=n.now??Date.now;return Object.assign(async({quoteB64:o,nonce:c,reportDataSuffix:l,collateral:p})=>{let d=Yr(o),m=p??await n.fetchCollateral?.(d);if(!m)throw new Error("The node sent no collateral for its quote, and no fetchCollateral was given to get it");let f;try{f=n.dcapVerify(d,m,Math.floor(i()/1e3))}catch(A){throw new Error(`The quote did not verify: ${A?.message??String(A)}`)}if(f.status==="Revoked"||!s.includes(f.status))throw new Error(`The platform's TCB status is ${f.status}, which is not accepted`);let g=Qr(f.report),R=[g.mrTd,g.rtMr0,g.rtMr1,g.rtMr2,g.rtMr3].map(A=>b(A));if(t.length>0&&!t.includes(R.join()))throw new Error(`The measurements (MRTD ${R[0]}, RTMR0-3 ${R.slice(1).join(", ")}) are not an image this verifier trusts`);if(e.length>0&&!e.includes(R[0]))throw new Error(`MRTD ${R[0]} is not an image this verifier trusts`);if([g.rtMr0,g.rtMr1,g.rtMr2,g.rtMr3].forEach((A,x)=>{let T=r[x];if(T.length>0&&!T.includes(b(A)))throw new Error(`RTMR${x} ${b(A)} is not one this verifier trusts`)}),b(g.reportData)!==`${c}${l}`.toLowerCase())throw new Error("The quote does not commit to this nonce and binding");return!0},{includeCollateral:!0})}function Q(n,e){return n.map(t=>{let r=t.trim().toLowerCase();if(!Jr.test(r))throw new Error(`${e} holds ${JSON.stringify(t)}, which is not a 48-byte hex measurement`);return r})}function Qr(n){let e=n.data;if(n.type==="td10"&&e)return e;if(n.type==="td15"&&e?.base)return e.base;throw new Error(`The quote is a ${n.type} quote, not a TDX one`)}function Yr(n){let e=atob(n),t=new Uint8Array(e.length);for(let r=0;r<e.length;r+=1)t[r]=e.charCodeAt(r);return t}var Xr=["UpToDate","SWHardeningNeeded","ConfigurationNeeded","ConfigurationAndSWHardeningNeeded","OutOfDate","OutOfDateConfigurationNeeded"];function ct(n,{profile:e}){if(n.length===0)throw new Error("No release given, so no image would be trusted");let t,r=n.map((s,i)=>{let a=s?.tag??`releases[${i}]`;if(s?.role!==void 0&&s.role!=="node")throw new Error(`${a} lists the measurements of a ${s.role}, not of a node image`);let o=s?.profiles?.[e];if(!o){let l=Object.keys(s?.profiles??{}).join(", ")||"none";throw new Error(`${a} has no profile ${JSON.stringify(e)} (it has: ${l})`)}let c=(o.allowed_tcb_statuses??["uptodate"]).map(l=>Zr(l,a));return t=t===void 0?c:t.filter(l=>c.includes(l)),{mrtd:o.mrtd,rtmr0:o.rtmr0,rtmr1:o.rtmr1,rtmr2:o.rtmr2,rtmr3:o.rtmr3}});if(!t||t.length===0)throw new Error("The releases given accept no TCB status in common");return{allowedMeasurements:r,allowedTcbStatuses:t}}function Zr(n,e){let t=Xr.find(r=>r.toLowerCase()===String(n).toLowerCase());if(!t)throw new Error(`${e} accepts TCB status ${JSON.stringify(n)}, which this verifier does not know`);return t}var nn=[{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"]}],rn=[{baseUrl:"https://rekor.sigstore.dev",logId:"c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d",publicKey:"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE2G2Y+2tabdTV5BcGiBIx0a9fAFwrkBbmLSGtks4L3qX6yYY0zufBnhC8Ur/iy55GhWP/9A/bY2LhC30M9+RYtw==",validFor:{start:"2021-01-12T11:53:27Z"}}];var es="1.2.840.10045.2.1",ts={"1.2.840.10045.3.1.7":"P-256","1.3.132.0.34":"P-384"},ns={"P-256":32,"P-384":48},rs={"1.2.840.10045.4.3.2":"SHA-256","1.2.840.10045.4.3.3":"SHA-384"};function sn(n,e,t){if(e+2>t)throw new Error("it is truncated");let r=n[e];if((r&31)===31)throw new Error("it uses a tag this parser does not read");let s=n[e+1],i=e+2;if(s&128){let o=s&127;if(o===0||o>4||i+o>t)throw new Error("it has a length this parser does not read");s=0;for(let c=0;c<o;c+=1)s=s*256+n[i+c];i+=o}let a=i+s;if(a>t)throw new Error("it is truncated");return{tag:r,bytes:n,offset:e,start:i,end:a}}function X(n){let e=sn(n,0,n.length);if(e.end!==n.length)throw new Error("it has trailing bytes");return e}function D(n){let e=[];for(let t=n.start;t<n.end;){let r=sn(n.bytes,t,n.end);e.push(r),t=r.end}return e}function w(n,e,t){if(!n||n.tag!==e)throw new Error(`${t} is not where it should be`);return n}function q(n){return n.bytes.slice(n.start,n.end)}function Ee(n){return n.bytes.slice(n.offset,n.end)}function Y(n){let e=q(w(n,6,"An object identifier"));if(e.length===0||e[e.length-1]&128)throw new Error("it has a malformed object identifier");let t=[],r=0;for(let a of e)r=r*128+(a&127),a&128||(t.push(r),r=0);let s=t.shift();return[...s<80?[Math.floor(s/40),s%40]:[2,s-80],...t].join(".")}function ss(n){let e=new TextDecoder().decode(q(n)),t=n.tag===23?/^(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})Z$/.exec(e):null,r=n.tag===24?/^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})Z$/.exec(e):null,s=t??r;if(!s)throw new Error(`it holds the time ${JSON.stringify(e)}, which is not one a certificate may hold`);let i=Number(s[1]);t&&(i+=i<50?2e3:1900);let[a,o,c,l,p]=s.slice(2).map(Number);return Date.UTC(i,a-1,o,c,l,p)}function lt(n){try{let[e,t,r,...s]=D(w(X(n),48,"The certificate"));if(s.length>0)throw new Error("it has fields after its signature");let i=D(w(e,48,"The signed part")),a=i[0]?.tag===160?1:0,[o,c,l,p,d,m,...f]=i.slice(a);w(o,2,"The serial number");let g=Y(D(w(t,48,"The signature algorithm"))[0]);if(Y(D(w(c,48,"The signature algorithm"))[0])!==g)throw new Error("it names two different signature algorithms");let C=rs[g];if(!C)throw new Error(`it is signed with ${g}, not ECDSA with SHA-256 or SHA-384`);let[A,x]=D(w(p,48,"The validity")).map(ss);if(x===void 0)throw new Error("its validity is incomplete");let[T,H]=D(w(m,48,"The public key"));w(H,3,"The public key");let[E,N]=D(w(T,48,"The key algorithm"));if(Y(E)!==es)throw new Error("its key is not an elliptic-curve key");let B=ts[Y(N)];if(!B)throw new Error("its key is on a curve other than P-256 or P-384");let K=new Map,j=f.find(Me=>Me.tag===163);if(j){let[Me]=D(j);for(let Un of D(w(Me,48,"The extensions"))){let V=D(w(Un,48,"An extension"));if(V.length===3)w(V[1],1,"An extension's critical flag");else if(V.length!==2)throw new Error("it has a malformed extension");let Ne=Y(V[0]);if(K.has(Ne))throw new Error(`it has extension ${Ne} twice`);K.set(Ne,q(w(V[V.length-1],4,"An extension value")))}}let ft=q(w(r,3,"The signature"));if(ft[0]!==0)throw new Error("its signature is not a whole number of bytes");return{der:n,tbs:Ee(e),signatureHash:C,signature:ft.slice(1),issuer:Ee(w(l,48,"The issuer")),subject:Ee(w(d,48,"The subject")),notBefore:A,notAfter:x,spki:Ee(m),curve:B,extensions:K}}catch(e){throw new Error(`The certificate is malformed: ${e.message}`)}}function on(n){return D(w(X(n),48,"The list")).map(Y)}function is(n,e){let t=ns[e],r=D(w(X(n),48,"The signature"));if(r.length!==2)throw new Error("The signature is not an ECDSA signature");let s=new Uint8Array(t*2);return r.forEach((i,a)=>{let o=q(w(i,2,"The signature"));if(o.length===0||o[0]&128)throw new Error("The signature is not an ECDSA signature");for(;o.length>1&&o[0]===0;)o=o.subarray(1);if(o.length>t)throw new Error("The signature is not an ECDSA signature");s.set(o,a*t+t-o.length)}),s}async function Ie(n,e,t,r,s){let i;try{i=is(r,e)}catch{return!1}let a=await crypto.subtle.importKey("spki",n,{name:"ECDSA",namedCurve:e},!1,["verify"]);return crypto.subtle.verify({name:"ECDSA",hash:t},a,i,s)}function M(n,e){let t=n.replace(/\s+/g,"");if(!/^[A-Za-z0-9+/]*={0,2}$/.test(t)||t.length%4!==0)throw new Error(`${e} is not base64`);let r=atob(t),s=new Uint8Array(r.length);for(let i=0;i<r.length;i+=1)s[i]=r.charCodeAt(i);return s}function ut(n,e){let t=[...n.matchAll(/-----BEGIN CERTIFICATE-----([^-]*)-----END CERTIFICATE-----/g)];if(t.length!==1||n.replace(t[0][0],"").trim()!=="")throw new Error(`${e} is not exactly one PEM certificate`);return M(t[0][1],e)}var os="2.5.29.17",as="2.5.29.37",cs="1.3.6.1.5.5.7.3.3",ls="1.3.6.1.4.1.57264.1.8",us="1.3.6.1.4.1.57264.1.1",ps=134,ds=12,gs=48,ms=new TextEncoder,Z=n=>new TextDecoder().decode(n);async function an(n,e,t,r){let{base64Signature:s,cert:i,rekorBundle:a}=bs(e),o=a.Payload;if(r!==void 0&&r.trim()!==s.trim())throw new Error("The detached signature is not the one in the bundle");let c=M(s,"The bundle signature"),l=ut(Z(M(i,"The bundle certificate")),"The bundle certificate"),p=lt(l),d=rn.find(x=>x.logId===o.logID.toLowerCase());if(!d)throw new Error(`The bundle names Rekor log ${o.logID}, which the Sigstore trust root does not know`);let m=ms.encode(`{"body":${JSON.stringify(o.body)},"integratedTime":${o.integratedTime},"logID":${JSON.stringify(o.logID)},"logIndex":${o.logIndex}}`);if(!await Ie(M(d.publicKey,"The Rekor key"),"P-256","SHA-256",M(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 g=o.integratedTime*1e3;if(!un(g,d.validFor))throw new Error(`Rekor log ${d.baseUrl} was not in use at ${de(g)}, when the entry says it was logged`);let R=ws(o.body),C=b(new Uint8Array(await crypto.subtle.digest("SHA-256",n)));if(R.hash!==C)throw new Error("The file's SHA-256 is not the one Rekor logged: the file is not the one signed");if(!pt(M(R.signature,"The logged signature"),c))throw new Error("The bundle's signature is not the one Rekor logged");let A=ut(Z(M(R.publicKey,"The logged certificate")),"The logged certificate");if(!pt(A,l))throw new Error("The bundle's certificate is not the one Rekor logged");if(p.curve!=="P-256"||!await Ie(p.spki,"P-256","SHA-256",c,n))throw new Error("The signature over the file does not verify with the bundle's certificate");return await hs(p,g),ys(p,t),{integratedTime:o.integratedTime}}async function hs(n,e){if(!ln(n,e))throw new Error(`The signing certificate was valid ${de(n.notBefore)} to ${de(n.notAfter)}, not at ${de(e)} when Rekor logged it`);let t=[];for(let r of nn){let s=r.certChain.map(a=>lt(M(a,"A Fulcio certificate")));if(!await cn(n,s[0]))continue;let i=await fs(s,r.validFor,e);if(!i)return;t.push(`${r.uri} (valid from ${r.validFor.start}): ${i}`)}throw new Error(t.length>0?`The signing certificate's CA is not trusted at ${de(e)}: ${t.join("; ")}`:"The signing certificate was not issued by a Fulcio CA in the Sigstore trust root")}async function fs(n,e,t){if(!un(t,e))return"the trust root says it was not issuing certificates then";for(let[r,s]of n.entries()){if(!ln(s,t))return`its certificate ${r} was not valid then`;let i=n[r+1]??s;if(!await cn(s,i))return`its certificate ${r} is not signed by the next`}}async function cn(n,e){return pt(n.issuer,e.subject)?Ie(e.spki,e.curve,n.signatureHash,n.signature,n.tbs):!1}function ys(n,e){let t=n.extensions.get(os);if(!t)throw new Error("The signing certificate names no identity");let r=D(w(X(t),gs,"The subject alternative name")),s=r.filter(l=>l.tag===ps).map(l=>Z(q(l)));if(s.length!==1||r.length!==1||s[0]!==e.identity)throw new Error(`The release was signed by ${JSON.stringify(s.length===1?s[0]:s)}, not by ${e.identity}`);let i=n.extensions.get(ls),a=n.extensions.get(us),o=i?Z(q(w(X(i),ds,"The OIDC issuer"))):a?Z(a):void 0;if(o!==e.issuer)throw new Error(`The signing certificate's OIDC issuer is ${o===void 0?"missing":JSON.stringify(o)}, not ${e.issuer}`);let c=n.extensions.get(as);if(!c||!on(c).includes(cs))throw new Error("The signing certificate is not for code signing")}function bs(n){let e=n;if(typeof e=="string")try{e=JSON.parse(e)}catch{throw new Error("The bundle is not JSON")}let t=e,r=t?.rekorBundle?.Payload;if(!(typeof t?.base64Signature=="string"&&typeof t.cert=="string"&&typeof t.rekorBundle?.SignedEntryTimestamp=="string"&&typeof r?.body=="string"&&typeof r.logID=="string"&&/^[0-9a-fA-F]{64}$/.test(r.logID)&&Number.isSafeInteger(r.integratedTime)&&r.integratedTime>=0&&Number.isSafeInteger(r.logIndex)&&r.logIndex>=0))throw new Error("The bundle is not a cosign bundle with a Rekor entry");return t}function ws(n){let e;try{e=JSON.parse(Z(M(n,"The logged entry")))}catch{throw new Error("The logged entry is not JSON")}let t=e?.spec?.data?.hash,r=e?.spec?.signature;if(e?.kind!=="hashedrekord"||t?.algorithm!=="sha256"||typeof t.value!="string"||typeof r?.content!="string"||typeof r.publicKey?.content!="string")throw new Error("The logged entry is not a SHA-256 hashedrekord");return{hash:t.value.toLowerCase(),signature:r.content,publicKey:r.publicKey.content}}function ln(n,e){return n.notBefore<=e&&e<=n.notAfter}function un(n,e){return Date.parse(e.start)<=n&&(e.end===void 0||n<=Date.parse(e.end))}function de(n){return new Date(n).toISOString()}function pt(n,e){return n.length===e.length&&n.every((t,r)=>t===e[r])}var dt=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"}),Rs=["mrtd","rtmr0","rtmr1","rtmr2","rtmr3"],dn="https://cloud.calimero.network";async function gn(n,e,t={}){let r=typeof n=="string"?new TextEncoder().encode(n):n;await an(r,e,{identity:t.identity??dt.identity,issuer:t.issuer??dt.issuer},t.signature);let s;try{s=JSON.parse(new TextDecoder().decode(r))}catch{throw new Error("The signed release is not JSON")}if(s?.role!=="node")throw new Error(`The signed release is a ${JSON.stringify(s?.role)} release, not a node one`);let i=Object.values(s.profiles??{}),a=o=>Rs.every(c=>/^[0-9a-f]{96}$/i.test(String(o?.[c])));if(typeof s.tag!="string"||i.length===0||!i.every(a))throw new Error("The signed file is not a release's published-mrtds.json: it lists no measured profiles");if(t.expectedVersion!==void 0&&s.tag!==t.expectedVersion)throw new Error(`The signed release is ${s.tag}, not ${t.expectedVersion}`);return s}async function mn(n,e={}){let t=await(e.fetch??fetch)(n,{headers:{accept:"application/json"}});if(!t.ok)throw new Error(`Fetching the node release from ${n} failed: HTTP ${t.status}`);let r;try{r=(await t.json())?.data}catch{throw new Error(`${n} did not answer with JSON`)}if(typeof r?.version!="string"||typeof r.publishedMrtds!="string"||typeof r.bundle!="string")throw new Error(`${n} did not answer with a signed node release`);return{version:r.version,publishedMrtds:r.publishedMrtds,bundle:r.bundle}}function hn(n){let e=/^merotee-.+-(\d+)-(\d+)-(\d+)$/.exec(n);if(!e)throw new Error(`${JSON.stringify(n)} is not the image of a mero-tee node release`);return`${Number(e[1])}.${Number(e[2])}.${Number(e[3])}`}async function fn(n,e={}){let t=`${n.replace(/\/+$/,"")}/admin-api/tee/info`,r=await(e.fetch??fetch)(t,{headers:{accept:"application/json"}});if(!r.ok)throw new Error(`Fetching ${t} failed: HTTP ${r.status}`);let s;try{s=(await r.json())?.data?.osImage}catch{throw new Error(`${t} did not answer with JSON`)}if(typeof s!="string")throw new Error(`${t} did not name the node's image`);return hn(s)}function yn(n,e){return`${n.replace(/\/+$/,"")}/api/tee/node-releases/${Pe(e,"version")}`}async function bn(n){let e=Pe(n.minReleaseVersion,"minReleaseVersion"),t=Pe(n.release?.version,"The release version"),r=await gn(n.release.publishedMrtds,n.release.bundle,{expectedVersion:t,identity:n.identity,issuer:n.issuer});if(xs(t,e)<0)throw new Error(`Release ${t} is older than the minimum trusted, ${e}`);return ct([r],{profile:n.profile})}function wn(n){return Pe(n.minReleaseVersion,"minReleaseVersion"),Object.assign(async t=>{let r=await bn({release:await n.release(),profile:n.profile,minReleaseVersion:n.minReleaseVersion,identity:n.identity,issuer:n.issuer});return at({dcapVerify:n.dcapVerify,fetchCollateral:n.fetchCollateral,now:n.now,...r})(t)},{includeCollateral:!0})}function As(n){let{baseUrl:e,releaseSource:t,applicationId:r,applicationHash:s,fetch:i,...a}=n,o=i??((l,p)=>fetch(l,p));return pe({baseUrl:e,verify:wn({...a,release:async()=>{let l=await fn(e,{fetch:o});return typeof t=="function"?t({baseUrl:e,version:l,fetch:o}):mn(yn(t??dn,l),{fetch:o})}}),applicationId:r,applicationHash:s,fetch:o})}var Rn=/^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/;function Pe(n,e){let t=typeof n=="string"?Rn.exec(n):null,r=t?.[4];if(!t||r!==void 0&&r.split(".").some(s=>s===""))throw new Error(`${e} is ${JSON.stringify(n)}, not a release version like 2.3.87`);return n}function xs(n,e){let[t,r]=pn(n),[s,i]=pn(e);for(let c=0;c<3;c+=1)if(t[c]!==s[c])return t[c]<s[c]?-1:1;if(r===void 0||i===void 0)return r===i?0:r===void 0?1:-1;let a=r.split("."),o=i.split(".");for(let c=0;c<Math.max(a.length,o.length);c+=1){let[l,p]=[a[c],o[c]];if(l===void 0||p===void 0)return l===void 0?-1:1;let[d,m]=[/^\d+$/.test(l),/^\d+$/.test(p)],f=d&&m?Math.sign(Number(l)-Number(p)):d!==m?d?-1:1:l<p?-1:l>p?1:0;if(f!==0)return f}return 0}function pn(n){let e=Rn.exec(n);return[[Number(e[1]),Number(e[2]),Number(e[3])],e[4]]}var mt=12,Cs=new TextEncoder().encode("calimero.namespace.v1"),vs=0,An={GroupCreated:0,GroupReparented:1,GroupDeleted:2,AdminChanged:3,PolicyUpdated:4,MemberJoined:5,KeyDelivery:6,MemberJoinedOpen:7,MemberJoinedAt:8,NamespaceCreatedV2:9,MemberJoinedViaTeeAttestation:10};function gt(n,e){if(n.length!==32)throw new Error(`${e} must be 32 bytes, got ${n.length}`);return new Uint8Array(n)}function xn(n,e){if(n==null)return new Uint8Array([0]);if(n.length!==32)throw new Error(`${e} must be 32 bytes, got ${n.length}`);return h(new Uint8Array([1]),new Uint8Array(n))}function Cn(n){let e=new TextEncoder().encode(n);return h(k(e.length),e)}function De(n){let e=n.invitation,t=e.admitters??[],r=n.admitter_addrs??[];return h(gt(e.inviter_identity,"inviter_identity"),gt(e.group_id,"group_id"),S(e.expiration_timestamp),gt(e.secret_salt,"secret_salt"),new Uint8Array([e.invited_role]),k(t.length),...t.map((s,i)=>y(s,`admitters[${i}]`,32)),Cn(n.inviter_signature),n.inviter_account?h(new Uint8Array([1]),y(n.inviter_account,"inviter_account",32)):new Uint8Array([0]),k(r.length),...r.map(Cn),xn(n.application_id,"application_id"),xn(n.app_key,"app_key"))}async function vn(n){let e=n.parentOpHashes??[],t=y(n.credential,"credential",n.credential.length/2),r=BigInt(n.invitation.invitation.expiration_timestamp??0)!==0n,s=n.joinedAt??BigInt(Math.floor(Date.now()/1e3)),i=r?h(new Uint8Array([An.MemberJoinedAt]),y(n.member,"member",32),De(n.invitation),S(s),t):h(new Uint8Array([An.MemberJoined]),y(n.member,"member",32),De(n.invitation),t),a=h(new Uint8Array([vs]),i),o=await I(n.deviceSecret),c=await P(n.deviceSecret),l=h(new Uint8Array([mt]),y(n.namespaceId,"namespaceId",32),k(e.length),...e.map((m,f)=>y(m,`parentOpHashes[${f}]`,32)),c,S(n.nonce),a),p=new Uint8Array(await crypto.subtle.sign("Ed25519",o,h(Cs,l))),d=new Uint8Array([0]);return b(h(l,p,d))}var ks=new TextEncoder().encode("calimero.auth.login.v1"),kn={webOrigin:0,codeSigningId:1,cli:2};function Sn(n){let e=new TextEncoder;switch(n.kind){case"webOrigin":return e.encode(n.origin);case"codeSigningId":return e.encode(n.id);case"cli":return new Uint8Array(0)}}function Ss(n){return h(Uint8Array.from([kn[n.kind]]),Sn(n))}function Ts(n){let e=Uint8Array.from([kn[n.kind]]);if(n.kind==="cli")return e;let t=Sn(n);return h(e,k(t.length),t)}async function Ue(n){let e=y(n.node,"node",32),t=y(n.challenge,"challenge",32),r=y(n.sessionKey,"sessionKey",32),s=await I(n.deviceSecret),i=await P(n.deviceSecret),a=S(n.issuedAt),o=S(n.expiresAt),c=await U(ks,[e,Ss(n.audience),t,r,i,a,o]),l=new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},s,c));return b(h(e,Ts(n.audience),t,r,i,a,o,l))}var Es=300;async function ht(){let n=b(crypto.getRandomValues(new Uint8Array(32)));return{publicKey:b(await P(n)),secret:n}}function Is(n){switch(n.kind){case"webOrigin":return n.origin;case"codeSigningId":return n.id;case"cli":return"cli"}}async function Tn(n){let e=n.nodeUrl.replace(/\/+$/,""),t=n.timeoutMs??1e4,r=async(m,f)=>{let g=new AbortController,R=setTimeout(()=>g.abort(),t),C;try{let x={...f,signal:g.signal};C=n.fetch?await n.fetch(`${e}${m}`,x):await globalThis.fetch(`${e}${m}`,x)}catch(x){throw new v(0,x instanceof Error?x.name:"NetworkError",`${e}${m}`,new Headers,x instanceof Error?x.message:String(x))}finally{clearTimeout(R)}let A=await C.text().catch(()=>"");if(!C.ok)throw new v(C.status,C.statusText,`${e}${m}`,C.headers,A);return A?JSON.parse(A):{}},s=await r("/auth/challenge",{method:"GET",headers:{Accept:"application/json"}}),i=s.challenge??s.data?.challenge;if(!i)throw new Error("the node issued no challenge");let a=await ht(),o=Math.floor(Date.now()/1e3),c=await Ue({node:n.node,audience:n.audience,challenge:i,sessionKey:a.publicKey,issuedAt:o,expiresAt:o+(n.ttlSeconds??Es),deviceSecret:n.deviceSecret}),l=await r("/auth/token",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({auth_method:"account_proof",public_key:a.publicKey,client_name:n.clientName??Is(n.audience),timestamp:o,provider_data:{challenge:i,login_statement:c,account_proof:n.accountProof}})}),p=l.access_token??l.data?.access_token,d=l.refresh_token??l.data?.refresh_token;if(!p)throw new Error("the node minted no session");return{accessToken:p,refreshToken:d??"",sessionKey:a.publicKey,sessionSecret:a.secret}}var En=[2428,2429,2528,2529],Ps="localhost",Ds=2e3;function In(n){return`http://${Ps}:${n}`}function Pn(n,e){let t=n.endsWith("/")?n:`${n}/`;return new URL(e,t).toString()}async function Dn(n,e={}){let{timeoutMs:t=Ds,signal:r}=e;if(r?.aborted)return!1;let s=new AbortController,i=()=>s.abort(),a=r;a&&a.addEventListener("abort",i,{once:!0});let o=setTimeout(()=>s.abort(),t);try{let c=Pn(n,"admin-api/health"),l=await fetch(c,{method:"GET",signal:s.signal});if(!l.ok)return!1;try{let p=await l.json(),d=p?.data?.status!==void 0?p?.data?.status:p?.status;return d===void 0?!0:typeof d=="string"&&d.toLowerCase()==="alive"}catch{return!0}}catch{return!1}finally{clearTimeout(o),a&&a.removeEventListener("abort",i)}}async function Us(n={}){let{ports:e=En,timeoutMs:t,signal:r}=n;return(await Promise.all(e.map(async i=>{let a=In(i);return await Dn(a,{timeoutMs:t,signal:r})?a:null}))).filter(i=>i!==null)}export{O as AdminApiClient,G as AuthApiClient,_ as AuthRevokedError,ne as CAPABILITIES,$ as CloudClient,En as DEFAULT_LOCAL_NODE_PORTS,dn as DEFAULT_RELEASE_MIRROR,se as EphemeralClient,Jt as HANDSHAKE_PATH,v as HTTPError,Te as IntentRefusedError,Ze as LocalStorageTokenStore,Xe as MemoryTokenStore,ke as MeroJs,dt as NODE_RELEASE_SIGNER,ae as RelayClient,re as RpcClient,we as RpcError,le as SEALED_CONTENT_TYPE,zt as SEALED_PATH,mt as SIGNED_NAMESPACE_OP_SCHEMA_VERSION,z as SealedTransportError,W as SseClient,ue as StaleTransportKeyError,ee as WebHttpClient,J as WsClient,xe as accountForRoot,Mt as accountRootFromPhrase,L as accountRootFromSecret,pr as admitterAddrsFromNetworkStatus,je as buildAuthLoginUrl,ye as callerProof,Be as classifyError,yn as cloudNodeReleaseUrl,_e as combineSignals,Vn as compareSemver,jr as connectCloud,fi as createAdminApiClient,xt as createAdminApiClientFromHttpClient,pe as createAttestedSealedFetch,Qs as createAuthApiClient,bt as createAuthApiClientFromHttpClient,mi as createBrowserAdminApiClient,Js as createBrowserAuthApiClient,F as createBrowserHttpClient,He as createHttpClient,nt as createLocalStorageNonceSource,tt as createMemoryNonceSource,hr as createMeroJs,hi as createNodeAdminApiClient,zs as createNodeAuthApiClient,ge as createNodeHttpClient,be as createProofSigner,at as createQuoteVerifier,Gn as createRetryableMethod,Zt as createSealedFetch,As as createSignedReleaseSealedFetch,wn as createSignedReleaseVerifier,qe as createTimeoutSignal,Ge as createUniversalHttpClient,Je as deviceCertPayload,Us as discoverLocalNodes,De as encodeSignedInvitation,Xt as fetchAttestedTransportKey,mn as fetchNodeRelease,fn as fetchNodeReleaseVersion,Ut as generateAccountRoot,ht as generateSessionKey,Oe as hasCap,li as hexEncodeUtf8,et as intentHash,Bn as isSettled,Ae as jsonCodec,In as localNodeUrl,Tn as login,Et as mintDeviceId,Pn as nodeEndpoint,hn as nodeReleaseVersionFromImage,Ke as parseAuthCallback,Dn as probeNodeHealth,wt as redeemInvitation,Ve as requestBodyHash,ve as routingProofHeaders,ni as shouldRetain,oe as signAccountLink,Ce as signAccountLogin,Pt as signDeviceCert,Ue as signLoginStatement,vn as signMemberJoinOp,fe as signRequest,Gt as signRoutingChallenge,Se as signWarrant,Yt as transportKeyBinding,bn as trustSignedRelease,ct as trustedMeasurementsFromReleases,gn as verifySignedNodeRelease,Le as withCap,me as withRetry,Xs as withoutCap};
|
|
1
|
+
function _e(n){let e=n.filter(Boolean);if(e.length===0)return;let t=AbortSignal;if(typeof t.any=="function")try{return t.any(e)}catch{}let r=new AbortController,s=i=>{r.abort(i.target.reason);for(let a of e)a.removeEventListener("abort",s)};for(let i of e){if(i.aborted)return AbortSignal.abort(i.reason);i.addEventListener("abort",s,{once:!0})}return r.signal}function qe(n){if(typeof AbortSignal.timeout=="function")return AbortSignal.timeout(n);let e=new AbortController;return setTimeout(()=>{e.abort(new DOMException("Timeout","TimeoutError"))},n),e.signal}var Gn=new Set(["token_reuse","token_revoked"]);function On(n){if(n)try{let e=JSON.parse(n),t=e?.error;if(typeof t=="string"&&t.trim()!=="")return t;let r=t?.message;if(typeof r=="string"&&r.trim()!=="")return r;let s=e?.detail;if(typeof s=="string"&&s.trim()!=="")return s}catch{}}var v=class extends Error{constructor(t,r,s,i,a){let o=On(a)??(t===0&&a?.trim()?a.trim():void 0);super(o?`HTTP ${t} ${r}: ${o}`:`HTTP ${t} ${r}`);this.status=t;this.statusText=r;this.url=s;this.headers=i;this.bodyText=a;this.name="HTTPError";this.explanation=o}toJSON(){return{status:this.status,statusText:this.statusText,url:this.url,headers:Rt(this.headers),bodyText:this.bodyText}}},_=class extends v{constructor(t,r,s,i,a,o){super(r,s,i,a,o);this.reason=t;this.name="AuthRevokedError";this.message=`Authentication revoked (${t}): HTTP ${r} ${s}`}};function Rt(n){let e={};return n.forEach((t,r)=>{e[r]=t}),e}function Ln(n){try{return new URL(n).pathname}catch{let e=n.indexOf("?");return e===-1?n:n.slice(0,e)}}var ee=class{constructor(e){this.transport=e;this.refreshTokenPromise=null;this.onTokenRefreshPromise=null}async get(e,t){return this.request(e,{...t,method:"GET"})}async post(e,t,r){return this.request(e,{...r,method:"POST",body:t?JSON.stringify(t):void 0,headers:{"Content-Type":"application/json",...r?.headers}})}async put(e,t,r){return this.request(e,{...r,method:"PUT",body:t?JSON.stringify(t):void 0,headers:{"Content-Type":"application/json",...r?.headers}})}async delete(e,t){return this.request(e,{...t,method:"DELETE"})}async patch(e,t,r){return this.request(e,{...r,method:"PATCH",body:t?JSON.stringify(t):void 0,headers:{"Content-Type":"application/json",...r?.headers}})}async head(e,t){let r=await this.makeRequest(e,{...t,method:"HEAD",parse:"response"});return{headers:Rt(r.headers),status:r.status}}async request(e,t){return this.makeRequest(e,t)}async makeRequest(e,t,r=0,s){let a=this.buildUrl(e),o=s??Date.now(),c=this.createAbortSignal(t),l=await this.buildHeaders(t?.headers),d;l instanceof Headers?(d={},l.forEach((g,R)=>{d[R]=g})):d=l;let p={method:t?.method||"GET",headers:d},m=t?.body instanceof ReadableStream||typeof t?.body=="object"&&t?.body!==null&&"getReader"in t.body&&!(t.body instanceof Blob);(t?.body!==void 0&&!m||t?.body!==void 0&&m&&r===0)&&(p.body=t.body);let f;if(r>0&&s!==void 0){let g=t?.timeoutMs||this.transport.timeoutMs;if(g){let R=Date.now()-o,C=Math.max(0,g-R);f=this.createAbortSignal({...t,timeoutMs:C})}else f=this.createAbortSignal(t)}else f=c;if(f&&(p.signal=f),this.transport.credentials!==void 0&&(p.credentials=this.transport.credentials),t?.mode!==void 0&&(p.mode=t.mode),t?.cache!==void 0&&(p.cache=t.cache),t?.redirect!==void 0&&(p.redirect=t.redirect),t?.referrer!==void 0&&(p.referrer=t.referrer),t?.referrerPolicy!==void 0&&(p.referrerPolicy=t.referrerPolicy),t?.integrity!==void 0&&(p.integrity=t.integrity),t?.keepalive!==void 0&&(p.keepalive=t.keepalive),this.transport.getProof){let g=await this.transport.getProof({method:p.method??"GET",path:Ln(a),body:p.body});g&&(d["X-Calimero-Proof"]=g)}try{let g=await this.transport.fetch(a,p);if(!g.ok){let R=await this.getBodyText(g),C=new v(g.status,g.statusText,a,g.headers,R),A=g.headers.get("x-auth-error");if((g.status===401||g.status===403)&&A&&Gn.has(A)){if(this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,this.transport.onAuthRevoked)try{await this.transport.onAuthRevoked()}catch{}throw new _(A,g.status,g.statusText,a,g.headers,R)}let x=t?.signal?.aborted===!0;if(g.status===401&&this.transport.refreshToken&&A==="token_expired"&&r<1&&!m&&!x)try{let T=this.refreshTokenPromise;T||(T=this.transport.refreshToken(),this.refreshTokenPromise=T);let H=await T;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 E=this.onTokenRefreshPromise;E||(E=this.transport.onTokenRefresh(H),this.onTokenRefreshPromise=E),await E,this.refreshTokenPromise=null,this.onTokenRefreshPromise=null;let N=t?.timeoutMs||this.transport.timeoutMs;if(N&&s!==void 0){let B=Date.now()-o;if(N-B<=0)throw C}return this.makeRequest(e,t,r+1,o)}catch(T){throw this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,T instanceof Error&&T.message.includes("onTokenRefresh")?T:C}throw C}return this.parseResponse(g,t?.parse)}catch(g){throw g instanceof v||g instanceof Error&&g.message.includes("onTokenRefresh")?g:new v(0,"Network Error",a,new Headers,g instanceof Error?g.message:"Unknown error")}}buildUrl(e){if(e.startsWith("http://")||e.startsWith("https://"))return e;let t=this.transport.baseUrl;return e.startsWith("/")?`${t.endsWith("/")?t.slice(0,-1):t}${e}`:`${t.endsWith("/")?t:`${t}/`}${e}`}createAbortSignal(e){let t=[];this.transport.defaultAbortSignal&&t.push(this.transport.defaultAbortSignal),e?.signal&&t.push(e.signal);let r=e?.timeoutMs||this.transport.timeoutMs;return r&&t.push(qe(r)),t.length>0?_e(t):void 0}async buildHeaders(e){let t={...this.transport.defaultHeaders};if(this.transport.getAuthToken)try{let r=await this.transport.getAuthToken();r&&r.trim()!==""&&(t.Authorization=`Bearer ${r}`)}catch{}return e&&(e instanceof Headers?e.forEach((r,s)=>{t[s]=r}):Array.isArray(e)?e.forEach(([r,s])=>{t[r]=s}):Object.assign(t,e)),t}async parseResponse(e,t){switch(t){case"text":return await e.text();case"blob":return await e.blob();case"arrayBuffer":return await e.arrayBuffer();case"response":return e;default:{let r=await e.text();if(!r)return null;try{return JSON.parse(r)}catch{throw new Error(`Expected a JSON response (status ${e.status}) but body was not JSON: ${r.slice(0,200)}`)}}}}async getBodyText(e){try{let t=await e.text();return t.length>65536?t.slice(0,65536)+"...":t}catch{return""}}};function He(n){return new ee(n)}function F(n){let e={fetch:(t,r)=>n.fetch?n.fetch(t,r):globalThis.fetch(t,r),baseUrl:n.baseUrl,getAuthToken:n.getAuthToken,getProof:n.getProof,onTokenRefresh:n.onTokenRefresh,refreshToken:n.refreshToken,onAuthRevoked:n.onAuthRevoked,defaultHeaders:n.defaultHeaders,timeoutMs:n.timeoutMs,credentials:n.credentials,defaultAbortSignal:n.defaultAbortSignal};return He(e)}function me(n){let e=n.fetch??globalThis.fetch;if(!e)throw new Error("No fetch implementation available. Please provide a fetch implementation (e.g., undici.fetch) or use Node.js 18+ which has native fetch support.");let r={fetch:e===globalThis.fetch?(s,i)=>globalThis.fetch(s,i):(s,i)=>e(s,i),baseUrl:n.baseUrl,getAuthToken:n.getAuthToken,getProof:n.getProof,onTokenRefresh:n.onTokenRefresh,refreshToken:n.refreshToken,onAuthRevoked:n.onAuthRevoked,defaultHeaders:n.defaultHeaders,timeoutMs:n.timeoutMs,credentials:n.credentials,defaultAbortSignal:n.defaultAbortSignal};return He(r)}function Ge(n){return typeof window<"u"?F(n):me(n)}function $n(n,e){if(e<=0)return!1;let r=n?.name;if(r==="TimeoutError")return!0;if(r==="AbortError")return!1;let s=n;if("status"in s&&typeof s.status=="number"){let i=s.status;return i>=500||i===429}return r==="TypeError"}function Bn(n){let t=250*Math.pow(2,n-1),r=(Math.random()-.5)*.4*t;return Math.max(0,t+r)}async function he(n,e={}){let{attempts:t=3}=e,r;for(let s=1;s<=t;s++)try{return await n(s)}catch(i){if(r=i,!$n(r,t-s))throw r;let a=Bn(s),l=r.headers?.get?.("Retry-After");if(l){let d=parseInt(l,10);if(!isNaN(d))a=Math.max(a,d*1e3);else{let p=new Date(l);if(!isNaN(p.getTime())){let m=Math.max(0,p.getTime()-Date.now());a=Math.max(a,Math.min(m,6e4))}}}await new Promise(d=>setTimeout(d,a))}throw r||new Error("Retry failed without error")}function Kn(n,e={}){return async(...t)=>he(()=>n(...t),e)}var G=class{constructor(e){this.httpClient=e}async getHealth(){let e=await this.httpClient.get("/auth/health");if(!e.data)throw new Error("Health response data is null");return e.data}async getIdentity(){let e=await this.httpClient.get("/admin/identity");if(!e.data)throw new Error("Identity response data is null");return e.data}async getProviders(){let e=await this.httpClient.get("/auth/providers");if(!e.data)throw new Error("Providers response data is null");return e.data}async getLoginPage(){return this.httpClient.get("/auth/login",{parse:"text"})}async generateTokens(e){return this.httpClient.post("/auth/token",e)}async refreshToken(e){return this.httpClient.post("/auth/refresh",e)}async generateMockTokens(e){return this.httpClient.post("/auth/mock-token",e)}async validateToken(e){try{let t=await this.validateTokenGet(e);return{valid:t.status===200,headers:t.headers,status:t.status}}catch{return{valid:!1,headers:{},status:401}}}async validateTokenGet(e){let t=await this.httpClient.head("/auth/validate",{headers:{Authorization:`Bearer ${e}`}});return{status:t.status,headers:t.headers}}async revokeTokens(e){let t=await this.httpClient.post("/admin/revoke",e);if(!t.data)throw new Error("Revoke tokens response data is null");return t.data}async listRootKeys(){let e=await this.httpClient.get("/admin/keys");if(!e.data)throw new Error("Root keys response data is null");return e.data}async createRootKey(e){let t=await this.httpClient.post("/admin/keys",e);if(!t.data)throw new Error("Create root key response data is null");return t.data}async deleteRootKey(e){return this.httpClient.delete(`/admin/keys/${e}`)}async listClientKeys(){let e=await this.httpClient.get("/admin/keys/clients");if(!e.data)throw new Error("Client keys response data is null");return e.data}async generateClientKey(e){return this.httpClient.post("/admin/client-key",e)}async deleteClientKey(e,t){return this.httpClient.delete(`/admin/keys/${e}/clients/${t}`)}async getKeyPermissions(e){return this.httpClient.get(`/admin/keys/${e}/permissions`)}async updateKeyPermissions(e,t){return this.httpClient.put(`/admin/keys/${e}/permissions`,{add:t.add,remove:t.remove})}};var te=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 Zs(n){let e=new te;return new G(e)}function ei(n){let e=new te;return new G(e)}function ti(n){let e=new te;return new G(e)}function At(n,e){return new G(n)}var ne={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};function Oe(n,e){let t=e>>>0;return(n&t)>>>0===t}function Le(n,e){return(n|e)>>>0}function ri(n,e){return(n&~e)>>>0}var jn={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 Vn(n){switch(n){case 0:return"unreachable";case 400:return"invalid";case 401:return"unauthorized";case 403:return"forbidden";case 404:return"not-found";case 409:return"conflict";case 410:return"gone";case 413:return"too-large";case 429:return"rate-limited";case 503:case 504:return"unavailable"}return n>=500&&n<600?"server":n>=400&&n<500?"invalid":"unknown"}function Fn(n){if(!n||typeof n!="object")return;let e=n;for(let t of[e.status,e.response?.status,e.statusCode])if(typeof t=="number"&&Number.isFinite(t))return t}function $e(n,e="Request failed"){if(typeof n=="string")return n.trim()||e;if(!n||typeof n!="object")return e;let t=n;for(let r of[t.explanation,t.response?.data?.error,t.response?.data?.message,t.data?.message,t.error,t.message])if(typeof r=="string"&&r.trim())return r;return e}function Be(n){let e=Fn(n),t;return e!==void 0?t=Vn(e):n instanceof TypeError?t="unreachable":t="unknown",{kind:t,status:e,retryable:jn[t],message:$e(n)}}function Wn(n){return n.status!=="failed"||!n.retryable}function ai(n){return!Wn(n)}function Jn(n){let e=n.toLowerCase();return e.includes("invitation has expired")||e.includes("invitation expired")||/\binvitation for group .+? expired at \d+/.test(e)?"expired":e.includes("malformed")||e.includes("does not match namespace_id")||e.includes("invalid invitation")||/\binvitation for group .+? is invalid:/.test(e)?"invalid":null}function zn(n,e){let{kind:t,status:r}=Be(n),s=Jn(e);return r===401?{reason:"signed-out",retryable:!0}:r===400?{reason:s??"invalid",retryable:!1}:r===410?{reason:"expired",retryable:!1}:r===403?{reason:"refused",retryable:!1}:r===409?{reason:s??"refused",retryable:!1}:t==="unavailable"?{reason:"no-one-online",retryable:!0}:t==="unreachable"?{reason:"node-unreachable",retryable:!0}:s?{reason:s,retryable:!1}:{reason:"unknown",retryable:!0}}async function xt(n,e){let{namespaceId:t,invitation:r,teamName:s}=n,i=null;try{await e.join(t,r)}catch(d){i=d}let a=null;try{a=(await e.memberships()).includes(t)}catch{a=null}if(i===null)return{status:"joined",namespaceId:t,teamName:s};if(a===!0)return{status:"already-member",namespaceId:t,teamName:s};let o=$e(i,"Could not join. Check the invitation."),{reason:c,retryable:l}=zn(i,o);return{status:"failed",namespaceId:t,message:o,reason:c,retryable:l}}function u(n){return n?.data}function Qn(n,e){let[t,r]=Ct(n),[s,i]=Ct(e),a=t.split("."),o=s.split("."),c=Math.max(a.length,o.length);for(let m=0;m<c;m++){let f=vt(a[m]??"0",o[m]??"0");if(f!==0)return f}if(r===void 0&&i===void 0)return 0;if(r===void 0)return 1;if(i===void 0)return-1;let l=r.split("."),d=i.split("."),p=Math.max(l.length,d.length);for(let m=0;m<p;m++){if(m>=l.length)return-1;if(m>=d.length)return 1;let f=vt(l[m],d[m]);if(f!==0)return f}return 0}function Ct(n){let e=n.split("+",1)[0],t=e.indexOf("-");return t===-1?[e,void 0]:[e.slice(0,t),e.slice(t+1)]}function vt(n,e){let t=/^\d+$/.test(n),r=/^\d+$/.test(e);if(t&&r){let s=Number(n)-Number(e);return s<0?-1:s>0?1:0}return t?-1:r?1:n<e?-1:n>e?1:0}async function Yn(n,e,t){return he(async()=>{let r=await fetch(n,{signal:AbortSignal.timeout(1e4)});if(!r.ok){let s=new Error(`registry ${e} fetch failed (${r.status}) for ${t}`);throw s.status=r.status,s}return r},{attempts:3})}var O=class{constructor(e){this.httpClient=e}async healthCheck(){return u(await this.httpClient.get("/admin-api/health"))}async readinessCheck(){return u(await this.httpClient.get("/admin-api/ready"))}async isAuthed(){return this.httpClient.get("/admin-api/is-authed")}async installApplication(e){return u(await this.httpClient.post("/admin-api/install-application",e))}async getRegistryVersions(e,t){let r=new URL("/api/v2/bundles",new URL(e).origin);r.searchParams.set("package",t);let i=await(await Yn(r.toString(),"versions",t)).json();return(Array.isArray(i)?i:[]).map(a=>a.appVersion).filter(a=>typeof a=="string").sort((a,o)=>Qn(o,a))}async installDevApplication(e){return u(await this.httpClient.post("/admin-api/install-dev-application",e))}async uninstallApplication(e){return u(await this.httpClient.delete(`/admin-api/applications/${e}`))}async listApplications(){return u(await this.httpClient.get("/admin-api/applications"))}async getApplication(e){return u(await this.httpClient.get(`/admin-api/applications/${e}`))}async listApplicationVersions(e){return u(await this.httpClient.get(`/admin-api/applications/${e}/versions`))}async getApplicationAbi(e,t){let r=t?`?service_name=${encodeURIComponent(t)}`:"";return u(await this.httpClient.get(`/admin-api/applications/${e}/abi${r}`))}async listPackages(){let e=await this.httpClient.get("/admin-api/packages");return e?.data??e}async listPackageVersions(e){let t=await this.httpClient.get(`/admin-api/packages/${encodeURIComponent(e)}/versions`);return t?.data??t}async getLatestPackageVersion(e){return this.httpClient.get(`/admin-api/packages/${encodeURIComponent(e)}/latest`)}async createContext(e){let t={...e,initializationParams:e.initializationParams??[]};return u(await this.httpClient.post("/admin-api/contexts",t))}async deleteContext(e){return u(await this.httpClient.delete(`/admin-api/contexts/${e}`))}async getContexts(){return u(await this.httpClient.get("/admin-api/contexts"))}async getContext(e){return u(await this.httpClient.get(`/admin-api/contexts/${e}`))}async getContextsForApplication(e){return u(await this.httpClient.get(`/admin-api/contexts/for-application/${e}`))}async generateContextIdentity(){return u(await this.httpClient.post("/admin-api/identity/context",{}))}async getContextIdentities(e){return u(await this.httpClient.get(`/admin-api/contexts/${e}/identities`))}async getContextIdentitiesOwned(e){return u(await this.httpClient.get(`/admin-api/contexts/${e}/identities-owned`))}async joinContext(e){return u(await this.httpClient.post(`/admin-api/contexts/${e}/join`,{}))}async getContextGroup(e){return u(await this.httpClient.get(`/admin-api/contexts/${e}/group`))}async getContextStorage(e){return u(await this.httpClient.get(`/admin-api/contexts/${e}/storage`))}async syncContext(e){let t=e?`/admin-api/contexts/sync/${e}`:"/admin-api/contexts/sync";await this.httpClient.post(t,{})}async resyncContext(e,t={}){return await this.httpClient.post(`/admin-api/contexts/${e}/resync`,t)??{contextId:e,resyncStarted:!0}}async inviteSpecializedNode(e){return u(await this.httpClient.post("/admin-api/contexts/invite-specialized-node",e))}async updateContextApplication(e,t){await this.httpClient.post(`/admin-api/contexts/${e}/application`,t)}async getContextsWithExecutorsForApplication(e){let t=await this.httpClient.get(`/admin-api/contexts/with-executors/for-application/${e}`);return Array.isArray(t)?t:t?.contexts??t?.data??[]}async uploadBlob(e){let t=new URLSearchParams;e.hash&&t.set("hash",e.hash),e.contextId&&t.set("context_id",e.contextId);let r=t.toString(),s=r?`/admin-api/blobs?${r}`:"/admin-api/blobs",i=u(await this.httpClient.request(s,{method:"PUT",body:e.data,headers:{"Content-Type":"application/octet-stream"}}));return{blobId:i.blob_id,size:i.size}}async deleteBlob(e){let t=await this.httpClient.delete(`/admin-api/blobs/${e}`);return{blobId:t.blob_id,deleted:t.deleted}}async listBlobs(){return{blobs:u(await this.httpClient.get("/admin-api/blobs")).blobs.map(t=>({blobId:t.blob_id,size:t.size}))}}blobPath(e,t){if(!t?.contextId)return`/admin-api/blobs/${e}`;let r=new URLSearchParams({context_id:t.contextId});return`/admin-api/blobs/${e}?${r.toString()}`}async getBlob(e,t){return this.httpClient.get(this.blobPath(e,t),{parse:"arrayBuffer"})}async getBlobInfo(e,t){let{headers:r}=await this.httpClient.head(this.blobPath(e,t)),s=Number(r["content-length"]);return{blobId:r["x-blob-id"]??e,size:Number.isFinite(s)?s:0,hash:r["x-blob-hash"],mimeType:r["x-blob-mime-type"],source:r["x-blob-source"]}}async createContextAlias(e){return u(await this.httpClient.post("/admin-api/alias/create/context",{alias:e.alias,contextId:e.contextId}))}async createApplicationAlias(e){return u(await this.httpClient.post("/admin-api/alias/create/application",{alias:e.alias,applicationId:e.applicationId}))}async lookupContextAlias(e){return u(await this.httpClient.post(`/admin-api/alias/lookup/context/${encodeURIComponent(e)}`,{}))}async lookupApplicationAlias(e){return u(await this.httpClient.post(`/admin-api/alias/lookup/application/${encodeURIComponent(e)}`,{}))}async deleteContextAlias(e){return u(await this.httpClient.post(`/admin-api/alias/delete/context/${encodeURIComponent(e)}`,{}))}async deleteApplicationAlias(e){return u(await this.httpClient.post(`/admin-api/alias/delete/application/${encodeURIComponent(e)}`,{}))}async listContextAliases(){return u(await this.httpClient.get("/admin-api/alias/list/context"))}async listApplicationAliases(){return u(await this.httpClient.get("/admin-api/alias/list/application"))}async createDeviceAlias(e){return u(await this.httpClient.post("/admin-api/alias/create/device",{alias:e.alias,deviceId:e.deviceId}))}async lookupDeviceAlias(e){return u(await this.httpClient.post(`/admin-api/alias/lookup/device/${encodeURIComponent(e)}`,{}))}async deleteDeviceAlias(e){return u(await this.httpClient.post(`/admin-api/alias/delete/device/${encodeURIComponent(e)}`,{}))}async listDeviceAliases(){return u(await this.httpClient.get("/admin-api/alias/list/device"))}async listNamespaces(){return u(await this.httpClient.get("/admin-api/namespaces"))}async getNamespace(e){return u(await this.httpClient.get(`/admin-api/namespaces/${e}`))}async getNodeIdentity(){return u(await this.httpClient.get("/admin-api/identity"))}async getNamespaceIdentity(e){let t=await this.getNodeIdentity();return{namespaceId:e,publicKey:t.publicKey,account:t.accountId}}async performIntent(e,t){return u(await this.httpClient.post(`/admin-api/contexts/${e}/intents`,t))}async queryContext(e,t){return u(await this.httpClient.post(`/admin-api/contexts/${e}/query`,t))}async getIntentRelay(e){return u(await this.httpClient.get(`/admin-api/contexts/${e}/intents`))}async listNamespacesForApplication(e){return u(await this.httpClient.get(`/admin-api/namespaces/for-application/${e}`))}async createNamespace(e){return u(await this.httpClient.post("/admin-api/namespaces",e))}async deleteNamespace(e){return u(await this.httpClient.request(`/admin-api/namespaces/${e}`,{method:"DELETE",body:"{}",headers:{"Content-Type":"application/json"}}))}async createNamespaceInvitation(e,t){return u(await this.httpClient.post(`/admin-api/namespaces/${e}/invite`,t??{}))}async admitJoin(e,t){return u(await this.httpClient.post(`/admin-api/namespaces/${e}/admit`,t,{timeoutMs:65e3}))}async joinNamespace(e,t){let r=u(await this.httpClient.post(`/admin-api/namespaces/${e}/join`,t,{timeoutMs:65e3}));return r&&r.namespaceId===void 0&&r.groupId!==void 0?{...r,namespaceId:r.groupId}:r}async redeemInvitation(e,t,r={}){let{groupName:s,teamName:i}=r;return xt({namespaceId:e,invitation:t,teamName:i},{join:async()=>{await this.joinNamespace(e,s===void 0?{invitation:t}:{invitation:t,groupName:s})},memberships:async()=>(await this.listNamespaces()??[]).map(a=>a.namespaceId)})}async createGroupInNamespace(e,t){return u(await this.httpClient.post(`/admin-api/namespaces/${e}/groups`,t??{}))}async listNamespaceGroups(e){return u(await this.httpClient.get(`/admin-api/namespaces/${e}/groups`))}async initAccountPairing(e){return u(await this.httpClient.post("/admin-api/account/pair-init",e))}async completeAccountPairing(e){return u(await this.httpClient.post("/admin-api/account/pair-complete",e))}async relinkAccountDevice(e,t){return u(await this.httpClient.post(`/admin-api/account/devices/${e}/relink`,t??{}))}async rescopeAccountDevice(e,t){return u(await this.httpClient.put(`/admin-api/account/devices/${encodeURIComponent(e)}/scope`,t))}async signWithAccountRoot(e){return u(await this.httpClient.post("/admin-api/account/sign-with-root",e))}async labelAccountDevice(e,t){return u(await this.httpClient.put(`/admin-api/account/devices/${encodeURIComponent(e)}/label`,t))}async listAccountDevices(){return(await this.httpClient.get("/admin-api/account/devices")).devices}async listAccountApplications(){return(await this.httpClient.get("/admin-api/account/applications")).applications}async revokeAccountDevice(e,t){return u(await this.httpClient.post(`/admin-api/namespaces/${e}/account/revoke`,t))}async getGroupInfo(e){return u(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 u(await this.httpClient.request(`/admin-api/groups/${e}`,{method:"DELETE",body:"{}",headers:{"Content-Type":"application/json"}}))}async listGroupMembers(e){let t=await this.httpClient.get(`/admin-api/groups/${e}/members`);if(!Array.isArray(t?.members)){let r=String(e).replace(/[\r\n\t\s]/g,"").slice(0,64);throw new Error(`Invalid listGroupMembers response for group ${r}: missing or non-array \`members\` field`)}return t}async listMemberDevices(e,t={}){let r=new URLSearchParams;t.offset!==void 0&&r.set("offset",String(t.offset)),t.limit!==void 0&&r.set("limit",String(t.limit));let s=r.toString(),i=`/admin-api/groups/${e}/member-devices${s?`?${s}`:""}`;return this.httpClient.get(i)}async sealToAccount(e,t,r){return u(await this.httpClient.post(`/admin-api/groups/${e}/accounts/${t}/seal`,r))}async listGroupContexts(e){return u(await this.httpClient.get(`/admin-api/groups/${e}/contexts`))}async addGroupMembers(e,t){await this.httpClient.post(`/admin-api/groups/${e}/members`,t)}async removeGroupMembers(e,t){await this.httpClient.post(`/admin-api/groups/${e}/members/remove`,t)}async updateMemberRole(e,t,r){await this.httpClient.put(`/admin-api/groups/${e}/members/${t}/role`,r)}async getMemberCapabilities(e,t){return u(await this.httpClient.get(`/admin-api/groups/${e}/members/${t}/capabilities`))}async setMemberCapabilities(e,t,r){await this.httpClient.put(`/admin-api/groups/${e}/members/${t}/capabilities`,r)}async setDefaultCapabilities(e,t){await this.httpClient.put(`/admin-api/groups/${e}/settings/default-capabilities`,t)}async openToDelegatedExecution(e){let t=await this.getDefaultCapabilities(e);if(Oe(t,ne.CAN_AUTHOR_ON_BEHALF))return{changed:!1,defaultCapabilities:t};let r=Le(t,ne.CAN_AUTHOR_ON_BEHALF);return await this.setDefaultCapabilities(e,{defaultCapabilities:r}),{changed:!0,defaultCapabilities:r}}async grantAuthorship(e,t){let{capabilities:r}=await this.getMemberCapabilities(e,t);if(Oe(r,ne.CAN_AUTHOR_ON_BEHALF))return{changed:!1,capabilities:r};let s=Le(r,ne.CAN_AUTHOR_ON_BEHALF);return await this.setMemberCapabilities(e,t,{capabilities:s}),{changed:!0,capabilities:s}}async setSubgroupVisibility(e,t){await this.httpClient.put(`/admin-api/groups/${e}/settings/subgroup-visibility`,t)}async setTeeAdmissionPolicy(e,t){await this.httpClient.put(`/admin-api/groups/${e}/settings/tee-admission-policy`,t)}async getTeeAdmissionPolicy(e){let t=await this.httpClient.get(`/admin-api/groups/${e}/settings/tee-admission-policy`);return t.data??t}async setTeeAuthoringPolicy(e,t){await this.httpClient.put(`/admin-api/groups/${e}/settings/tee-authoring-policy`,t)}async disableTeeAuthoringPolicy(e){await this.httpClient.delete(`/admin-api/groups/${e}/settings/tee-authoring-policy`)}async setGroupMetadata(e,t){await this.httpClient.put(`/admin-api/groups/${e}/metadata`,t)}async getGroupMetadata(e){return(await this.httpClient.get(`/admin-api/groups/${e}/metadata`))?.data??null}async setMemberMetadata(e,t,r){await this.httpClient.put(`/admin-api/groups/${e}/members/${t}/metadata`,r)}async getMemberMetadata(e,t){return(await this.httpClient.get(`/admin-api/groups/${e}/members/${t}/metadata`))?.data??null}async setContextMetadata(e,t,r){await this.httpClient.put(`/admin-api/groups/${e}/contexts/${t}/metadata`,r)}async getContextMetadata(e,t){return(await this.httpClient.get(`/admin-api/groups/${e}/contexts/${t}/metadata`))?.data??null}async syncGroup(e){return u(await this.httpClient.post(`/admin-api/groups/${e}/sync`,{}))}async upgradeGroup(e,t){return u(await this.httpClient.post(`/admin-api/groups/${e}/upgrade`,t))}async getGroupUpgradeStatus(e){return u(await this.httpClient.get(`/admin-api/groups/${e}/upgrade/status`))}async getMigrationStatus(e){let t=encodeURIComponent(e);return this.httpClient.get(`/admin-api/groups/${t}/migration-status`)}async getCascadeStatus(e){let t=encodeURIComponent(e);return u(await this.httpClient.get(`/admin-api/groups/${t}/cascade-status`))}async retryGroupUpgrade(e){return u(await this.httpClient.post(`/admin-api/groups/${e}/upgrade/retry`,{}))}async reparentGroup(e,t){let r=await this.httpClient.post(`/admin-api/groups/${e}/reparent`,t);return r?.data??r}async listSubgroups(e){let t=await this.httpClient.get(`/admin-api/groups/${e}/subgroups`);return t.subgroups??t.data??[]}async detachContextFromGroup(e,t){await this.httpClient.post(`/admin-api/groups/${e}/contexts/${t}/remove`,{})}async createGroupInvitation(e,t){return u(await this.httpClient.post(`/admin-api/groups/${e}/invite`,t??{}))}async joinGroup(e){return u(await this.httpClient.post("/admin-api/groups/join",e))}async joinSubgroupInheritance(e){return u(await this.httpClient.post(`/admin-api/groups/${e}/join-via-inheritance`,{}))}async getTeeInfo(){return u(await this.httpClient.get("/admin-api/tee/info"))}async teeAttest(e){return u(await this.httpClient.post("/admin-api/tee/attest",e))}async teeVerifyQuote(e){return u(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 u(await this.httpClient.post("/admin-api/groups",e))}async leaveGroup(e){await this.httpClient.post(`/admin-api/groups/${e}/leave`,{})}async leaveContext(e){await this.httpClient.post(`/admin-api/contexts/${e}/leave`,{})}async leaveNamespace(e){await this.httpClient.post(`/admin-api/namespaces/${e}/leave`,{})}async issueOwnershipProof(e,t){return this.httpClient.post(`/admin-api/groups/${e}/issue-ownership-proof`,t)}async issueNamespaceOwnershipProof(e,t){return this.httpClient.post(`/admin-api/groups/${e}/issue-namespace-ownership-proof`,t)}async setMemberAutoFollow(e,t,r){await this.httpClient.put(`/admin-api/groups/${e}/members/${t}/auto-follow`,r)}async abortMigration(e){return this.httpClient.post(`/admin-api/groups/${e}/migration/abort`,{})}};function mi(n){return Array.from(new TextEncoder().encode(n),e=>e.toString(16).padStart(2,"0")).join("")}function wi(n){return new O(F(n))}function Ri(n){return new O(me(n))}function Ai(n){return new O(Ge(n))}function kt(n,e){return new O(n)}function Ke(n){try{let e=n.indexOf("#");if(e===-1)return null;let t=n.substring(e+1),r=new URLSearchParams(t),s=r.get("access_token");return s?{accessToken:s,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 je(n,e){let t=new URLSearchParams;return t.set("callback-url",e.callbackUrl),e.permissions&&e.permissions.length>0&&t.set("permissions",e.permissions.join(",")),t.set("mode",e.mode),e.packageName&&(t.set("package-name",e.packageName),e.packageVersion&&t.set("package-version",e.packageVersion),e.registryUrl&&t.set("registry-url",e.registryUrl)),`${n.replace(/\/+$/,"")}/auth/login?${t.toString()}`}var St=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,112,4,34,4,32]);function k(n){let e=new Uint8Array(4);return new DataView(e.buffer).setUint32(0,n,!0),e}function b(n){return Array.from(n,e=>e.toString(16).padStart(2,"0")).join("")}function y(n,e,t){let r=n.trim();if(!/^[0-9a-fA-F]*$/.test(r)||r.length!==t*2)throw new Error(`${e} must be ${t*2} hex characters, got ${r.length}`);let s=new Uint8Array(t);for(let i=0;i<t;i+=1)s[i]=Number.parseInt(r.slice(i*2,i*2+2),16);return s}function fe(n,e){let t=n.trim();if(!/^[0-9a-fA-F]*$/.test(t)||t.length%2!==0)throw new Error(`${e} must be an even number of hex characters`);let r=new Uint8Array(t.length/2);for(let s=0;s<r.length;s+=1)r[s]=Number.parseInt(t.slice(s*2,s*2+2),16);return r}function S(n){let e=new Uint8Array(8);return new DataView(e.buffer).setBigUint64(0,BigInt(n),!0),e}function h(...n){let e=new Uint8Array(n.reduce((r,s)=>r+s.length,0)),t=0;for(let r of n)e.set(r,t),t+=r.length;return e}async function U(n,e){let t=[S(n.length),n];for(let r of e)t.push(S(r.length),r);return new Uint8Array(await crypto.subtle.digest("SHA-256",h(...t)))}async function I(n){let e=y(n,"deviceSecret",32),t=h(St,e);try{return await crypto.subtle.importKey("pkcs8",t,{name:"Ed25519"},!1,["sign"])}catch(r){let s=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`"+s)}}async function P(n){let e=y(n,"deviceSecret",32),t=h(St,e),r=await crypto.subtle.importKey("pkcs8",t,{name:"Ed25519"},!0,["sign"]),i=(await crypto.subtle.exportKey("jwk",r)).x;return Uint8Array.from(atob(i.replace(/-/g,"+").replace(/_/g,"/")),a=>a.charCodeAt(0))}var Xn=new TextEncoder().encode("calimero.auth.request.v1"),Zn=new TextEncoder().encode("calimero.auth.request.body.v1");function Tt(n){let e=new TextEncoder().encode(n);return h(k(e.length),e)}async function Ve(n=new Uint8Array(0)){let e=typeof n=="string"?new TextEncoder().encode(n):n;return U(Zn,[e])}async function ye(n){let e=await I(n.signerSecret),t=await Ve(n.body),r=S(n.issuedAt),s=S(n.expiresAt),i=new TextEncoder,a=await U(Xn,[i.encode(n.method),i.encode(n.path),t,r,s]),o=new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},e,a));return b(h(Tt(n.method),Tt(n.path),t,r,s,o))}function be(n){let e=fe(n.credential,"credential"),t=fe(n.request,"request signature"),r=n.session===void 0?new Uint8Array([0]):h(new Uint8Array([1]),fe(n.session,"session statement"));return b(h(e,r,t))}function er(n){if(n==null)return new Uint8Array(0);if(typeof n=="string"||n instanceof Uint8Array)return n;if(n instanceof ArrayBuffer)return new Uint8Array(n);if(ArrayBuffer.isView(n))return new Uint8Array(n.buffer,n.byteOffset,n.byteLength);throw new Error(`a request-carried proof cannot commit to a ${n?.constructor?.name??typeof n} body: pass a string or bytes, or use a session for this call`)}function we(n){let e=n.ttlSeconds??120,t=n.now??(()=>Math.floor(Date.now()/1e3));return async r=>{let s=t();return be({credential:n.credential,session:n.session,request:await ye({method:r.method,path:r.path,body:er(r.body),issuedAt:s,expiresAt:s+e,signerSecret:n.signerSecret})})}}var Re=class extends Error{constructor(e,t,r,s){super(t),this.name="RpcError",this.code=e,this.data=r,this.type=s}};async function Fe(n,e,t){let r=await n.post("/jsonrpc",{jsonrpc:"2.0",id:1,method:e,params:t});if(r.error){let s=r.error;throw new Re(s.code??-1,s.message??s.type??"RPC error",s.data,s.type)}return r.result}var re=class{constructor(e){this.httpClient=e.httpClient}async execute(e){let t=await Fe(this.httpClient,"execute",{contextId:e.contextId,method:e.method,argsJson:e.argsJson??{}});return t&&"output"in t?t.output:t}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 tr=new Set(["MigrationStarted","MigrationProgress","CascadeProgress","MigrationCompleted"]);function Et(n){return n.type!==void 0&&tr.has(n.type)}var nr=new Set(["token_reuse","token_revoked"]),rr=new Set([401,403]);function It(n){let e=n.headers.get("x-auth-error");return!e||!rr.has(n.status)?null:nr.has(e)?e:null}var W=class{constructor(e){this.sessionId=null;this.abortController=null;this.reconnectTimer=null;this.subscribedContextIds=new Set;this.subscribedGroupIds=new Set;this.closed=!1;this.listeners={connect:[],event:[],error:[]};this.baseUrl=e.baseUrl.replace(/\/+$/,""),this.getAuthToken=e.getAuthToken,this.reconnectDelayMs=e.reconnectDelayMs??3e3,this.fetchImpl=(t,r)=>e.fetch?e.fetch(t,r):globalThis.fetch(t,r)}on(e,t){let r=e;if(r in this.listeners){let s=this.listeners[r];s.includes(t)||s.push(t)}}off(e,t){let r=e;if(r in this.listeners){let s=this.listeners[r],i=s.indexOf(t);i!==-1&&s.splice(i,1)}}onAppVersionChanged(e){let t=r=>{if(r.type!=="AppVersionChanged")return;let s=r.data;e({contextId:r.contextId,fromVersion:s?.fromVersion,toVersion:s?.toVersion})};return this.on("event",t),()=>this.off("event",t)}onMigrationEvent(e){let t=r=>{Et(r)&&e(r)};return this.on("event",t),()=>this.off("event",t)}emit(e,t){let r=e;if(r in this.listeners)for(let s of this.listeners[r])try{s(t)}catch{}}async connect(){if(!(this.abortController&&!this.closed)){this.closed=!1,this.abortController=new AbortController;try{let e=await this.getAuthToken(),t=`${this.baseUrl}/sse`,r=await this.fetchImpl(t,{headers:{Authorization:`Bearer ${e}`,Accept:"text/event-stream"},signal:this.abortController.signal});if(!r.ok){let s=It(r),i=await r.text().catch(()=>{});throw s?new _(s,r.status,r.statusText,t,r.headers,i):new v(r.status,r.statusText,t,r.headers,i)}if(!r.body)throw new Error("SSE response has no body");this.readStream(r.body).catch(s=>{if(this.closed)return;let i=s instanceof Error?s:new Error(String(s));this.emit("error",i),this.scheduleReconnect()})}catch(e){if(this.closed)return;let t=e instanceof Error?e:new Error(String(e));if(this.emit("error",t),t instanceof _)return;this.scheduleReconnect()}}}async readStream(e){let t=e.getReader(),r=new TextDecoder,s="";try{for(;;){let{done:i,value:a}=await t.read();if(i)break;s+=r.decode(a,{stream:!0});let o=s.split(`
|
|
2
|
+
`);s=o.pop()??"";for(let c of o)if(c.startsWith("data:")){let l=c.slice(5).trim();l&&this.handleMessage(l)}}if(s+=r.decode(),s.startsWith("data:")){let i=s.slice(5).trim();i&&this.handleMessage(i)}}catch(i){if(this.closed)return;let a=i instanceof Error?i:new Error(String(i));this.emit("error",a)}this.closed||this.scheduleReconnect()}handleMessage(e){try{let t=JSON.parse(e);if(t.type==="connect"&&t.session_id){this.sessionId=t.session_id,this.emit("connect",t.session_id),(this.subscribedContextIds.size>0||this.subscribedGroupIds.size>0)&&this.sendSubscription("subscribe",{contextIds:[...this.subscribedContextIds],groupIds:[...this.subscribedGroupIds]});return}if(!t.result)return;let r=t.result.data;if(Array.isArray(r))try{let s=new Uint8Array(r),i=new TextDecoder().decode(s);r=JSON.parse(i)}catch{}if(t.result.contextId){this.emit("event",{contextId:t.result.contextId,type:t.result.type,data:r});return}t.result.groupId&&this.emit("event",{groupId:t.result.groupId,type:t.result.type,data:r})}catch{}}async subscribe(e){let t=Array.isArray(e)?{contextIds:e}:e,r=(t.contextIds??[]).filter(i=>!this.subscribedContextIds.has(i)),s=(t.groupIds??[]).filter(i=>!this.subscribedGroupIds.has(i));for(let i of t.contextIds??[])this.subscribedContextIds.add(i);for(let i of t.groupIds??[])this.subscribedGroupIds.add(i);(r.length>0||s.length>0)&&this.sessionId&&await this.sendSubscription("subscribe",{contextIds:r,groupIds:s})}async unsubscribe(e){let t=Array.isArray(e)?{contextIds:e}:e,r=(t.contextIds??[]).filter(i=>this.subscribedContextIds.has(i)),s=(t.groupIds??[]).filter(i=>this.subscribedGroupIds.has(i));for(let i of t.contextIds??[])this.subscribedContextIds.delete(i);for(let i of t.groupIds??[])this.subscribedGroupIds.delete(i);(r.length>0||s.length>0)&&this.sessionId&&await this.sendSubscription("unsubscribe",{contextIds:r,groupIds:s})}async sendSubscription(e,t){try{let r=await this.getAuthToken(),s={};t.contextIds&&t.contextIds.length>0&&(s.contextIds=t.contextIds),t.groupIds&&t.groupIds.length>0&&(s.groupIds=t.groupIds);let i=await this.fetchImpl(`${this.baseUrl}/sse/subscription`,{method:"POST",headers:{Authorization:`Bearer ${r}`,"Content-Type":"application/json"},body:JSON.stringify({id:this.sessionId,method:e,params:s})});if(!i.ok){let a=It(i),o=await i.text().catch(()=>{});this.emit("error",a?new _(a,i.status,i.statusText,`${this.baseUrl}/sse/subscription`,i.headers,o):new v(i.status,i.statusText,`${this.baseUrl}/sse/subscription`,i.headers,o))}}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 Ae=class Ae{constructor(e){this.ws=null;this.closed=!1;this.reconnectAttempt=0;this.reconnectTimer=null;this.subscribedContextIds=new Set;this.subscribedGroupIds=new Set;this.listeners={connect:[],event:[],error:[]};this.baseUrl=e.baseUrl.replace(/\/+$/,""),this.getAuthToken=e.getAuthToken}on(e,t){let r=e;if(r in this.listeners){let s=this.listeners[r];s.includes(t)||s.push(t)}}off(e,t){let r=e;if(r in this.listeners){let s=this.listeners[r],i=s.indexOf(t);i!==-1&&s.splice(i,1)}}emit(e,t){let r=e;if(r in this.listeners)for(let s of this.listeners[r])try{s(t)}catch{}}async connect(){if(!(this.ws&&(this.ws.readyState===0||this.ws.readyState===1))){this.closed=!1;try{let e=await this.getAuthToken();if(!e)throw new Error("No authentication token available for WebSocket connection");let t=this.baseUrl.replace(/^http/,"ws");this.ws=new WebSocket(`${t}/ws?token=${encodeURIComponent(e)}`),this.ws.onopen=()=>{this.reconnectAttempt=0,this.emit("connect"),this.resubscribeAfterReconnect()},this.ws.onmessage=r=>{this.handleMessage(r.data)},this.ws.onerror=()=>{this.emit("error",new Error("WebSocket error"))},this.ws.onclose=()=>{this.closed||this.scheduleReconnect()}}catch(e){if(this.closed)return;let t=e instanceof Error?e:new Error(String(e));this.emit("error",t),this.scheduleReconnect()}}}handleMessage(e){if(typeof e=="string")try{let t=JSON.parse(e);if(!t.result)return;let r=t.result.data;if(Array.isArray(r))try{let s=new Uint8Array(r),i=new TextDecoder().decode(s);r=JSON.parse(i)}catch{}if(t.result.contextId){this.emit("event",{contextId:t.result.contextId,type:t.result.type,data:r});return}t.result.groupId&&this.emit("event",{groupId:t.result.groupId,type:t.result.type,data:r})}catch{}}subscribe(e){let t=Array.isArray(e)?{contextIds:e}:e;for(let r of t.contextIds??[])this.subscribedContextIds.add(r);for(let r of t.groupIds??[])this.subscribedGroupIds.add(r);this.ws&&this.ws.readyState===1&&this.sendMessage({id:null,method:"subscribe",params:this.buildSubscriptionParams(t.contextIds??[],t.groupIds??[])})}unsubscribe(e){let t=Array.isArray(e)?{contextIds:e}:e;for(let r of t.contextIds??[])this.subscribedContextIds.delete(r);for(let r of t.groupIds??[])this.subscribedGroupIds.delete(r);this.ws&&this.ws.readyState===1&&this.sendMessage({id:null,method:"unsubscribe",params:this.buildSubscriptionParams(t.contextIds??[],t.groupIds??[])})}resubscribeAfterReconnect(){this.subscribedContextIds.size===0&&this.subscribedGroupIds.size===0||this.sendMessage({id:null,method:"subscribe",params:this.buildSubscriptionParams([...this.subscribedContextIds],[...this.subscribedGroupIds])})}buildSubscriptionParams(e,t){let r={};return e.length>0&&(r.contextIds=e),t.length>0&&(r.groupIds=t),r}sendMessage(e){this.ws&&this.ws.readyState===1&&this.ws.send(JSON.stringify(e))}scheduleReconnect(){if(this.closed)return;this.reconnectTimer&&clearTimeout(this.reconnectTimer);let e=Math.min(1e3*Math.pow(2,this.reconnectAttempt),Ae.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()}};Ae.MAX_BACKOFF_MS=3e4;var J=Ae;function xe(){return{encode(n){return Array.from(new TextEncoder().encode(JSON.stringify(n)))},decode(n){return JSON.parse(new TextDecoder().decode(new Uint8Array(n)))}}}var se=class{constructor(e){this.httpClient=e.httpClient,this.sse=e.sse}async set(e,t,r=xe()){await Fe(this.httpClient,"set_ephemeral",{contextId:e,state:r.encode(t)})}subscribe(e,t,r=xe()){let s=i=>{let a=i;if(a.type!=="Ephemeral"||a.contextId!==e)return;let o=a.data;if(!o?.author)return;let c=!!o.removed,l={author:o.author,state:c||o.state===void 0?void 0:r.decode(o.state),removed:c};o.ageMs!==void 0&&(l.ageMs=o.ageMs),t(l)};return this.sse.on("event",s),this.sse.connect().catch(()=>{}),this.sse.subscribe([e]).catch(()=>{}),()=>{this.sse.off("event",s)}}};var sr=new TextEncoder().encode("calimero.device.cert.v1"),Pt=new TextEncoder().encode("calimero.account.genesis.v1"),ir=new TextEncoder().encode("calimero.device.id.v1"),We=2;async function Dt(n,e){if(e.length!==16)throw new Error(`nonce must be 16 bytes, got ${e.length}`);let t=y(n,"account",32);return b(await U(ir,[t,e]))}async function Je(n){return U(sr,[y(n.account,"account",32),y(n.device,"device",32),y(n.signPublicKey,"signPublicKey",32),y(n.kemPublicKey,"kemPublicKey",32),k(n.keyEpoch),k(n.deviceEpoch)])}function Ut(n){return h(new Uint8Array([We]),n.rootPublicKey,k(0),y(n.account,"account",32),y(n.device,"device",32),y(n.signPublicKey,"signPublicKey",32),y(n.kemPublicKey,"kemPublicKey",32),k(n.keyEpoch),k(n.deviceEpoch),n.signature)}async function Mt(n){let e=await P(n.rootSecret),t=b(await U(Pt,[h(new Uint8Array([We]),e)])),r=0,s=await Je({account:t,device:n.device,signPublicKey:n.signPublicKey,kemPublicKey:n.kemPublicKey,keyEpoch:r,deviceEpoch:n.deviceEpoch}),i=await I(n.rootSecret),a=new Uint8Array(await crypto.subtle.sign("Ed25519",i,s)),o=Ut({rootPublicKey:e,account:t,device:n.device,signPublicKey:n.signPublicKey,kemPublicKey:n.kemPublicKey,keyEpoch:r,deviceEpoch:n.deviceEpoch,signature:a});return b(o)}async function Ce(n){let e=await P(n);return b(await U(Pt,[h(new Uint8Array([We]),e)]))}var ze=["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 or=new TextEncoder().encode("calimero.mdma.account-link.v1\0"),ar=new TextEncoder().encode("calimero.mdma.account-login.v1\0"),ie=256,Nt=ie/32,Qe=(ie+Nt)/11;async function _t(){let n=crypto.getRandomValues(new Uint8Array(ie/8));return Ht(b(n),await lr(n))}async function qt(n){let e=cr(n);return Ht(b(await ur(e)),e.join(" "))}async function L(n){return y(n,"secret",32),{secret:n,publicKey:b(await P(n)),accountId:await Ce(n)}}async function oe(n){if(!n.nonce)throw new Error("nonce is required to sign an account link");let e=await I(n.rootSecret),t=new Uint8Array(await crypto.subtle.sign("Ed25519",e,h(or,new TextEncoder().encode(n.nonce))));return Lt(t)}async function ve(n){if(!n.nonce)throw new Error("nonce is required to sign an account login");let e=await I(n.rootSecret),t=new Uint8Array(await crypto.subtle.sign("Ed25519",e,h(ar,new TextEncoder().encode(n.nonce))));return Lt(t)}async function Ht(n,e){return{...await L(n),phrase:e}}function cr(n){let e=n.normalize("NFKD").toLowerCase().trim().split(/\s+/),t=e[0]===""?0:e.length;if(t!==Qe)throw new Error(`recovery phrase must be ${Qe} words, got ${t}`);return e}async function lr(n){let e=Ot(n)+await Gt(n),t=[];for(let r=0;r<Qe;r+=1){let s=Number.parseInt(e.slice(r*11,r*11+11),2);t.push(ze[s])}return t.join(" ")}async function ur(n){let e="";for(let r of n){let s=ze.indexOf(r);if(s<0)throw new Error(`"${r}" is not a word in the recovery phrase list`);e+=s.toString(2).padStart(11,"0")}let t=new Uint8Array(ie/8);for(let r=0;r<t.length;r+=1)t[r]=Number.parseInt(e.slice(r*8,r*8+8),2);if(e.slice(ie)!==await Gt(t))throw new Error("recovery phrase checksum failed \u2014 check for a mistyped or transposed word");return t}async function Gt(n){let e=new Uint8Array(await crypto.subtle.digest("SHA-256",n));return Ot(e).slice(0,Nt)}function Ot(n){let e="";for(let t of n)e+=t.toString(2).padStart(8,"0");return e}function Lt(n){let e="";for(let t of n)e+=String.fromCharCode(t);return btoa(e)}var dr=new TextEncoder().encode("calimero.mdma.routing-read.v1\0");async function $t(n,e){y(e,"deviceSecret",32);let t=await I(e),r=h(dr,new TextEncoder().encode(n)),s=new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},t,r));return pr(s)}async function ke(n,e){return{"X-Calimero-Credential":e.credential,"X-Calimero-Nonce":n.nonce,"X-Calimero-Signature":await $t(n.nonce,e.deviceSecret)}}function pr(n){let e="";for(let t of n)e+=String.fromCharCode(t);return btoa(e)}var gr="https://cloud.calimero.network";function Ye(n,e){return typeof n.can_execute=="boolean"?n.can_execute:e}function Xe(n){return typeof n.tee_role=="string"&&n.tee_role!==""?n.tee_role:null}function Ze(n){return n.find(e=>e.canExecute&&e.relayUrl!==null&&e.executorAccount!==null)??null}var mr="x-mdma-session-refresh",hr="x-mdma-session-expires",$=class{constructor(e={}){this.session=null;this.baseUrl=(e.cloudBaseUrl||gr).replace(/\/+$/,""),this.onSession=e.onSession;let t=e.fetch;this.fetchImpl=t?(r,s)=>t(r,s):(r,s)=>globalThis.fetch(r,s),this.timeoutMs=e.timeoutMs??1e4,this.routingCredential=e.routingCredential,e.sessionToken&&(this.session={sessionToken:e.sessionToken,expiresAt:0,user:{email:""}})}getSession(){return this.session}isSignedIn(){return this.session!==null}async signInWithGoogle(e){let t=await this.request("POST","/api/auth/google",{body:{id_token:e},anonymous:!0});return this.adoptSession(t)}async signInWithAccount(e){let t=await L(e),{nonce:r}=await this.getAccountLoginChallenge();return this.submitAccountLogin({rootPublicKey:t.publicKey,nonce:r,signature:await ve({rootSecret:e,nonce:r})})}async getAccountLoginChallenge(){let e=await this.request("GET","/api/auth/account/challenge",{anonymous:!0});return{nonce:e.nonce,expiresAtMs:e.expires_at_ms}}async submitAccountLogin(e){let t=await this.request("POST","/api/auth/account",{body:{root_public_key:e.rootPublicKey,nonce:e.nonce,signature:e.signature},anonymous:!0});return this.adoptSession(t)}async refreshSession(){let e=await this.request("POST","/api/auth/refresh");return this.adoptSession(e)}async signOut(){try{this.session&&await this.request("POST","/api/auth/logout",{parse:"none"})}finally{this.session=null,this.notifySession(null)}}async getMyNamespaces(){return(await this.request("GET","/api/cloud/me/namespaces")).map(t=>({namespaceId:String(t.namespace_id??t.group_id??""),groupId:String(t.group_id??t.namespace_id??""),haStatus:String(t.ha_status??"none"),haEnabledAt:t.ha_enabled_at??null,contexts:Array.isArray(t.contexts)?t.contexts:[],fleetReplicas:t.fleet_replicas}))}async getNamespaceRelays(e){return((await this.request("GET",`/api/cloud/me/namespaces/${encodeURIComponent(e)}/relays`)).relays??[]).map(r=>{let s=r.relay_url??null,i=r.executor_account??null,a=r.authorship_ready===!0;return{peerId:String(r.peer_id??""),relayUrl:s,executorAccount:i,status:String(r.status??""),authorshipReady:a,teeRole:Xe(r),canExecute:Ye(r,a&&s!==null&&i!==null),lastSeenAt:r.last_seen_at??null,confirmedAt:r.confirmed_at??null}})}async findExecutingRelay(e){let t=await this.getNamespaceRelays(e);return Ze(t)}async getNamespaceRouting(e){let t=await this.request("GET",`/api/cloud/namespaces/${encodeURIComponent(e)}/admitters`,{anonymous:!0,headers:await this.routingProof(e)});return{namespaceId:String(t.namespace_id??e),nodes:(t.admitters??[]).map(r=>{let s=r.account??null,i=r.relay_url??null,a=r.fresh===!0,o=r.authorship_ready===!0;return{peerId:String(r.peer_id??""),account:s,relayUrl:i,admitUrl:r.admit_url??null,status:String(r.status??""),fresh:a,canAdmit:r.can_admit===!0,authorshipReady:o,teeRole:Xe(r),canExecute:Ye(r,o&&i!==null&&s!==null&&a)}}),servable:t.servable===!0,writable:t.writable===!0}}async getRoutingChallenge(e){let t=await this.request("GET",`/api/cloud/namespaces/${encodeURIComponent(e)}/challenge`,{anonymous:!0});return{namespaceId:String(t.namespace_id??e),nonce:String(t.nonce??""),expiresAtMs:Number(t.expires_at_ms??0)}}async routingProof(e){if(!this.routingCredential)return;let t=await this.getRoutingChallenge(e);return ke(t,this.routingCredential)}async getAccountRelaysChallenge(e){let t=await this.request("GET",`/api/cloud/accounts/${encodeURIComponent(e)}/challenge`,{anonymous:!0});return{accountId:String(t.account_id??e),nonce:String(t.nonce??""),expiresAtMs:Number(t.expires_at_ms??0)}}async getAccountRelays(e){if(!this.routingCredential)throw new Error("getAccountRelays needs a routingCredential: construct the client with the device certificate and its signing secret, since this read is proven by the device, not by a session.");let t=await this.getAccountRelaysChallenge(e);return((await this.request("GET",`/api/cloud/accounts/${encodeURIComponent(e)}/relays`,{anonymous:!0,headers:await ke(t,this.routingCredential)})).relays??[]).map(s=>({peerId:String(s.peer_id??""),relayUrl:s.relay_url??null,fresh:s.fresh===!0}))}async findAdmitter(e,t){let{nodes:r}=await this.getNamespaceRouting(e),s=t&&t.length>0?new Set(t.map(i=>i.toLowerCase())):null;return r.find(i=>i.canAdmit&&(s===null||i.account!==null&&s.has(i.account.toLowerCase())))??null}async getMyMachines(){return((await this.request("GET","/api/cloud/me/machines")).machines??[]).map(t=>{let r=t.relay_url??null,s=t.executor_account??null,i=(Array.isArray(t.namespaces)?t.namespaces:[]).map(a=>{let o=a;return{namespaceId:String(o.namespace_id??""),status:String(o.status??""),authorshipReady:o.authorship_ready===!0,teeRole:Xe(o),fresh:o.fresh===!0,confirmedAt:o.confirmed_at??null,lastSeenAt:o.last_seen_at??null}});return{peerId:String(t.peer_id??""),relayUrl:r,executorAccount:s,canExecute:Ye(t,r!==null&&s!==null&&i.some(a=>a.authorshipReady)),namespaces:i}})}async claimNamespace(e,t){await this.request("POST","/api/cloud/namespaces/claim",{body:{namespace_id:e,ownership_proof:t}})}async enableNamespaceHa(e,t={}){let r=t.admitterAddrs===void 0?{}:{admitter_addrs:[...t.admitterAddrs]};return this.request("POST",`/api/cloud/namespaces/${encodeURIComponent(e)}/enable-ha`,{body:r})}async disableNamespaceHa(e){return this.request("POST",`/api/cloud/namespaces/${encodeURIComponent(e)}/disable-ha`,{body:{}})}async getMyNode(){return(await this.request("GET","/api/cloud/me/node")).node??null}enableHA(e){let t=new URLSearchParams({group_id:e.groupId,context_id:e.contextId});e.redirectUrl&&t.set("redirect_url",e.redirectUrl),window.open(`${this.baseUrl}/enable-ha?${t.toString()}`)}disableHA(e){let t=new URLSearchParams({group_id:e.groupId,context_id:e.contextId});e.redirectUrl&&t.set("redirect_url",e.redirectUrl),window.open(`${this.baseUrl}/disable-ha?${t.toString()}`)}async linkAccount(e){let t=await L(e),{nonce:r}=await this.getAccountLinkChallenge();return this.submitAccountLink({accountId:t.accountId,rootPublicKey:t.publicKey,nonce:r,signature:await oe({rootSecret:e,nonce:r})})}async getAccountLinkChallenge(){let e=await this.request("GET","/api/cloud/me/accounts/challenge");return{nonce:e.nonce,expiresAtMs:e.expires_at_ms??null}}async submitAccountLink(e){let t=await this.request("POST","/api/cloud/me/accounts",{body:{account_id:e.accountId,root_public_key:e.rootPublicKey,nonce:e.nonce,signature:e.signature}});return{accountId:String(t.account_id??e.accountId),linkedAt:t.linked_at??null,alreadyLinked:t.already_linked===!0}}static accountLinkHandoff(e){let t=e.portalUrl.replace(/\/+$/,""),r=new URLSearchParams({"link-account":e.accountId,"callback-url":e.callbackUrl});return{url:`${t}/?${r.toString()}`,accountId:e.accountId}}static readAccountLinkCallback(e){let t=e??(typeof window>"u"?"":window.location.href);if(!t)return{};let r;try{r=new URL(t).hash}catch{return{}}let s=new URLSearchParams(r.replace(/^#/,"")),i=s.get("grant"),a=s.get("account"),o=s.get("error"),c={};return i&&(c.grant=i),a&&(c.accountId=a),o&&(c.error=o),c}async linkAccountWithGrant(e){let t=await L(e.rootSecret),r=await this.request("POST","/api/cloud/accounts/link",{body:{grant:e.grant,root_public_key:t.publicKey,signature:await oe({rootSecret:e.rootSecret,nonce:e.grant})},anonymous:!0});return{accountId:String(r.account_id??t.accountId),linkedAt:r.linked_at??null,alreadyLinked:r.already_linked===!0}}async getMyAccounts(){let e=await this.request("GET","/api/cloud/me/accounts");return{accounts:(e.accounts??[]).map(t=>({accountId:String(t.account_id??""),linkedAt:t.linked_at??null,hasRecoveryEnvelope:t.has_recovery_envelope===!0})),limit:e.limit??null}}adoptSession(e){return this.session={sessionToken:e.session_token,expiresAt:e.expires_at,user:e.user},this.notifySession(this.session),this.session}async notifySession(e){try{await this.onSession?.(e)}catch{}}async request(e,t,r={}){if(!r.anonymous&&!this.session)throw new Error("Not signed in to Calimero Cloud: call signInWithGoogle() or construct the client with a sessionToken");let s={...r.headers,Accept:"application/json"};r.body!==void 0&&(s["Content-Type"]="application/json"),!r.anonymous&&this.session&&(s.Authorization=`Bearer ${this.session.sessionToken}`);let i=new AbortController,a=setTimeout(()=>i.abort(),this.timeoutMs),o;try{o=await this.fetchImpl(`${this.baseUrl}${t}`,{method:e,headers:s,body:r.body===void 0?void 0:JSON.stringify(r.body),signal:i.signal})}catch(c){throw new v(0,c instanceof Error?c.name:"NetworkError",`${this.baseUrl}${t}`,new Headers,c instanceof Error?c.message:String(c))}finally{clearTimeout(a)}if(this.adoptRollingRefresh(o),!o.ok){let c=await o.text().catch(()=>{});throw new v(o.status,o.statusText,`${this.baseUrl}${t}`,o.headers,c)}if(!(r.parse==="none"||o.status===204))return await o.json()}adoptRollingRefresh(e){let t=e.headers.get(mr);if(!t||!this.session)return;let r=e.headers.get(hr),s=Number(r);this.session={sessionToken:t,expiresAt:Number.isFinite(s)&&s>0?s:this.session.expiresAt,user:this.session.user},this.notifySession(this.session)}};function fr(n){let e=n&&typeof n=="object"?n.data??n:void 0;if(!e||typeof e!="object")return[];let t=e.localPeerId,r=e.externalAddrs;if(typeof t!="string"||!t||!Array.isArray(r))return[];let s=`/p2p/${t}`,i=[];for(let a of r){if(typeof a!="string")continue;let o=a.trim();if(!o.startsWith("/"))continue;let c=o.endsWith(s)?o:`${o}${s}`;i.includes(c)||i.push(c)}return i}function yr(n){if(n)return typeof n=="function"?n:we(n)}var br="mero-js:token-refresh";function wr(){let e=globalThis.navigator?.locks;return e&&typeof e.request=="function"?e:null}function et(n,e){try{let t=n.split(".");if(t.length===3){let r=t[1].replace(/-/g,"+").replace(/_/g,"/");for(;r.length%4;)r+="=";let s=JSON.parse(atob(r));if(typeof s.exp=="number")return s.exp*1e3}}catch{}return e}var Se=class{constructor(e){this.tokenData=null;this.refreshPromise=null;this.rpcClient=null;this.sseClient=null;this.wsClient=null;this.wsWarned=!1;this.config={timeoutMs:1e4,...e},this.tokenStore=e.tokenStore??null,this.tokenStore&&(this.tokenData=this.tokenStore.getTokens());let t=typeof window<"u"&&"__TAURI_INTERNALS__"in window,r=yr(this.config.requestProof);this.httpClient=F({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 s=>{this.tokenData&&(this.tokenData.access_token=s,this.tokenStore?.setTokens(this.tokenData))},onAuthRevoked:async()=>{this.clearToken();try{await this.config.onAuthRevoked?.()}catch{}},timeoutMs:this.config.timeoutMs,credentials:this.config.requestCredentials??(t?"omit":void 0)}),this.authClient=At(this.httpClient,{baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||"",timeoutMs:this.config.timeoutMs}),this.adminClient=kt(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 re({httpClient:this.httpClient})),this.rpcClient}get events(){return this.sseClient||(this.sseClient=new W({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 se({httpClient:this.httpClient,sse:this.events})),this.ephemeralClient}get cloud(){return this.cloudClient||(this.cloudClient=new $(this.config.cloud??{})),this.cloudClient}get ws(){return this.wsWarned||(this.wsWarned=!0,console.warn("[mero-js] WsClient is experimental. Use mero.events (SSE) for production.")),this.wsClient||(this.wsClient=new J({baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||""})),this.wsClient}async authenticate(e){let t=e||this.config.credentials;if(!t)throw new Error("No credentials provided for authentication");try{let r={auth_method:"user_password",public_key:t.username,client_name:"mero-js-sdk",permissions:["admin"],timestamp:Math.floor(Date.now()/1e3),provider_data:{username:t.username,password:t.password}},s=await this.authClient.generateTokens(r),i=s.data.access_token;return this.tokenData={access_token:i,refresh_token:s.data.refresh_token,expires_at:et(i,Date.now()+36e5)},this.tokenStore?.setTokens(this.tokenData),this.tokenData}catch(r){throw new Error(`Authentication failed: ${r instanceof Error?r.message:"Unknown error"}`)}}async getValidToken(){return this.tokenData}async performTokenRefresh(){if(this.refreshPromise)return this.refreshPromise;let e=this.tokenData?.access_token,t=this.withRefreshLock(()=>this.performTokenRefreshLocked(e));this.refreshPromise=t;try{return await t}finally{this.refreshPromise===t&&(this.refreshPromise=null)}}withRefreshLock(e){let t=wr();return t?t.request(br,e):e()}async performTokenRefreshLocked(e){let t=this.tokenStore?.getTokens()??null;if(t?.refresh_token&&(this.tokenData=t,e&&t.access_token!==e))return t;if(!this.tokenData?.refresh_token)throw new Error("No refresh token available");try{let r=await this.authClient.refreshToken({access_token:this.tokenData.access_token,refresh_token:this.tokenData.refresh_token}),s=r.data.access_token;return this.tokenData={access_token:s,refresh_token:r.data.refresh_token,expires_at:et(s,Date.now()+36e5)},this.tokenStore?.setTokens(this.tokenData),this.tokenData}catch(r){throw new Error(`Token refresh failed: ${r instanceof Error?r.message:"Unknown error"}`)}}clearToken(){this.refreshPromise=null,this.tokenData=null,this.tokenStore?.clear()}isAuthenticated(){return this.tokenData!==null}setTokenData(e){let t=e.expires_at||et(e.access_token,Date.now()+36e5);this.tokenData={...e,expires_at:t},this.tokenStore?.setTokens(this.tokenData)}getTokenData(){return this.tokenData}close(){this.sseClient?.close(),this.wsClient?.close()}static parseAuthCallback(e){return Ke(e)}static buildAuthLoginUrl(e,t){return je(e,t)}};function Rr(n){return new Se(n)}var tt=class{constructor(){this.tokens=null}getTokens(){return this.tokens}setTokens(e){this.tokens=e}clear(){this.tokens=null}},Ar="mero-tokens",nt=class{constructor(e=Ar){this.key=e}getTokens(){try{if(typeof localStorage>"u")return null;let e=localStorage.getItem(this.key);if(!e)return null;let t=JSON.parse(e);return t&&t.access_token&&t.refresh_token?{access_token:t.access_token,refresh_token:t.refresh_token,expires_at:typeof t.expires_at=="number"?t.expires_at:Date.now()+36e5}:null}catch{return null}}setTokens(e){try{if(typeof localStorage>"u")return;localStorage.setItem(this.key,JSON.stringify(e))}catch{}}clear(){try{if(typeof localStorage>"u")return;localStorage.removeItem(this.key)}catch{}}};var xr=new TextEncoder().encode("calimero.warrant.v2"),Cr=new TextEncoder().encode("calimero.warrant.intent.v1"),Bt=64,vr="00".repeat(32);async function rt(n,e){let t=new TextEncoder().encode(JSON.stringify(e));return U(Cr,[new TextEncoder().encode(n),t])}async function Te(n){let e=y(n.context,"context",32),t=y(n.authorAccount,"authorAccount",32),r=y(n.executor,"executor",32),s=y(n.appVersion??vr,"appVersion",32),i=Kt(n.accountHeads,"accountHeads"),a=Kt(n.governanceFloor,"governanceFloor"),o=await I(n.deviceSecret),c=await P(n.deviceSecret),l=new TextEncoder().encode(n.method),d=await rt(n.method,n.argsJson),p=S(n.nonce),m=S(n.notAfter),f=await U(xr,[e,t,c,r,s,l,d,S(i.length),...i,S(a.length),...a,p,m]),g=new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},o,f));return b(h(e,t,c,r,s,k(l.length),l,d,k(i.length),...i,k(a.length),...a,p,m,g))}function Kt(n,e){let t=n??[];if(t.length>Bt)throw new Error(`${e} cites ${t.length} heads, over the ${Bt} a node accepts`);return t.map((r,s)=>y(r,`${e}[${s}]`,32))}var kr=300,Ee=class extends Error{constructor(t,r,s){super(`relay refused the intent (HTTP ${s}): ${t}`);this.reason=t;this.retryable=r;this.status=s;this.name="IntentRefusedError"}},ae=class{constructor(e){this.config=e,this.baseUrl=e.relayUrl.replace(/\/+$/,""),this.executorAccount=e.executorAccount;let t=e.fetch;this.fetchImpl=t?(r,s)=>t(r,s):(r,s)=>globalThis.fetch(r,s),this.timeoutMs=e.timeoutMs??1e4}async describe(e){let t=await this.json("GET",`/admin-api/contexts/${encodeURIComponent(e)}/intents`);return this.executorAccount=t.data.executorAccount,t.data}async execute(e,t,r={}){let s=this.executorAccount??(await this.describe(e)).executorAccount,i=await this.config.nonces.next(),a=this.config.ttlSeconds??kr,o=await Te({context:e,authorAccount:this.config.authorAccount,executor:s,method:t,argsJson:r,nonce:i,notAfter:BigInt(Math.floor(Date.now()/1e3))+BigInt(a),deviceSecret:this.config.deviceSecret}),c=await this.json("POST",`/admin-api/contexts/${encodeURIComponent(e)}/intents`,{method:t,argsJson:r,warrant:o,authorProof:this.config.authorProof});return{rootHash:c.data.rootHash,returns:c.data.returns??null}}async json(e,t,r){let s={Accept:"application/json"};r!==void 0&&(s["Content-Type"]="application/json");let i=new AbortController,a=setTimeout(()=>i.abort(),this.timeoutMs),o;try{o=await this.fetchImpl(`${this.baseUrl}${t}`,{method:e,headers:s,body:r===void 0?void 0:JSON.stringify(r),signal:i.signal})}catch(c){throw new v(0,c instanceof Error?c.name:"NetworkError",`${this.baseUrl}${t}`,new Headers,c instanceof Error?c.message:String(c))}finally{clearTimeout(a)}if(!o.ok){let c=await o.text().catch(()=>"");if(o.status===400||o.status===403){let l=Sr(c);throw new Ee(l,/nonce/i.test(l),o.status)}throw new v(o.status,o.statusText,`${this.baseUrl}${t}`,o.headers,c)}return await o.json()}};function Sr(n){if(!n)return"no reason given";try{let e=JSON.parse(n);for(let t of[e.error,e.message])if(typeof t=="string"&&t)return t}catch{}return n}function st(n=1){let e=BigInt(n);if(e<1n)throw new Error("nonce sequence starts at 1");return{next(){let t=e;return e+=1n,Promise.resolve(t)}}}function it(n,e){let t=e??globalThis.localStorage;if(!t)throw new Error("no localStorage in this runtime: pass a storage implementation, or use createMemoryNonceSource for a process that owns its whole sequence");return{next(){let r=t.getItem(n),s=0n;if(r!==null&&r!=="")try{let a=BigInt(r);a>0n&&(s=a)}catch{s=0n}let i=s+1n;return t.setItem(n,i.toString()),Promise.resolve(i)}}}var Tr="Noise_NK_25519_AESGCM_SHA256",ot=32,Er=16,Ir=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,110,4,34,4,32]),ct=class n{constructor(e){this.k=null;this.n=0;this.ck=e,this.h=e}static async initialize(){let e=new TextEncoder().encode(Tr),t=new Uint8Array(32);return t.set(e),new n(t)}async mixHash(e){this.h=await Dr(h(this.h,e))}async mixKey(e){let[t,r]=await Ft(this.ck,e);this.ck=t,this.k=await crypto.subtle.importKey("raw",r,"AES-GCM",!1,["encrypt","decrypt"]),this.n=0}async encryptAndHash(e){if(!this.k)throw new Error("Noise: no cipher key yet");let t=new Uint8Array(await crypto.subtle.encrypt({name:"AES-GCM",iv:Vt(this.n),additionalData:this.h},this.k,e));return this.n+=1,await this.mixHash(t),t}async decryptAndHash(e){if(!this.k)throw new Error("Noise: no cipher key yet");let t=new Uint8Array(await crypto.subtle.decrypt({name:"AES-GCM",iv:Vt(this.n),additionalData:this.h},this.k,e));return this.n+=1,await this.mixHash(e),t}split(){return Ft(this.ck,new Uint8Array)}};async function Wt(n,e,t){let r=await ct.initialize();await r.mixHash(e),await r.mixHash(n);let s=await Pr(t);return await r.mixHash(s.publicKey),await r.mixKey(await jt(s.privateKey,n)),{message1:h(s.publicKey,await r.encryptAndHash(new Uint8Array)),async finish(a){if(a.length<ot+Er)throw new Error("Noise: message 2 is too short");let o=a.slice(0,ot);return await r.mixHash(o),await r.mixKey(await jt(s.privateKey,o)),{payload:await r.decryptAndHash(a.slice(ot)),split:await r.split()}}}}async function Pr(n){if(!n){let r;try{r=await crypto.subtle.generateKey({name:"X25519"},!0,["deriveBits"])}catch(i){throw new Error(`Sealed transport needs WebCrypto with X25519, which this runtime lacks (${i?.name??"no crypto.subtle"}). Current browsers and Node have it; in React Native, install react-native-quick-crypto as the global crypto.`)}let s=new Uint8Array(await crypto.subtle.exportKey("raw",r.publicKey));return{privateKey:r.privateKey,publicKey:s}}let e=await crypto.subtle.importKey("pkcs8",h(Ir,n),{name:"X25519"},!0,["deriveBits"]),t=await crypto.subtle.exportKey("jwk",e);return{privateKey:e,publicKey:Ur(t.x)}}async function jt(n,e){let t=await crypto.subtle.importKey("raw",e,{name:"X25519"},!1,[]);return new Uint8Array(await crypto.subtle.deriveBits({name:"X25519",public:t},n,256))}function Vt(n){let e=new Uint8Array(12);return new DataView(e.buffer).setBigUint64(4,BigInt(n),!1),e}async function Dr(n){return new Uint8Array(await crypto.subtle.digest("SHA-256",n))}async function at(n,e){let t=await crypto.subtle.importKey("raw",n,{name:"HMAC",hash:"SHA-256"},!1,["sign"]);return new Uint8Array(await crypto.subtle.sign("HMAC",t,e))}async function Ft(n,e){let t=await at(n,e),r=await at(t,new Uint8Array([1])),s=await at(t,h(r,new Uint8Array([2])));return[r,s]}function Ur(n){let e=n.replace(/-/g,"+").replace(/_/g,"/"),t=atob(e+"=".repeat((4-e.length%4)%4));return Uint8Array.from(t,r=>r.charCodeAt(0))}var Yt="/sealed/v2/handshake",Xt="/sealed/v2",le="application/vnd.calimero.sealed",lt=2,Mr=new TextEncoder().encode("calimero/sealed-http/v2"),ce=16,Nr=1+ce+8,_r=0,qr=1,Hr=2,Gr=1+64*1024+16,Or=1024,Lr=6e4,$r="calimero.tee-attest.transport-key.v1",Br=[101,204,205,304],Zt=new TextEncoder,ue=class extends Error{constructor(){super("The node no longer holds the attested transport key; attest again for the current one");this.name="StaleTransportKeyError"}},z=class extends Error{constructor(t,r,s,i){super(s);this.status=t;this.code=r;this.retryAfterMs=i;this.name="SealedTransportError"}};async function en(n,e){let t=await crypto.subtle.digest("SHA-256",h(Zt.encode($r),n,e));return new Uint8Array(t)}async function tn(n,e,t={}){if(t.applicationId===void 0!=(t.applicationHash===void 0))throw new Error("applicationId and applicationHash are given together or not at all");let r=b(crypto.getRandomValues(new Uint8Array(32))),s=await n.teeAttest({nonce:r,applicationId:t.applicationId,bindTransportKey:!0,...e.includeCollateral?{includeCollateral:!0}:{}});if(!s.transportPublicKey)throw new Error("The node did not report a transport key; it predates sealed transport");let i=y(s.transportPublicKey,"transportPublicKey",32),a=t.applicationHash?y(t.applicationHash,"applicationHash",32):new Uint8Array(32),o=b(await en(a,i));if(!await e({quoteB64:s.quoteB64,nonce:r,reportDataSuffix:o,collateral:s.collateral}))throw new Error("The attestation did not verify, so its transport key is not trusted");return i}function de(n){let e=n.fetch??((s,i)=>fetch(s,i)),t=`${n.baseUrl.replace(/\/+$/,"")}/admin-api/tee/attest`,r={async teeAttest(s){let i=await e(t,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(s)});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 nn({baseUrl:n.baseUrl,transportPublicKey:()=>tn(r,n.verify,{applicationId:n.applicationId,applicationHash:n.applicationHash}),fetch:e})}function nn(n){let e=new URL(n.baseUrl),t=e.pathname.replace(/\/+$/,""),r=`${e.origin}${t}`,s=n.fetch??((p,m)=>fetch(p,m)),i=typeof n.transportPublicKey=="function"?n.transportPublicKey:void 0,a=i?Promise.resolve().then(i):Promise.resolve(n.transportPublicKey);a.catch(()=>{});let o,c=async()=>{try{return await zt(s,r,await Jt(a))}catch(p){if(!(p instanceof ue)||!i)throw p;return a=Promise.resolve().then(i),zt(s,r,await Jt(a))}},l=async()=>{let p=o??d(void 0),m=await p;if(Date.now()<m.renewAt)return[m,p];let f=d(p);return[await f,f]},d=p=>{if(o===p){let m=c();o=m,m.catch(()=>{o===m&&(o=void 0)})}return o};return async(p,m)=>{let f=new Request(p,m),g=new URL(f.url);if(g.origin!==e.origin||!g.pathname.startsWith(`${t}/`))throw new Error(`Refusing to send ${g.href} outside the sealed node at ${n.baseUrl}`);let R=[];f.headers.forEach((E,N)=>R.push([N,E]));let C={method:f.method,path:g.pathname.slice(t.length)+g.search,headers:R},A=new Uint8Array(await f.arrayBuffer()),x=async E=>{let{requestId:N,header:B,envelope:K}=await jr(E,C,A),j=await s(`${r}${Xt}`,{method:"POST",headers:{"content-type":le},body:K,signal:f.signal});if(j.headers.get("content-type")!==le)throw await sn(j);return Fr(j,E.responseKey,B,N)},[T,H]=await l();try{return await x(T)}catch(E){if(!(E instanceof z)||E.code!=="unknown_session")throw E;return x(await d(H))}}}async function Jt(n){let e=await n;if(e.length!==32)throw new Error("transportPublicKey must be 32 bytes");return e}async function zt(n,e,t){try{return await Qt(n,e,t)}catch(r){if(!(r instanceof z)||r.code!=="busy")throw r;return await new Promise(s=>setTimeout(s,r.retryAfterMs??1e3)),Qt(n,e,t)}}async function Qt(n,e,t){let r=await Wt(t,Mr),s=await n(`${e}${Yt}`,{method:"POST",headers:{"content-type":le},body:h(new Uint8Array([lt]),t,r.message1)});if(s.headers.get("content-type")!==le)throw await sn(s);let i=await Jr(s,Or);return Kr(r,i)}async function Kr(n,e){if(e[0]!==lt)throw new Error("The handshake reply is malformed");let t;try{t=await n.finish(e.slice(1))}catch{throw new Error("The handshake reply did not open: it did not come from the attested node")}let{payload:r,split:s}=t;if(r.length!==ce+4)throw new Error("The handshake reply is malformed");let i=r.slice(0,ce),a=new DataView(r.buffer,r.byteOffset).getUint32(ce,!1),[o,c]=await Promise.all([crypto.subtle.importKey("raw",s[0],"AES-GCM",!1,["encrypt"]),crypto.subtle.importKey("raw",s[1],"AES-GCM",!1,["decrypt"])]);return s[0].fill(0),s[1].fill(0),{requestKey:o,responseKey:c,nextRequestId:1,renewAt:Date.now()+a*1e3-Lr,header(l){let d=new Uint8Array(Nr);return d[0]=lt,d.set(i,1),new DataView(d.buffer).setBigUint64(1+ce,BigInt(l),!1),d}}}async function jr(n,e,t){let r=n.nextRequestId;n.nextRequestId+=1;let s=n.header(r),i=await crypto.subtle.encrypt({name:"AES-GCM",iv:rn(r,0),additionalData:s},n.requestKey,Vr(e,t));return{requestId:r,header:s,envelope:h(s,new Uint8Array(i))}}function rn(n,e){let t=new Uint8Array(12),r=new DataView(t.buffer);return r.setBigUint64(0,BigInt(n),!1),r.setUint32(8,e,!1),t}function Vr(n,e){let t=Zt.encode(JSON.stringify(n)),r=new Uint8Array(4);return new DataView(r.buffer).setUint32(0,t.length,!1),h(r,t,e)}async function Fr(n,e,t,r){if(!n.body)throw new Error("The sealed response has no body");let s=Wr(n.body.getReader()),i=0,a=async()=>{let d=await s.next();if(!d)return null;let p;try{p=new Uint8Array(await crypto.subtle.decrypt({name:"AES-GCM",iv:rn(r,i),additionalData:t},e,d))}catch{throw new Error("A sealed response frame did not open: it was not sealed by the attested node")}return i+=1,{kind:p[0],data:p.slice(1)}},o=await a();if(!o||o.kind!==_r)throw new Error("The sealed response is malformed");let c=JSON.parse(new TextDecoder().decode(o.data));if(Br.includes(c.status))return await s.cancel(),new Response(null,{status:c.status,headers:c.headers});let l=new ReadableStream({async pull(d){try{let p=await a();p?p.kind===qr?d.enqueue(p.data):p.kind===Hr?(d.close(),await s.cancel()):d.error(new Error("The sealed response is malformed")):d.error(new Error("The sealed response was cut short"))}catch(p){d.error(p)}},cancel(){return s.cancel()}});return new Response(l,{status:c.status,headers:c.headers})}function Wr(n){let e=new Uint8Array,t=async r=>{for(;e.length<r;){let{done:s,value:i}=await n.read();if(s)return!1;e=h(e,i)}return!0};return{async next(){if(!await t(4))return null;let r=new DataView(e.buffer,e.byteOffset).getUint32(0,!1);if(r>Gr)throw await n.cancel(),new Error("The sealed response is malformed: a frame is larger than the node sends");if(!await t(4+r))return null;let s=e.slice(4,4+r);return e=e.slice(4+r),s},cancel:()=>n.cancel()}}async function Jr(n,e){if(!n.body)return new Uint8Array;let t=n.body.getReader(),r=new Uint8Array;for(;;){let{done:s,value:i}=await t.read();if(s)return r;if(r=h(r,i),r.length>e)throw await t.cancel(),new Error("The handshake reply is malformed: it is too long")}}async function sn(n){let e,t=`Sealed request refused: HTTP ${n.status}`;try{let i=await n.json();e=i?.error?.code,i?.error?.message&&(t=`Sealed request refused: ${i.error.message}`)}catch{}if(e==="stale_transport_key")return new ue;let r=Number(n.headers.get("retry-after")),s=Number.isFinite(r)&&r>0?Math.min(r,5)*1e3:void 0;return new z(n.status,e,t,s)}async function zr(n){if(!n.sessionToken&&!n.googleIdToken)throw new Error("connectCloud needs either a sessionToken or a googleIdToken");let e=new $({cloudBaseUrl:n.cloudBaseUrl,sessionToken:n.sessionToken,onSession:n.onSession,fetch:n.fetch,timeoutMs:n.timeoutMs});!n.sessionToken&&n.googleIdToken&&await e.signInWithGoogle(n.googleIdToken);let t=await e.getMyNamespaces(),r=Qr(t,n.namespaceId),s=await e.getNamespaceRelays(r.namespaceId),i=Ze(s);if(!i)throw new Error(Yr(r,s));let a=new ae({relayUrl:i.relayUrl,executorAccount:i.executorAccount,authorAccount:n.authorAccount,authorProof:n.authorProof,deviceSecret:n.deviceSecret,nonces:n.nonces??await Xr(n.deviceSecret),ttlSeconds:n.ttlSeconds,fetch:n.seal?de({baseUrl:i.relayUrl,verify:n.seal,fetch:n.fetch}):n.fetch,timeoutMs:n.timeoutMs});return{cloud:e,relay:a,namespaceId:r.namespaceId,namespace:r,relayInfo:i,execute:(o,c,l)=>a.execute(o,c,l)}}function Qr(n,e){if(e){let t=n.find(r=>r.namespaceId===e);if(!t)throw new Error(`this account owns no namespace ${e}; it owns: ${n.map(r=>r.namespaceId).join(", ")||"(none)"}`);return t}if(n.length===0)throw new Error("this account owns no namespaces in the cloud: claim one first, then enable HA on it so a relay is assigned");if(n.length>1)throw new Error(`this account owns ${n.length} namespaces \u2014 pass namespaceId to say which: ${n.map(t=>t.namespaceId).join(", ")}`);return n[0]}function Yr(n,e){if(e.length===0)return n.haStatus==="enabled"?`namespace ${n.namespaceId} has HA enabled but no relay has been assigned to it yet \u2014 retry shortly`:`namespace ${n.namespaceId} has no relays: enable HA on it in the cloud to have an attested node assigned`;let t=e.filter(s=>s.teeRole!==null&&s.teeRole!=="RelayTee");if(t.length===e.length)return`every node on namespace ${n.namespaceId} is a read-only TEE replica (ReadOnlyTee), which never relays delegated writes: an admin of the namespace must set its TEE admission policy with mode: 'relay' \u2014 AdminClient.setTeeAdmissionPolicy(namespaceId, { ..., mode: 'relay' }) \u2014 so fleet nodes are admitted as RelayTee`;let r=e.filter(s=>s.teeRole===null&&!s.authorshipReady);return r.length>0&&r.length+t.length===e.length?`every relay on namespace ${n.namespaceId} is waiting for the authorship grant: an admin of the namespace must grant CAN_AUTHOR_ON_BEHALF to ${r.map(s=>s.executorAccount??s.peerId).join(", ")||"the relay account"} \u2014 with AdminClient.grantAuthorship(namespaceId, account) for these relays, and AdminClient.openToDelegatedExecution(namespaceId) so relays assigned later need no further op`:`namespace ${n.namespaceId} has ${e.length} relay(s), but none is ready to relay yet (a URL, an executor account and a recent heartbeat) \u2014 retry shortly`}async function Xr(n){let e=`mero-js:warrant-nonce:${b(await P(n))}`;try{return it(e)}catch{return st(1)}}var Zr=/^[0-9a-f]{96}$/,es=["mrtd","rtmr0","rtmr1","rtmr2","rtmr3"];function ut(n){let e=Q(n.allowedMrtd??[],"allowedMrtd"),t=(n.allowedMeasurements??[]).map((o,c)=>{let l=`allowedMeasurements[${c}]`;return es.map(d=>Q([o?.[d]??""],`${l}.${d}`)[0]).join()}),r=[Q(n.allowedRtmr0??[],"allowedRtmr0"),Q(n.allowedRtmr1??[],"allowedRtmr1"),Q(n.allowedRtmr2??[],"allowedRtmr2"),Q(n.allowedRtmr3??[],"allowedRtmr3")];if(n.allowedMeasurements!==void 0&&t.length===0)throw new Error("allowedMeasurements is empty, so no quote would ever be accepted");if(t.length===0){if(e.length===0)throw new Error("No image is trusted: give allowedMeasurements, or allowedMrtd with allowedRtmr1-3");if(r.slice(1).some(o=>o.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 s=n.allowedTcbStatuses??["UpToDate"],i=n.now??Date.now;return Object.assign(async({quoteB64:o,nonce:c,reportDataSuffix:l,collateral:d})=>{let p=ns(o),m=d??await n.fetchCollateral?.(p);if(!m)throw new Error("The node sent no collateral for its quote, and no fetchCollateral was given to get it");let f;try{f=n.dcapVerify(p,m,Math.floor(i()/1e3))}catch(A){throw new Error(`The quote did not verify: ${A?.message??String(A)}`)}if(f.status==="Revoked"||!s.includes(f.status))throw new Error(`The platform's TCB status is ${f.status}, which is not accepted`);let g=ts(f.report),R=[g.mrTd,g.rtMr0,g.rtMr1,g.rtMr2,g.rtMr3].map(A=>b(A));if(t.length>0&&!t.includes(R.join()))throw new Error(`The measurements (MRTD ${R[0]}, RTMR0-3 ${R.slice(1).join(", ")}) are not an image this verifier trusts`);if(e.length>0&&!e.includes(R[0]))throw new Error(`MRTD ${R[0]} is not an image this verifier trusts`);if([g.rtMr0,g.rtMr1,g.rtMr2,g.rtMr3].forEach((A,x)=>{let T=r[x];if(T.length>0&&!T.includes(b(A)))throw new Error(`RTMR${x} ${b(A)} is not one this verifier trusts`)}),b(g.reportData)!==`${c}${l}`.toLowerCase())throw new Error("The quote does not commit to this nonce and binding");return!0},{includeCollateral:!0})}function Q(n,e){return n.map(t=>{let r=t.trim().toLowerCase();if(!Zr.test(r))throw new Error(`${e} holds ${JSON.stringify(t)}, which is not a 48-byte hex measurement`);return r})}function ts(n){let e=n.data;if(n.type==="td10"&&e)return e;if(n.type==="td15"&&e?.base)return e.base;throw new Error(`The quote is a ${n.type} quote, not a TDX one`)}function ns(n){let e=atob(n),t=new Uint8Array(e.length);for(let r=0;r<e.length;r+=1)t[r]=e.charCodeAt(r);return t}var rs=["UpToDate","SWHardeningNeeded","ConfigurationNeeded","ConfigurationAndSWHardeningNeeded","OutOfDate","OutOfDateConfigurationNeeded"];function dt(n,{profile:e}){if(n.length===0)throw new Error("No release given, so no image would be trusted");let t,r=n.map((s,i)=>{let a=s?.tag??`releases[${i}]`;if(s?.role!==void 0&&s.role!=="node")throw new Error(`${a} lists the measurements of a ${s.role}, not of a node image`);let o=s?.profiles?.[e];if(!o){let l=Object.keys(s?.profiles??{}).join(", ")||"none";throw new Error(`${a} has no profile ${JSON.stringify(e)} (it has: ${l})`)}let c=(o.allowed_tcb_statuses??["uptodate"]).map(l=>ss(l,a));return t=t===void 0?c:t.filter(l=>c.includes(l)),{mrtd:o.mrtd,rtmr0:o.rtmr0,rtmr1:o.rtmr1,rtmr2:o.rtmr2,rtmr3:o.rtmr3}});if(!t||t.length===0)throw new Error("The releases given accept no TCB status in common");return{allowedMeasurements:r,allowedTcbStatuses:t}}function ss(n,e){let t=rs.find(r=>r.toLowerCase()===String(n).toLowerCase());if(!t)throw new Error(`${e} accepts TCB status ${JSON.stringify(n)}, which this verifier does not know`);return t}var on=[{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"]}],an=[{baseUrl:"https://rekor.sigstore.dev",logId:"c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d",publicKey:"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE2G2Y+2tabdTV5BcGiBIx0a9fAFwrkBbmLSGtks4L3qX6yYY0zufBnhC8Ur/iy55GhWP/9A/bY2LhC30M9+RYtw==",validFor:{start:"2021-01-12T11:53:27Z"}}];var is="1.2.840.10045.2.1",os={"1.2.840.10045.3.1.7":"P-256","1.3.132.0.34":"P-384"},as={"P-256":32,"P-384":48},cs={"1.2.840.10045.4.3.2":"SHA-256","1.2.840.10045.4.3.3":"SHA-384"};function cn(n,e,t){if(e+2>t)throw new Error("it is truncated");let r=n[e];if((r&31)===31)throw new Error("it uses a tag this parser does not read");let s=n[e+1],i=e+2;if(s&128){let o=s&127;if(o===0||o>4||i+o>t)throw new Error("it has a length this parser does not read");s=0;for(let c=0;c<o;c+=1)s=s*256+n[i+c];i+=o}let a=i+s;if(a>t)throw new Error("it is truncated");return{tag:r,bytes:n,offset:e,start:i,end:a}}function X(n){let e=cn(n,0,n.length);if(e.end!==n.length)throw new Error("it has trailing bytes");return e}function D(n){let e=[];for(let t=n.start;t<n.end;){let r=cn(n.bytes,t,n.end);e.push(r),t=r.end}return e}function w(n,e,t){if(!n||n.tag!==e)throw new Error(`${t} is not where it should be`);return n}function q(n){return n.bytes.slice(n.start,n.end)}function Ie(n){return n.bytes.slice(n.offset,n.end)}function Y(n){let e=q(w(n,6,"An object identifier"));if(e.length===0||e[e.length-1]&128)throw new Error("it has a malformed object identifier");let t=[],r=0;for(let a of e)r=r*128+(a&127),a&128||(t.push(r),r=0);let s=t.shift();return[...s<80?[Math.floor(s/40),s%40]:[2,s-80],...t].join(".")}function ls(n){let e=new TextDecoder().decode(q(n)),t=n.tag===23?/^(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})Z$/.exec(e):null,r=n.tag===24?/^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})Z$/.exec(e):null,s=t??r;if(!s)throw new Error(`it holds the time ${JSON.stringify(e)}, which is not one a certificate may hold`);let i=Number(s[1]);t&&(i+=i<50?2e3:1900);let[a,o,c,l,d]=s.slice(2).map(Number);return Date.UTC(i,a-1,o,c,l,d)}function pt(n){try{let[e,t,r,...s]=D(w(X(n),48,"The certificate"));if(s.length>0)throw new Error("it has fields after its signature");let i=D(w(e,48,"The signed part")),a=i[0]?.tag===160?1:0,[o,c,l,d,p,m,...f]=i.slice(a);w(o,2,"The serial number");let g=Y(D(w(t,48,"The signature algorithm"))[0]);if(Y(D(w(c,48,"The signature algorithm"))[0])!==g)throw new Error("it names two different signature algorithms");let C=cs[g];if(!C)throw new Error(`it is signed with ${g}, not ECDSA with SHA-256 or SHA-384`);let[A,x]=D(w(d,48,"The validity")).map(ls);if(x===void 0)throw new Error("its validity is incomplete");let[T,H]=D(w(m,48,"The public key"));w(H,3,"The public key");let[E,N]=D(w(T,48,"The key algorithm"));if(Y(E)!==is)throw new Error("its key is not an elliptic-curve key");let B=os[Y(N)];if(!B)throw new Error("its key is on a curve other than P-256 or P-384");let K=new Map,j=f.find(Me=>Me.tag===163);if(j){let[Me]=D(j);for(let Hn of D(w(Me,48,"The extensions"))){let V=D(w(Hn,48,"An extension"));if(V.length===3)w(V[1],1,"An extension's critical flag");else if(V.length!==2)throw new Error("it has a malformed extension");let Ne=Y(V[0]);if(K.has(Ne))throw new Error(`it has extension ${Ne} twice`);K.set(Ne,q(w(V[V.length-1],4,"An extension value")))}}let wt=q(w(r,3,"The signature"));if(wt[0]!==0)throw new Error("its signature is not a whole number of bytes");return{der:n,tbs:Ie(e),signatureHash:C,signature:wt.slice(1),issuer:Ie(w(l,48,"The issuer")),subject:Ie(w(p,48,"The subject")),notBefore:A,notAfter:x,spki:Ie(m),curve:B,extensions:K}}catch(e){throw new Error(`The certificate is malformed: ${e.message}`)}}function ln(n){return D(w(X(n),48,"The list")).map(Y)}function us(n,e){let t=as[e],r=D(w(X(n),48,"The signature"));if(r.length!==2)throw new Error("The signature is not an ECDSA signature");let s=new Uint8Array(t*2);return r.forEach((i,a)=>{let o=q(w(i,2,"The signature"));if(o.length===0||o[0]&128)throw new Error("The signature is not an ECDSA signature");for(;o.length>1&&o[0]===0;)o=o.subarray(1);if(o.length>t)throw new Error("The signature is not an ECDSA signature");s.set(o,a*t+t-o.length)}),s}async function Pe(n,e,t,r,s){let i;try{i=us(r,e)}catch{return!1}let a=await crypto.subtle.importKey("spki",n,{name:"ECDSA",namedCurve:e},!1,["verify"]);return crypto.subtle.verify({name:"ECDSA",hash:t},a,i,s)}function M(n,e){let t=n.replace(/\s+/g,"");if(!/^[A-Za-z0-9+/]*={0,2}$/.test(t)||t.length%4!==0)throw new Error(`${e} is not base64`);let r=atob(t),s=new Uint8Array(r.length);for(let i=0;i<r.length;i+=1)s[i]=r.charCodeAt(i);return s}function gt(n,e){let t=[...n.matchAll(/-----BEGIN CERTIFICATE-----([^-]*)-----END CERTIFICATE-----/g)];if(t.length!==1||n.replace(t[0][0],"").trim()!=="")throw new Error(`${e} is not exactly one PEM certificate`);return M(t[0][1],e)}var ds="2.5.29.17",ps="2.5.29.37",gs="1.3.6.1.5.5.7.3.3",ms="1.3.6.1.4.1.57264.1.8",hs="1.3.6.1.4.1.57264.1.1",fs=134,ys=12,bs=48,ws=new TextEncoder,Z=n=>new TextDecoder().decode(n);async function un(n,e,t,r){let{base64Signature:s,cert:i,rekorBundle:a}=Cs(e),o=a.Payload;if(r!==void 0&&r.trim()!==s.trim())throw new Error("The detached signature is not the one in the bundle");let c=M(s,"The bundle signature"),l=gt(Z(M(i,"The bundle certificate")),"The bundle certificate"),d=pt(l),p=an.find(x=>x.logId===o.logID.toLowerCase());if(!p)throw new Error(`The bundle names Rekor log ${o.logID}, which the Sigstore trust root does not know`);let m=ws.encode(`{"body":${JSON.stringify(o.body)},"integratedTime":${o.integratedTime},"logID":${JSON.stringify(o.logID)},"logIndex":${o.logIndex}}`);if(!await Pe(M(p.publicKey,"The Rekor key"),"P-256","SHA-256",M(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 g=o.integratedTime*1e3;if(!gn(g,p.validFor))throw new Error(`Rekor log ${p.baseUrl} was not in use at ${pe(g)}, when the entry says it was logged`);let R=vs(o.body),C=b(new Uint8Array(await crypto.subtle.digest("SHA-256",n)));if(R.hash!==C)throw new Error("The file's SHA-256 is not the one Rekor logged: the file is not the one signed");if(!mt(M(R.signature,"The logged signature"),c))throw new Error("The bundle's signature is not the one Rekor logged");let A=gt(Z(M(R.publicKey,"The logged certificate")),"The logged certificate");if(!mt(A,l))throw new Error("The bundle's certificate is not the one Rekor logged");if(d.curve!=="P-256"||!await Pe(d.spki,"P-256","SHA-256",c,n))throw new Error("The signature over the file does not verify with the bundle's certificate");return await Rs(d,g),xs(d,t),{integratedTime:o.integratedTime}}async function Rs(n,e){if(!pn(n,e))throw new Error(`The signing certificate was valid ${pe(n.notBefore)} to ${pe(n.notAfter)}, not at ${pe(e)} when Rekor logged it`);let t=[];for(let r of on){let s=r.certChain.map(a=>pt(M(a,"A Fulcio certificate")));if(!await dn(n,s[0]))continue;let i=await As(s,r.validFor,e);if(!i)return;t.push(`${r.uri} (valid from ${r.validFor.start}): ${i}`)}throw new Error(t.length>0?`The signing certificate's CA is not trusted at ${pe(e)}: ${t.join("; ")}`:"The signing certificate was not issued by a Fulcio CA in the Sigstore trust root")}async function As(n,e,t){if(!gn(t,e))return"the trust root says it was not issuing certificates then";for(let[r,s]of n.entries()){if(!pn(s,t))return`its certificate ${r} was not valid then`;let i=n[r+1]??s;if(!await dn(s,i))return`its certificate ${r} is not signed by the next`}}async function dn(n,e){return mt(n.issuer,e.subject)?Pe(e.spki,e.curve,n.signatureHash,n.signature,n.tbs):!1}function xs(n,e){let t=n.extensions.get(ds);if(!t)throw new Error("The signing certificate names no identity");let r=D(w(X(t),bs,"The subject alternative name")),s=r.filter(l=>l.tag===fs).map(l=>Z(q(l)));if(s.length!==1||r.length!==1||s[0]!==e.identity)throw new Error(`The release was signed by ${JSON.stringify(s.length===1?s[0]:s)}, not by ${e.identity}`);let i=n.extensions.get(ms),a=n.extensions.get(hs),o=i?Z(q(w(X(i),ys,"The OIDC issuer"))):a?Z(a):void 0;if(o!==e.issuer)throw new Error(`The signing certificate's OIDC issuer is ${o===void 0?"missing":JSON.stringify(o)}, not ${e.issuer}`);let c=n.extensions.get(ps);if(!c||!ln(c).includes(gs))throw new Error("The signing certificate is not for code signing")}function Cs(n){let e=n;if(typeof e=="string")try{e=JSON.parse(e)}catch{throw new Error("The bundle is not JSON")}let t=e,r=t?.rekorBundle?.Payload;if(!(typeof t?.base64Signature=="string"&&typeof t.cert=="string"&&typeof t.rekorBundle?.SignedEntryTimestamp=="string"&&typeof r?.body=="string"&&typeof r.logID=="string"&&/^[0-9a-fA-F]{64}$/.test(r.logID)&&Number.isSafeInteger(r.integratedTime)&&r.integratedTime>=0&&Number.isSafeInteger(r.logIndex)&&r.logIndex>=0))throw new Error("The bundle is not a cosign bundle with a Rekor entry");return t}function vs(n){let e;try{e=JSON.parse(Z(M(n,"The logged entry")))}catch{throw new Error("The logged entry is not JSON")}let t=e?.spec?.data?.hash,r=e?.spec?.signature;if(e?.kind!=="hashedrekord"||t?.algorithm!=="sha256"||typeof t.value!="string"||typeof r?.content!="string"||typeof r.publicKey?.content!="string")throw new Error("The logged entry is not a SHA-256 hashedrekord");return{hash:t.value.toLowerCase(),signature:r.content,publicKey:r.publicKey.content}}function pn(n,e){return n.notBefore<=e&&e<=n.notAfter}function gn(n,e){return Date.parse(e.start)<=n&&(e.end===void 0||n<=Date.parse(e.end))}function pe(n){return new Date(n).toISOString()}function mt(n,e){return n.length===e.length&&n.every((t,r)=>t===e[r])}var ht=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"}),ks=["mrtd","rtmr0","rtmr1","rtmr2","rtmr3"],hn="https://cloud.calimero.network";async function fn(n,e,t={}){let r=typeof n=="string"?new TextEncoder().encode(n):n;await un(r,e,{identity:t.identity??ht.identity,issuer:t.issuer??ht.issuer},t.signature);let s;try{s=JSON.parse(new TextDecoder().decode(r))}catch{throw new Error("The signed release is not JSON")}if(s?.role!=="node")throw new Error(`The signed release is a ${JSON.stringify(s?.role)} release, not a node one`);let i=Object.values(s.profiles??{}),a=o=>ks.every(c=>/^[0-9a-f]{96}$/i.test(String(o?.[c])));if(typeof s.tag!="string"||i.length===0||!i.every(a))throw new Error("The signed file is not a release's published-mrtds.json: it lists no measured profiles");if(t.expectedVersion!==void 0&&s.tag!==t.expectedVersion)throw new Error(`The signed release is ${s.tag}, not ${t.expectedVersion}`);return s}async function yn(n,e={}){let t=await(e.fetch??fetch)(n,{headers:{accept:"application/json"}});if(!t.ok)throw new Error(`Fetching the node release from ${n} failed: HTTP ${t.status}`);let r;try{r=(await t.json())?.data}catch{throw new Error(`${n} did not answer with JSON`)}if(typeof r?.version!="string"||typeof r.publishedMrtds!="string"||typeof r.bundle!="string")throw new Error(`${n} did not answer with a signed node release`);return{version:r.version,publishedMrtds:r.publishedMrtds,bundle:r.bundle}}function bn(n){let e=/^merotee-.+-(\d+)-(\d+)-(\d+)$/.exec(n);if(!e)throw new Error(`${JSON.stringify(n)} is not the image of a mero-tee node release`);return`${Number(e[1])}.${Number(e[2])}.${Number(e[3])}`}async function wn(n,e={}){let t=await An(n,e.fetch??fetch);if(t===void 0)throw new Error(`${Rn(n)} was refused unsealed: the node requires sealing and is too old to name its release before a session exists. Name the release it runs yourself (createSignedReleaseSealedFetch's \`releaseVersion\`), or upgrade the node`);return t}function Rn(n){return`${n.replace(/\/+$/,"")}/admin-api/tee/info`}async function An(n,e){let t=Rn(n),r=await e(t,{headers:{accept:"application/json"}});if(r.status===403&&await r.json().then(a=>a?.error?.code).catch(()=>{})==="sealed_required")return;if(!r.ok)throw new Error(`Fetching ${t} failed: HTTP ${r.status}`);let s;try{s=(await r.json())?.data?.osImage}catch{throw new Error(`${t} did not answer with JSON`)}if(typeof s!="string")throw new Error(`${t} did not name the node's image`);return bn(s)}function xn(n,e){return`${n.replace(/\/+$/,"")}/api/tee/node-releases/${ge(e,"version")}`}async function Cn(n){let e=ge(n.minReleaseVersion,"minReleaseVersion"),t=ge(n.release?.version,"The release version"),r=await fn(n.release.publishedMrtds,n.release.bundle,{expectedVersion:t,identity:n.identity,issuer:n.issuer});if(Ts(t,e)<0)throw new Error(`Release ${t} is older than the minimum trusted, ${e}`);return dt([r],{profile:n.profile})}function vn(n){return ge(n.minReleaseVersion,"minReleaseVersion"),Object.assign(async t=>{let r=await Cn({release:await n.release(),profile:n.profile,minReleaseVersion:n.minReleaseVersion,identity:n.identity,issuer:n.issuer});return ut({dcapVerify:n.dcapVerify,fetchCollateral:n.fetchCollateral,now:n.now,...r})(t)},{includeCollateral:!0})}function Ss(n){let{baseUrl:e,releaseSource:t,releaseVersion:r,applicationId:s,applicationHash:i,fetch:a,...o}=n;r!==void 0&&ge(r,"releaseVersion");let c=a??((d,p)=>fetch(d,p));return de({baseUrl:e,verify:vn({...o,release:async()=>{let d=r===void 0?await wn(e,{fetch:c}):await An(e,c)??r;return typeof t=="function"?t({baseUrl:e,version:d,fetch:c}):yn(xn(t??hn,d),{fetch:c})}}),applicationId:s,applicationHash:i,fetch:c})}var kn=/^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/;function ge(n,e){let t=typeof n=="string"?kn.exec(n):null,r=t?.[4];if(!t||r!==void 0&&r.split(".").some(s=>s===""))throw new Error(`${e} is ${JSON.stringify(n)}, not a release version like 2.3.87`);return n}function Ts(n,e){let[t,r]=mn(n),[s,i]=mn(e);for(let c=0;c<3;c+=1)if(t[c]!==s[c])return t[c]<s[c]?-1:1;if(r===void 0||i===void 0)return r===i?0:r===void 0?1:-1;let a=r.split("."),o=i.split(".");for(let c=0;c<Math.max(a.length,o.length);c+=1){let[l,d]=[a[c],o[c]];if(l===void 0||d===void 0)return l===void 0?-1:1;let[p,m]=[/^\d+$/.test(l),/^\d+$/.test(d)],f=p&&m?Math.sign(Number(l)-Number(d)):p!==m?p?-1:1:l<d?-1:l>d?1:0;if(f!==0)return f}return 0}function mn(n){let e=kn.exec(n);return[[Number(e[1]),Number(e[2]),Number(e[3])],e[4]]}var yt=12,Es=new TextEncoder().encode("calimero.namespace.v1"),Is=0,Sn={GroupCreated:0,GroupReparented:1,GroupDeleted:2,AdminChanged:3,PolicyUpdated:4,MemberJoined:5,KeyDelivery:6,MemberJoinedOpen:7,MemberJoinedAt:8,NamespaceCreatedV2:9,MemberJoinedViaTeeAttestation:10};function ft(n,e){if(n.length!==32)throw new Error(`${e} must be 32 bytes, got ${n.length}`);return new Uint8Array(n)}function Tn(n,e){if(n==null)return new Uint8Array([0]);if(n.length!==32)throw new Error(`${e} must be 32 bytes, got ${n.length}`);return h(new Uint8Array([1]),new Uint8Array(n))}function En(n){let e=new TextEncoder().encode(n);return h(k(e.length),e)}function De(n){let e=n.invitation,t=e.admitters??[],r=n.admitter_addrs??[];return h(ft(e.inviter_identity,"inviter_identity"),ft(e.group_id,"group_id"),S(e.expiration_timestamp),ft(e.secret_salt,"secret_salt"),new Uint8Array([e.invited_role]),k(t.length),...t.map((s,i)=>y(s,`admitters[${i}]`,32)),En(n.inviter_signature),n.inviter_account?h(new Uint8Array([1]),y(n.inviter_account,"inviter_account",32)):new Uint8Array([0]),k(r.length),...r.map(En),Tn(n.application_id,"application_id"),Tn(n.app_key,"app_key"))}async function In(n){let e=n.parentOpHashes??[],t=y(n.credential,"credential",n.credential.length/2),r=BigInt(n.invitation.invitation.expiration_timestamp??0)!==0n,s=n.joinedAt??BigInt(Math.floor(Date.now()/1e3)),i=r?h(new Uint8Array([Sn.MemberJoinedAt]),y(n.member,"member",32),De(n.invitation),S(s),t):h(new Uint8Array([Sn.MemberJoined]),y(n.member,"member",32),De(n.invitation),t),a=h(new Uint8Array([Is]),i),o=await I(n.deviceSecret),c=await P(n.deviceSecret),l=h(new Uint8Array([yt]),y(n.namespaceId,"namespaceId",32),k(e.length),...e.map((m,f)=>y(m,`parentOpHashes[${f}]`,32)),c,S(n.nonce),a),d=new Uint8Array(await crypto.subtle.sign("Ed25519",o,h(Es,l))),p=new Uint8Array([0]);return b(h(l,d,p))}var Ps=new TextEncoder().encode("calimero.auth.login.v1"),Pn={webOrigin:0,codeSigningId:1,cli:2};function Dn(n){let e=new TextEncoder;switch(n.kind){case"webOrigin":return e.encode(n.origin);case"codeSigningId":return e.encode(n.id);case"cli":return new Uint8Array(0)}}function Ds(n){return h(Uint8Array.from([Pn[n.kind]]),Dn(n))}function Us(n){let e=Uint8Array.from([Pn[n.kind]]);if(n.kind==="cli")return e;let t=Dn(n);return h(e,k(t.length),t)}async function Ue(n){let e=y(n.node,"node",32),t=y(n.challenge,"challenge",32),r=y(n.sessionKey,"sessionKey",32),s=await I(n.deviceSecret),i=await P(n.deviceSecret),a=S(n.issuedAt),o=S(n.expiresAt),c=await U(Ps,[e,Ds(n.audience),t,r,i,a,o]),l=new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},s,c));return b(h(e,Us(n.audience),t,r,i,a,o,l))}var Ms=300;async function bt(){let n=b(crypto.getRandomValues(new Uint8Array(32)));return{publicKey:b(await P(n)),secret:n}}function Ns(n){switch(n.kind){case"webOrigin":return n.origin;case"codeSigningId":return n.id;case"cli":return"cli"}}async function Un(n){let e=n.nodeUrl.replace(/\/+$/,""),t=n.timeoutMs??1e4,r=async(m,f)=>{let g=new AbortController,R=setTimeout(()=>g.abort(),t),C;try{let x={...f,signal:g.signal};C=n.fetch?await n.fetch(`${e}${m}`,x):await globalThis.fetch(`${e}${m}`,x)}catch(x){throw new v(0,x instanceof Error?x.name:"NetworkError",`${e}${m}`,new Headers,x instanceof Error?x.message:String(x))}finally{clearTimeout(R)}let A=await C.text().catch(()=>"");if(!C.ok)throw new v(C.status,C.statusText,`${e}${m}`,C.headers,A);return A?JSON.parse(A):{}},s=await r("/auth/challenge",{method:"GET",headers:{Accept:"application/json"}}),i=s.challenge??s.data?.challenge;if(!i)throw new Error("the node issued no challenge");let a=await bt(),o=Math.floor(Date.now()/1e3),c=await Ue({node:n.node,audience:n.audience,challenge:i,sessionKey:a.publicKey,issuedAt:o,expiresAt:o+(n.ttlSeconds??Ms),deviceSecret:n.deviceSecret}),l=await r("/auth/token",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({auth_method:"account_proof",public_key:a.publicKey,client_name:n.clientName??Ns(n.audience),timestamp:o,provider_data:{challenge:i,login_statement:c,account_proof:n.accountProof}})}),d=l.access_token??l.data?.access_token,p=l.refresh_token??l.data?.refresh_token;if(!d)throw new Error("the node minted no session");return{accessToken:d,refreshToken:p??"",sessionKey:a.publicKey,sessionSecret:a.secret}}var Mn=[2428,2429,2528,2529],_s="localhost",qs=2e3;function Nn(n){return`http://${_s}:${n}`}function _n(n,e){let t=n.endsWith("/")?n:`${n}/`;return new URL(e,t).toString()}async function qn(n,e={}){let{timeoutMs:t=qs,signal:r}=e;if(r?.aborted)return!1;let s=new AbortController,i=()=>s.abort(),a=r;a&&a.addEventListener("abort",i,{once:!0});let o=setTimeout(()=>s.abort(),t);try{let c=_n(n,"admin-api/health"),l=await fetch(c,{method:"GET",signal:s.signal});if(!l.ok)return!1;try{let d=await l.json(),p=d?.data?.status!==void 0?d?.data?.status:d?.status;return p===void 0?!0:typeof p=="string"&&p.toLowerCase()==="alive"}catch{return!0}}catch{return!1}finally{clearTimeout(o),a&&a.removeEventListener("abort",i)}}async function Hs(n={}){let{ports:e=Mn,timeoutMs:t,signal:r}=n;return(await Promise.all(e.map(async i=>{let a=Nn(i);return await qn(a,{timeoutMs:t,signal:r})?a:null}))).filter(i=>i!==null)}export{O as AdminApiClient,G as AuthApiClient,_ as AuthRevokedError,ne as CAPABILITIES,$ as CloudClient,Mn as DEFAULT_LOCAL_NODE_PORTS,hn as DEFAULT_RELEASE_MIRROR,se as EphemeralClient,Yt as HANDSHAKE_PATH,v as HTTPError,Ee as IntentRefusedError,nt as LocalStorageTokenStore,tt as MemoryTokenStore,Se as MeroJs,ht as NODE_RELEASE_SIGNER,ae as RelayClient,re as RpcClient,Re as RpcError,le as SEALED_CONTENT_TYPE,Xt as SEALED_PATH,yt as SIGNED_NAMESPACE_OP_SCHEMA_VERSION,z as SealedTransportError,W as SseClient,ue as StaleTransportKeyError,ee as WebHttpClient,J as WsClient,Ce as accountForRoot,qt as accountRootFromPhrase,L as accountRootFromSecret,fr as admitterAddrsFromNetworkStatus,je as buildAuthLoginUrl,be as callerProof,Be as classifyError,xn as cloudNodeReleaseUrl,_e as combineSignals,Qn as compareSemver,zr as connectCloud,Ai as createAdminApiClient,kt as createAdminApiClientFromHttpClient,de as createAttestedSealedFetch,ti as createAuthApiClient,At as createAuthApiClientFromHttpClient,wi as createBrowserAdminApiClient,Zs as createBrowserAuthApiClient,F as createBrowserHttpClient,He as createHttpClient,it as createLocalStorageNonceSource,st as createMemoryNonceSource,Rr as createMeroJs,Ri as createNodeAdminApiClient,ei as createNodeAuthApiClient,me as createNodeHttpClient,we as createProofSigner,ut as createQuoteVerifier,Kn as createRetryableMethod,nn as createSealedFetch,Ss as createSignedReleaseSealedFetch,vn as createSignedReleaseVerifier,qe as createTimeoutSignal,Ge as createUniversalHttpClient,Je as deviceCertPayload,Hs as discoverLocalNodes,De as encodeSignedInvitation,tn as fetchAttestedTransportKey,yn as fetchNodeRelease,wn as fetchNodeReleaseVersion,_t as generateAccountRoot,bt as generateSessionKey,Oe as hasCap,mi as hexEncodeUtf8,rt as intentHash,Wn as isSettled,xe as jsonCodec,Nn as localNodeUrl,Un as login,Dt as mintDeviceId,_n as nodeEndpoint,bn as nodeReleaseVersionFromImage,Ke as parseAuthCallback,qn as probeNodeHealth,xt as redeemInvitation,Ve as requestBodyHash,ke as routingProofHeaders,ai as shouldRetain,oe as signAccountLink,ve as signAccountLogin,Mt as signDeviceCert,Ue as signLoginStatement,In as signMemberJoinOp,ye as signRequest,$t as signRoutingChallenge,Te as signWarrant,en as transportKeyBinding,Cn as trustSignedRelease,dt as trustedMeasurementsFromReleases,fn as verifySignedNodeRelease,Le as withCap,he as withRetry,ri as withoutCap};
|
|
3
3
|
//# sourceMappingURL=index.browser.mjs.map
|