@calimero-network/mero-js 19.24.1 → 19.26.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/dist/admin-api/admin-client.d.ts +33 -1
- package/dist/admin-api/admin-client.js +47 -0
- package/dist/admin-api/admin-types.d.ts +96 -0
- package/dist/admin-api/admin-types.js +0 -2
- package/dist/index.browser.mjs +2 -2
- package/dist/index.browser.mjs.map +4 -4
- package/dist/index.cjs +152 -5
- package/dist/index.cjs.map +4 -4
- package/dist/index.mjs +152 -5
- package/dist/index.mjs.map +4 -4
- package/dist/sealed/index.d.ts +2 -0
- package/dist/sealed/index.js +1 -0
- package/dist/sealed/noise.js +11 -3
- package/dist/sealed/sealed.d.ts +14 -6
- package/dist/sealed/sealed.js +8 -1
- package/dist/sealed/verify.d.ts +109 -0
- package/dist/sealed/verify.js +116 -0
- package/package.json +2 -1
package/dist/index.browser.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
function be(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=o=>{r.abort(o.target.reason);for(let a of e)a.removeEventListener("abort",s)};for(let o of e){if(o.aborted)return AbortSignal.abort(o.reason);o.addEventListener("abort",s,{once:!0})}return r.signal}function we(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 Lt=new Set(["token_reuse","token_revoked"]);function $t(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 w=class extends Error{constructor(t,r,s,o,a){let i=$t(a);super(i?`HTTP ${t} ${r}: ${i}`:`HTTP ${t} ${r}`);this.status=t;this.statusText=r;this.url=s;this.headers=o;this.bodyText=a;this.name="HTTPError"}toJSON(){return{status:this.status,statusText:this.statusText,url:this.url,headers:We(this.headers),bodyText:this.bodyText}}},E=class extends w{constructor(t,r,s,o,a,i){super(r,s,o,a,i);this.reason=t;this.name="AuthRevokedError";this.message=`Authentication revoked (${t}): HTTP ${r} ${s}`}};function We(n){let e={};return n.forEach((t,r)=>{e[r]=t}),e}function Ot(n){try{return new URL(n).pathname}catch{let e=n.indexOf("?");return e===-1?n:n.slice(0,e)}}var K=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:We(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),i=s??Date.now(),l=this.createAbortSignal(t),g=await this.buildHeaders(t?.headers),d;g instanceof Headers?(d={},g.forEach((m,I)=>{d[I]=m})):d=g;let u={method:t?.method||"GET",headers:d},f=t?.body instanceof ReadableStream||typeof t?.body=="object"&&t?.body!==null&&"getReader"in t.body&&!(t.body instanceof Blob);(t?.body!==void 0&&!f||t?.body!==void 0&&f&&r===0)&&(u.body=t.body);let y;if(r>0&&s!==void 0){let m=t?.timeoutMs||this.transport.timeoutMs;if(m){let I=Date.now()-i,T=Math.max(0,m-I);y=this.createAbortSignal({...t,timeoutMs:T})}else y=this.createAbortSignal(t)}else y=l;if(y&&(u.signal=y),this.transport.credentials!==void 0&&(u.credentials=this.transport.credentials),t?.mode!==void 0&&(u.mode=t.mode),t?.cache!==void 0&&(u.cache=t.cache),t?.redirect!==void 0&&(u.redirect=t.redirect),t?.referrer!==void 0&&(u.referrer=t.referrer),t?.referrerPolicy!==void 0&&(u.referrerPolicy=t.referrerPolicy),t?.integrity!==void 0&&(u.integrity=t.integrity),t?.keepalive!==void 0&&(u.keepalive=t.keepalive),this.transport.getProof){let m=await this.transport.getProof({method:u.method??"GET",path:Ot(a),body:u.body});m&&(d["X-Calimero-Proof"]=m)}try{let m=await this.transport.fetch(a,u);if(!m.ok){let I=await this.getBodyText(m),T=new w(m.status,m.statusText,a,m.headers,I),k=m.headers.get("x-auth-error");if((m.status===401||m.status===403)&&k&&Lt.has(k)){if(this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,this.transport.onAuthRevoked)try{await this.transport.onAuthRevoked()}catch{}throw new E(k,m.status,m.statusText,a,m.headers,I)}let D=t?.signal?.aborted===!0;if(m.status===401&&this.transport.refreshToken&&k==="token_expired"&&r<1&&!f&&!D)try{let x=this.refreshTokenPromise;x||(x=this.transport.refreshToken(),this.refreshTokenPromise=x);let O=await x;if(!O||O.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 P=this.onTokenRefreshPromise;P||(P=this.transport.onTokenRefresh(O),this.onTokenRefreshPromise=P),await P,this.refreshTokenPromise=null,this.onTokenRefreshPromise=null;let q=t?.timeoutMs||this.transport.timeoutMs;if(q&&s!==void 0){let fe=Date.now()-i;if(q-fe<=0)throw T}return this.makeRequest(e,t,r+1,i)}catch(x){throw this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,x instanceof Error&&x.message.includes("onTokenRefresh")?x:T}throw T}return this.parseResponse(m,t?.parse)}catch(m){throw m instanceof w||m instanceof Error&&m.message.includes("onTokenRefresh")?m:new w(0,"Network Error",a,new Headers,m instanceof Error?m.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(we(r)),t.length>0?be(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 Re(n){return new K(n)}function H(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 Re(e)}function Z(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,o)=>globalThis.fetch(s,o):(s,o)=>e(s,o),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 Re(r)}function Ae(n){return typeof window<"u"?H(n):Z(n)}function Kt(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 o=s.status;return o>=500||o===429}return r==="TypeError"}function jt(n){let t=250*Math.pow(2,n-1),r=(Math.random()-.5)*.4*t;return Math.max(0,t+r)}async function ee(n,e={}){let{attempts:t=3}=e,r;for(let s=1;s<=t;s++)try{return await n(s)}catch(o){if(r=o,!Kt(r,t-s))throw r;let a=jt(s),g=r.headers?.get?.("Retry-After");if(g){let d=parseInt(g,10);if(!isNaN(d))a=Math.max(a,d*1e3);else{let u=new Date(g);if(!isNaN(u.getTime())){let f=Math.max(0,u.getTime()-Date.now());a=Math.max(a,Math.min(f,6e4))}}}await new Promise(d=>setTimeout(d,a))}throw r||new Error("Retry failed without error")}function Bt(n,e={}){return async(...t)=>ee(()=>n(...t),e)}var U=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 j=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 xr(n){let e=new j;return new U(e)}function Cr(n){let e=new j;return new U(e)}function vr(n){let e=new j;return new U(e)}function Fe(n,e){return new U(n)}var B={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 xe(n,e){let t=e>>>0;return(n&t)>>>0===t}function Ce(n,e){return(n|e)>>>0}function Pr(n,e){return(n&~e)>>>0}function c(n){return n?.data}function Vt(n,e){let[t,r]=Je(n),[s,o]=Je(e),a=t.split("."),i=s.split("."),l=Math.max(a.length,i.length);for(let f=0;f<l;f++){let y=ze(a[f]??"0",i[f]??"0");if(y!==0)return y}if(r===void 0&&o===void 0)return 0;if(r===void 0)return 1;if(o===void 0)return-1;let g=r.split("."),d=o.split("."),u=Math.max(g.length,d.length);for(let f=0;f<u;f++){if(f>=g.length)return-1;if(f>=d.length)return 1;let y=ze(g[f],d[f]);if(y!==0)return y}return 0}function Je(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 ze(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 Wt(n,e,t){return ee(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 _=class{constructor(e){this.httpClient=e}async healthCheck(){return c(await this.httpClient.get("/admin-api/health"))}async isAuthed(){return this.httpClient.get("/admin-api/is-authed")}async installApplication(e){return c(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 o=await(await Wt(r.toString(),"versions",t)).json();return(Array.isArray(o)?o:[]).map(a=>a.appVersion).filter(a=>typeof a=="string").sort((a,i)=>Vt(i,a))}async installDevApplication(e){return c(await this.httpClient.post("/admin-api/install-dev-application",e))}async uninstallApplication(e){return c(await this.httpClient.delete(`/admin-api/applications/${e}`))}async listApplications(){return c(await this.httpClient.get("/admin-api/applications"))}async getApplication(e){return c(await this.httpClient.get(`/admin-api/applications/${e}`))}async listApplicationVersions(e){return c(await this.httpClient.get(`/admin-api/applications/${e}/versions`))}async getApplicationAbi(e,t){let r=t?`?service_name=${encodeURIComponent(t)}`:"";return c(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 c(await this.httpClient.post("/admin-api/contexts",t))}async deleteContext(e){return c(await this.httpClient.delete(`/admin-api/contexts/${e}`))}async getContexts(){return c(await this.httpClient.get("/admin-api/contexts"))}async getContext(e){return c(await this.httpClient.get(`/admin-api/contexts/${e}`))}async getContextsForApplication(e){return c(await this.httpClient.get(`/admin-api/contexts/for-application/${e}`))}async generateContextIdentity(){return c(await this.httpClient.post("/admin-api/identity/context",{}))}async getContextIdentities(e){return c(await this.httpClient.get(`/admin-api/contexts/${e}/identities`))}async getContextIdentitiesOwned(e){return c(await this.httpClient.get(`/admin-api/contexts/${e}/identities-owned`))}async joinContext(e){return c(await this.httpClient.post(`/admin-api/contexts/${e}/join`,{}))}async getContextGroup(e){return c(await this.httpClient.get(`/admin-api/contexts/${e}/group`))}async getContextStorage(e){return c(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 c(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",o=c(await this.httpClient.request(s,{method:"PUT",body:e.data,headers:{"Content-Type":"application/octet-stream"}}));return{blobId:o.blob_id,size:o.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:c(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 c(await this.httpClient.post("/admin-api/alias/create/context",{alias:e.alias,contextId:e.contextId}))}async createApplicationAlias(e){return c(await this.httpClient.post("/admin-api/alias/create/application",{alias:e.alias,applicationId:e.applicationId}))}async lookupContextAlias(e){return c(await this.httpClient.post(`/admin-api/alias/lookup/context/${encodeURIComponent(e)}`,{}))}async lookupApplicationAlias(e){return c(await this.httpClient.post(`/admin-api/alias/lookup/application/${encodeURIComponent(e)}`,{}))}async deleteContextAlias(e){return c(await this.httpClient.post(`/admin-api/alias/delete/context/${encodeURIComponent(e)}`,{}))}async deleteApplicationAlias(e){return c(await this.httpClient.post(`/admin-api/alias/delete/application/${encodeURIComponent(e)}`,{}))}async listContextAliases(){return c(await this.httpClient.get("/admin-api/alias/list/context"))}async listApplicationAliases(){return c(await this.httpClient.get("/admin-api/alias/list/application"))}async createDeviceAlias(e){return c(await this.httpClient.post("/admin-api/alias/create/device",{alias:e.alias,deviceId:e.deviceId}))}async lookupDeviceAlias(e){return c(await this.httpClient.post(`/admin-api/alias/lookup/device/${encodeURIComponent(e)}`,{}))}async deleteDeviceAlias(e){return c(await this.httpClient.post(`/admin-api/alias/delete/device/${encodeURIComponent(e)}`,{}))}async listDeviceAliases(){return c(await this.httpClient.get("/admin-api/alias/list/device"))}async listNamespaces(){return c(await this.httpClient.get("/admin-api/namespaces"))}async getNamespace(e){return c(await this.httpClient.get(`/admin-api/namespaces/${e}`))}async getNodeIdentity(){return c(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 c(await this.httpClient.post(`/admin-api/contexts/${e}/intents`,t))}async getIntentRelay(e){return c(await this.httpClient.get(`/admin-api/contexts/${e}/intents`))}async listNamespacesForApplication(e){return c(await this.httpClient.get(`/admin-api/namespaces/for-application/${e}`))}async createNamespace(e){return c(await this.httpClient.post("/admin-api/namespaces",e))}async deleteNamespace(e){return c(await this.httpClient.request(`/admin-api/namespaces/${e}`,{method:"DELETE",body:"{}",headers:{"Content-Type":"application/json"}}))}async createNamespaceInvitation(e,t){return c(await this.httpClient.post(`/admin-api/namespaces/${e}/invite`,t??{}))}async admitJoin(e,t){return c(await this.httpClient.post(`/admin-api/namespaces/${e}/admit`,t,{timeoutMs:65e3}))}async joinNamespace(e,t){let r=c(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 createGroupInNamespace(e,t){return c(await this.httpClient.post(`/admin-api/namespaces/${e}/groups`,t??{}))}async listNamespaceGroups(e){return c(await this.httpClient.get(`/admin-api/namespaces/${e}/groups`))}async initAccountPairing(e){return c(await this.httpClient.post("/admin-api/account/pair-init",e))}async completeAccountPairing(e){return c(await this.httpClient.post("/admin-api/account/pair-complete",e))}async relinkAccountDevice(e,t){return c(await this.httpClient.post(`/admin-api/account/devices/${e}/relink`,t??{}))}async rescopeAccountDevice(e,t){return c(await this.httpClient.put(`/admin-api/account/devices/${encodeURIComponent(e)}/scope`,t))}async signWithAccountRoot(e){return c(await this.httpClient.post("/admin-api/account/sign-with-root",e))}async labelAccountDevice(e,t){return c(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 c(await this.httpClient.post(`/admin-api/namespaces/${e}/account/revoke`,t))}async getGroupInfo(e){return c(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 c(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 listGroupContexts(e){return c(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 c(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(xe(t,B.CAN_AUTHOR_ON_BEHALF))return{changed:!1,defaultCapabilities:t};let r=Ce(t,B.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(xe(r,B.CAN_AUTHOR_ON_BEHALF))return{changed:!1,capabilities:r};let s=Ce(r,B.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 c(await this.httpClient.post(`/admin-api/groups/${e}/sync`,{}))}async upgradeGroup(e,t){return c(await this.httpClient.post(`/admin-api/groups/${e}/upgrade`,t))}async getGroupUpgradeStatus(e){return c(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 c(await this.httpClient.get(`/admin-api/groups/${t}/cascade-status`))}async retryGroupUpgrade(e){return c(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 c(await this.httpClient.post(`/admin-api/groups/${e}/invite`,t??{}))}async joinGroup(e){return c(await this.httpClient.post("/admin-api/groups/join",e))}async joinSubgroupInheritance(e){return c(await this.httpClient.post(`/admin-api/groups/${e}/join-via-inheritance`,{}))}async getTeeInfo(){return c(await this.httpClient.get("/admin-api/tee/info"))}async teeAttest(e){return c(await this.httpClient.post("/admin-api/tee/attest",e))}async teeVerifyQuote(e){return c(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 getCertificate(){return this.httpClient.get("/admin-api/certificate",{parse:"text"})}async createGroup(e){return c(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 Ur(n){return Array.from(new TextEncoder().encode(n),e=>e.toString(16).padStart(2,"0")).join("")}function Hr(n){return new _(H(n))}function Gr(n){return new _(Z(n))}function Lr(n){return new _(Ae(n))}function Xe(n,e){return new _(n)}function ve(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 ke(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 Qe=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,112,4,34,4,32]);function R(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 h(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 o=0;o<t;o+=1)s[o]=Number.parseInt(r.slice(o*2,o*2+2),16);return s}function te(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 A(n){let e=new Uint8Array(8);return new DataView(e.buffer).setBigUint64(0,BigInt(n),!0),e}function p(...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 S(n,e){let t=[A(n.length),n];for(let r of e)t.push(A(r.length),r);return new Uint8Array(await crypto.subtle.digest("SHA-256",p(...t)))}async function C(n){let e=h(n,"deviceSecret",32),t=p(Qe,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 v(n){let e=h(n,"deviceSecret",32),t=p(Qe,e),r=await crypto.subtle.importKey("pkcs8",t,{name:"Ed25519"},!0,["sign"]),o=(await crypto.subtle.exportKey("jwk",r)).x;return Uint8Array.from(atob(o.replace(/-/g,"+").replace(/_/g,"/")),a=>a.charCodeAt(0))}var Ft=new TextEncoder().encode("calimero.auth.request.v1"),Jt=new TextEncoder().encode("calimero.auth.request.body.v1");function Ye(n){let e=new TextEncoder().encode(n);return p(R(e.length),e)}async function Pe(n=new Uint8Array(0)){let e=typeof n=="string"?new TextEncoder().encode(n):n;return S(Jt,[e])}async function ne(n){let e=await C(n.signerSecret),t=await Pe(n.body),r=A(n.issuedAt),s=A(n.expiresAt),o=new TextEncoder,a=await S(Ft,[o.encode(n.method),o.encode(n.path),t,r,s]),i=new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},e,a));return b(p(Ye(n.method),Ye(n.path),t,r,s,i))}function re(n){let e=te(n.credential,"credential"),t=te(n.request,"request signature"),r=n.session===void 0?new Uint8Array([0]):p(new Uint8Array([1]),te(n.session,"session statement"));return b(p(e,r,t))}function zt(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 se(n){let e=n.ttlSeconds??120,t=n.now??(()=>Math.floor(Date.now()/1e3));return async r=>{let s=t();return re({credential:n.credential,session:n.session,request:await ne({method:r.method,path:r.path,body:zt(r.body),issuedAt:s,expiresAt:s+e,signerSecret:n.signerSecret})})}}var oe=class extends Error{constructor(e,t,r,s){super(t),this.name="RpcError",this.code=e,this.data=r,this.type=s}};async function Se(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 oe(s.code??-1,s.message??s.type??"RPC error",s.data,s.type)}return r.result}var V=class{constructor(e){this.httpClient=e.httpClient}async execute(e){let t=await Se(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 Xt=new Set(["MigrationStarted","MigrationProgress","CascadeProgress","MigrationCompleted"]);function Ze(n){return n.type!==void 0&&Xt.has(n.type)}var Qt=new Set(["token_reuse","token_revoked"]),Yt=new Set([401,403]);function et(n){let e=n.headers.get("x-auth-error");return!e||!Yt.has(n.status)?null:Qt.has(e)?e:null}var G=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],o=s.indexOf(t);o!==-1&&s.splice(o,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=>{Ze(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=et(r),o=await r.text().catch(()=>{});throw s?new E(s,r.status,r.statusText,t,r.headers,o):new w(r.status,r.statusText,t,r.headers,o)}if(!r.body)throw new Error("SSE response has no body");this.readStream(r.body).catch(s=>{if(this.closed)return;let o=s instanceof Error?s:new Error(String(s));this.emit("error",o),this.scheduleReconnect()})}catch(e){if(this.closed)return;let t=e instanceof Error?e:new Error(String(e));if(this.emit("error",t),t instanceof E)return;this.scheduleReconnect()}}}async readStream(e){let t=e.getReader(),r=new TextDecoder,s="";try{for(;;){let{done:o,value:a}=await t.read();if(o)break;s+=r.decode(a,{stream:!0});let i=s.split(`
|
|
2
|
-
`);s=i.pop()??"";for(let l of i)if(l.startsWith("data:")){let g=l.slice(5).trim();g&&this.handleMessage(g)}}if(s+=r.decode(),s.startsWith("data:")){let o=s.slice(5).trim();o&&this.handleMessage(o)}}catch(o){if(this.closed)return;let a=o instanceof Error?o:new Error(String(o));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),o=new TextDecoder().decode(s);r=JSON.parse(o)}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(o=>!this.subscribedContextIds.has(o)),s=(t.groupIds??[]).filter(o=>!this.subscribedGroupIds.has(o));for(let o of t.contextIds??[])this.subscribedContextIds.add(o);for(let o of t.groupIds??[])this.subscribedGroupIds.add(o);(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(o=>this.subscribedContextIds.has(o)),s=(t.groupIds??[]).filter(o=>this.subscribedGroupIds.has(o));for(let o of t.contextIds??[])this.subscribedContextIds.delete(o);for(let o of t.groupIds??[])this.subscribedGroupIds.delete(o);(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 o=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(!o.ok){let a=et(o),i=await o.text().catch(()=>{});this.emit("error",a?new E(a,o.status,o.statusText,`${this.baseUrl}/sse/subscription`,o.headers,i):new w(o.status,o.statusText,`${this.baseUrl}/sse/subscription`,o.headers,i))}}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 ie=class ie{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],o=s.indexOf(t);o!==-1&&s.splice(o,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),o=new TextDecoder().decode(s);r=JSON.parse(o)}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),ie.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()}};ie.MAX_BACKOFF_MS=3e4;var L=ie;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 W=class{constructor(e){this.httpClient=e.httpClient,this.sse=e.sse}async set(e,t,r=ae()){await Se(this.httpClient,"set_ephemeral",{contextId:e,state:r.encode(t)})}subscribe(e,t,r=ae()){let s=o=>{let a=o;if(a.type!=="Ephemeral"||a.contextId!==e)return;let i=a.data;if(!i?.author)return;let l=!!i.removed,g={author:i.author,state:l||i.state===void 0?void 0:r.decode(i.state),removed:l};i.ageMs!==void 0&&(g.ageMs=i.ageMs),t(g)};return this.sse.on("event",s),this.sse.connect().catch(()=>{}),this.sse.subscribe([e]).catch(()=>{}),()=>{this.sse.off("event",s)}}};var Zt=new TextEncoder().encode("calimero.device.cert.v1"),tt=new TextEncoder().encode("calimero.account.genesis.v1"),en=new TextEncoder().encode("calimero.device.id.v1"),Ie=2;async function nt(n,e){if(e.length!==16)throw new Error(`nonce must be 16 bytes, got ${e.length}`);let t=h(n,"account",32);return b(await S(en,[t,e]))}async function Te(n){return S(Zt,[h(n.account,"account",32),h(n.device,"device",32),h(n.signPublicKey,"signPublicKey",32),h(n.kemPublicKey,"kemPublicKey",32),R(n.keyEpoch),R(n.deviceEpoch)])}function rt(n){return p(new Uint8Array([Ie]),n.rootPublicKey,R(0),h(n.account,"account",32),h(n.device,"device",32),h(n.signPublicKey,"signPublicKey",32),h(n.kemPublicKey,"kemPublicKey",32),R(n.keyEpoch),R(n.deviceEpoch),n.signature)}async function st(n){let e=await v(n.rootSecret),t=b(await S(tt,[p(new Uint8Array([Ie]),e)])),r=0,s=await Te({account:t,device:n.device,signPublicKey:n.signPublicKey,kemPublicKey:n.kemPublicKey,keyEpoch:r,deviceEpoch:n.deviceEpoch}),o=await C(n.rootSecret),a=new Uint8Array(await crypto.subtle.sign("Ed25519",o,s)),i=rt({rootPublicKey:e,account:t,device:n.device,signPublicKey:n.signPublicKey,kemPublicKey:n.kemPublicKey,keyEpoch:r,deviceEpoch:n.deviceEpoch,signature:a});return b(i)}async function ce(n){let e=await v(n);return b(await S(tt,[p(new Uint8Array([Ie]),e)]))}var De=["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 tn=new TextEncoder().encode("calimero.mdma.account-link.v1\0"),nn=new TextEncoder().encode("calimero.mdma.account-login.v1\0"),F=256,ot=F/32,Ee=(F+ot)/11;async function it(){let n=crypto.getRandomValues(new Uint8Array(F/8));return ct(b(n),await sn(n))}async function at(n){let e=rn(n);return ct(b(await on(e)),e.join(" "))}async function M(n){return h(n,"secret",32),{secret:n,publicKey:b(await v(n)),accountId:await ce(n)}}async function J(n){if(!n.nonce)throw new Error("nonce is required to sign an account link");let e=await C(n.rootSecret),t=new Uint8Array(await crypto.subtle.sign("Ed25519",e,p(tn,new TextEncoder().encode(n.nonce))));return pt(t)}async function le(n){if(!n.nonce)throw new Error("nonce is required to sign an account login");let e=await C(n.rootSecret),t=new Uint8Array(await crypto.subtle.sign("Ed25519",e,p(nn,new TextEncoder().encode(n.nonce))));return pt(t)}async function ct(n,e){return{...await M(n),phrase:e}}function rn(n){let e=n.normalize("NFKD").toLowerCase().trim().split(/\s+/),t=e[0]===""?0:e.length;if(t!==Ee)throw new Error(`recovery phrase must be ${Ee} words, got ${t}`);return e}async function sn(n){let e=ut(n)+await lt(n),t=[];for(let r=0;r<Ee;r+=1){let s=Number.parseInt(e.slice(r*11,r*11+11),2);t.push(De[s])}return t.join(" ")}async function on(n){let e="";for(let r of n){let s=De.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(F/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(F)!==await lt(t))throw new Error("recovery phrase checksum failed \u2014 check for a mistyped or transposed word");return t}async function lt(n){let e=new Uint8Array(await crypto.subtle.digest("SHA-256",n));return ut(e).slice(0,ot)}function ut(n){let e="";for(let t of n)e+=t.toString(2).padStart(8,"0");return e}function pt(n){let e="";for(let t of n)e+=String.fromCharCode(t);return btoa(e)}var an=new TextEncoder().encode("calimero.mdma.routing-read.v1\0");async function dt(n,e){h(e,"deviceSecret",32);let t=await C(e),r=p(an,new TextEncoder().encode(n)),s=new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},t,r));return cn(s)}async function ue(n,e){return{"X-Calimero-Credential":e.credential,"X-Calimero-Nonce":n.nonce,"X-Calimero-Signature":await dt(n.nonce,e.deviceSecret)}}function cn(n){let e="";for(let t of n)e+=String.fromCharCode(t);return btoa(e)}var ln="https://cloud.calimero.network",un="x-mdma-session-refresh",pn="x-mdma-session-expires",N=class{constructor(e={}){this.session=null;this.baseUrl=(e.cloudBaseUrl||ln).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 M(e),{nonce:r}=await this.getAccountLoginChallenge();return this.submitAccountLogin({rootPublicKey:t.publicKey,nonce:r,signature:await le({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 ue(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 ue(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(o=>o.toLowerCase())):null;return r.find(o=>o.canAdmit&&(s===null||o.account!==null&&s.has(o.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 M(e),{nonce:r}=await this.getAccountLinkChallenge();return this.submitAccountLink({accountId:t.accountId,rootPublicKey:t.publicKey,nonce:r,signature:await J({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(/^#/,"")),o=s.get("grant"),a=s.get("account"),i=s.get("error"),l={};return o&&(l.grant=o),a&&(l.accountId=a),i&&(l.error=i),l}async linkAccountWithGrant(e){let t=await M(e.rootSecret),r=await this.request("POST","/api/cloud/accounts/link",{body:{grant:e.grant,root_public_key:t.publicKey,signature:await J({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 o=new AbortController,a=setTimeout(()=>o.abort(),this.timeoutMs),i;try{i=await this.fetchImpl(`${this.baseUrl}${t}`,{method:e,headers:s,body:r.body===void 0?void 0:JSON.stringify(r.body),signal:o.signal})}catch(l){throw new w(0,l instanceof Error?l.name:"NetworkError",`${this.baseUrl}${t}`,new Headers,l instanceof Error?l.message:String(l))}finally{clearTimeout(a)}if(this.adoptRollingRefresh(i),!i.ok){let l=await i.text().catch(()=>{});throw new w(i.status,i.statusText,`${this.baseUrl}${t}`,i.headers,l)}if(!(r.parse==="none"||i.status===204))return await i.json()}adoptRollingRefresh(e){let t=e.headers.get(un);if(!t||!this.session)return;let r=e.headers.get(pn),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 dn(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}`,o=[];for(let a of r){if(typeof a!="string")continue;let i=a.trim();if(!i.startsWith("/"))continue;let l=i.endsWith(s)?i:`${i}${s}`;o.includes(l)||o.push(l)}return o}function gn(n){if(n)return typeof n=="function"?n:se(n)}var mn="mero-js:token-refresh";function hn(){let e=globalThis.navigator?.locks;return e&&typeof e.request=="function"?e:null}function Ue(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 pe=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=gn(this.config.requestProof);this.httpClient=H({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=Fe(this.httpClient,{baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||"",timeoutMs:this.config.timeoutMs}),this.adminClient=Xe(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 V({httpClient:this.httpClient})),this.rpcClient}get events(){return this.sseClient||(this.sseClient=new G({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 W({httpClient:this.httpClient,sse:this.events})),this.ephemeralClient}get cloud(){return this.cloudClient||(this.cloudClient=new N(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 L({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),o=s.data.access_token;return this.tokenData={access_token:o,refresh_token:s.data.refresh_token,expires_at:Ue(o,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=hn();return t?t.request(mn,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:Ue(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||Ue(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 ve(e)}static buildAuthLoginUrl(e,t){return ke(e,t)}};function fn(n){return new pe(n)}var _e=class{constructor(){this.tokens=null}getTokens(){return this.tokens}setTokens(e){this.tokens=e}clear(){this.tokens=null}},yn="mero-tokens",Me=class{constructor(e=yn){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 bn=new TextEncoder().encode("calimero.warrant.v2"),wn=new TextEncoder().encode("calimero.warrant.intent.v1"),gt=64,Rn="00".repeat(32);async function Ne(n,e){let t=new TextEncoder().encode(JSON.stringify(e));return S(wn,[new TextEncoder().encode(n),t])}async function de(n){let e=h(n.context,"context",32),t=h(n.authorAccount,"authorAccount",32),r=h(n.executor,"executor",32),s=h(n.appVersion??Rn,"appVersion",32),o=mt(n.accountHeads,"accountHeads"),a=mt(n.governanceFloor,"governanceFloor"),i=await C(n.deviceSecret),l=await v(n.deviceSecret),g=new TextEncoder().encode(n.method),d=await Ne(n.method,n.argsJson),u=A(n.nonce),f=A(n.notAfter),y=await S(bn,[e,t,l,r,s,g,d,A(o.length),...o,A(a.length),...a,u,f]),m=new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},i,y));return b(p(e,t,l,r,s,R(g.length),g,d,R(o.length),...o,R(a.length),...a,u,f,m))}function mt(n,e){let t=n??[];if(t.length>gt)throw new Error(`${e} cites ${t.length} heads, over the ${gt} a node accepts`);return t.map((r,s)=>h(r,`${e}[${s}]`,32))}var An=300,ge=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"}},z=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,o=await this.config.nonces.next(),a=this.config.ttlSeconds??An,i=await de({context:e,authorAccount:this.config.authorAccount,executor:s,method:t,argsJson:r,nonce:o,notAfter:BigInt(Math.floor(Date.now()/1e3))+BigInt(a),deviceSecret:this.config.deviceSecret}),l=await this.json("POST",`/admin-api/contexts/${encodeURIComponent(e)}/intents`,{method:t,argsJson:r,warrant:i,authorProof:this.config.authorProof});return{rootHash:l.data.rootHash,returns:l.data.returns??null}}async json(e,t,r){let s={Accept:"application/json"};r!==void 0&&(s["Content-Type"]="application/json");let o=new AbortController,a=setTimeout(()=>o.abort(),this.timeoutMs),i;try{i=await this.fetchImpl(`${this.baseUrl}${t}`,{method:e,headers:s,body:r===void 0?void 0:JSON.stringify(r),signal:o.signal})}catch(l){throw new w(0,l instanceof Error?l.name:"NetworkError",`${this.baseUrl}${t}`,new Headers,l instanceof Error?l.message:String(l))}finally{clearTimeout(a)}if(!i.ok){let l=await i.text().catch(()=>"");if(i.status===400||i.status===403){let g=xn(l);throw new ge(g,/nonce/i.test(g),i.status)}throw new w(i.status,i.statusText,`${this.baseUrl}${t}`,i.headers,l)}return await i.json()}};function xn(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 qe(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 He(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 o=s+1n;return t.setItem(n,o.toString()),Promise.resolve(o)}}}async function Cn(n){if(!n.sessionToken&&!n.googleIdToken)throw new Error("connectCloud needs either a sessionToken or a googleIdToken");let e=new N({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=vn(t,n.namespaceId),s=await e.getNamespaceRelays(r.namespaceId),o=s.find(i=>i.authorshipReady&&i.relayUrl!==null&&i.executorAccount!==null)??null;if(!o)throw new Error(kn(r,s));let a=new z({relayUrl:o.relayUrl,executorAccount:o.executorAccount,authorAccount:n.authorAccount,authorProof:n.authorProof,deviceSecret:n.deviceSecret,nonces:n.nonces??await Pn(n.deviceSecret),ttlSeconds:n.ttlSeconds,fetch:n.fetch,timeoutMs:n.timeoutMs});return{cloud:e,relay:a,namespaceId:r.namespaceId,namespace:r,relayInfo:o,execute:(i,l,g)=>a.execute(i,l,g)}}function vn(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 kn(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 Pn(n){let e=`mero-js:warrant-nonce:${b(await v(n))}`;try{return He(e)}catch{return qe(1)}}var Sn="Noise_NK_25519_AESGCM_SHA256",Ge=32,In=16,Tn=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,110,4,34,4,32]),$e=class n{constructor(e){this.k=null;this.n=0;this.ck=e,this.h=e}static async initialize(){let e=new TextEncoder().encode(Sn),t=new Uint8Array(32);return t.set(e),new n(t)}async mixHash(e){this.h=await En(p(this.h,e))}async mixKey(e){let[t,r]=await yt(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:ft(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:ft(this.n),additionalData:this.h},this.k,e));return this.n+=1,await this.mixHash(e),t}split(){return yt(this.ck,new Uint8Array)}};async function bt(n,e,t){let r=await $e.initialize();await r.mixHash(e),await r.mixHash(n);let s=await Dn(t);return await r.mixHash(s.publicKey),await r.mixKey(await ht(s.privateKey,n)),{message1:p(s.publicKey,await r.encryptAndHash(new Uint8Array)),async finish(a){if(a.length<Ge+In)throw new Error("Noise: message 2 is too short");let i=a.slice(0,Ge);return await r.mixHash(i),await r.mixKey(await ht(s.privateKey,i)),{payload:await r.decryptAndHash(a.slice(Ge)),split:await r.split()}}}}async function Dn(n){if(!n){let r=await crypto.subtle.generateKey({name:"X25519"},!0,["deriveBits"]),s=new Uint8Array(await crypto.subtle.exportKey("raw",r.publicKey));return{privateKey:r.privateKey,publicKey:s}}let e=await crypto.subtle.importKey("pkcs8",p(Tn,n),{name:"X25519"},!0,["deriveBits"]),t=await crypto.subtle.exportKey("jwk",e);return{privateKey:e,publicKey:Un(t.x)}}async function ht(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 ft(n){let e=new Uint8Array(12);return new DataView(e.buffer).setBigUint64(4,BigInt(n),!1),e}async function En(n){return new Uint8Array(await crypto.subtle.digest("SHA-256",n))}async function Le(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 yt(n,e){let t=await Le(n,e),r=await Le(t,new Uint8Array([1])),s=await Le(t,p(r,new Uint8Array([2])));return[r,s]}function Un(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 xt="/sealed/v2/handshake",Ct="/sealed/v2",Q="application/vnd.calimero.sealed",Oe=2,_n=new TextEncoder().encode("calimero/sealed-http/v2"),X=16,Mn=1+X+8,Nn=0,qn=1,Hn=2,Gn=1+64*1024+16,Ln=1024,$n=6e4,On="calimero.tee-attest.transport-key.v1",Kn=[101,204,205,304],vt=new TextEncoder,Y=class extends Error{constructor(){super("The node no longer holds the attested transport key; attest again for the current one");this.name="StaleTransportKeyError"}},$=class extends Error{constructor(t,r,s,o){super(s);this.status=t;this.code=r;this.retryAfterMs=o;this.name="SealedTransportError"}};async function kt(n,e){let t=await crypto.subtle.digest("SHA-256",p(vt.encode(On),n,e));return new Uint8Array(t)}async function jn(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});if(!s.transportPublicKey)throw new Error("The node did not report a transport key; it predates sealed transport");let o=h(s.transportPublicKey,"transportPublicKey",32),a=t.applicationHash?h(t.applicationHash,"applicationHash",32):new Uint8Array(32),i=b(await kt(a,o));if(!await e({quoteB64:s.quoteB64,nonce:r,reportDataSuffix:i}))throw new Error("The attestation did not verify, so its transport key is not trusted");return o}function Bn(n){let e=new URL(n.baseUrl),t=e.pathname.replace(/\/+$/,""),r=`${e.origin}${t}`,s=n.fetch??((u,f)=>fetch(u,f)),o=typeof n.transportPublicKey=="function"?n.transportPublicKey:void 0,a=o?Promise.resolve().then(o):Promise.resolve(n.transportPublicKey),i,l=async()=>{try{return await Rt(s,r,await wt(a))}catch(u){if(!(u instanceof Y)||!o)throw u;return a=Promise.resolve().then(o),Rt(s,r,await wt(a))}},g=async()=>{let u=i??d(void 0),f=await u;if(Date.now()<f.renewAt)return[f,u];let y=d(u);return[await y,y]},d=u=>{if(i===u){let f=l();i=f,f.catch(()=>{i===f&&(i=void 0)})}return i};return async(u,f)=>{let y=new Request(u,f),m=new URL(y.url);if(m.origin!==e.origin||!m.pathname.startsWith(`${t}/`))throw new Error(`Refusing to send ${m.href} outside the sealed node at ${n.baseUrl}`);let I=[];y.headers.forEach((P,q)=>I.push([q,P]));let T={method:y.method,path:m.pathname.slice(t.length)+m.search,headers:I},k=new Uint8Array(await y.arrayBuffer()),D=async P=>{let{requestId:q,header:fe,envelope:Ve}=await Wn(P,T,k),ye=await s(`${r}${Ct}`,{method:"POST",headers:{"content-type":Q},body:Ve,signal:y.signal});if(ye.headers.get("content-type")!==Q)throw await St(ye);return Jn(ye,P.responseKey,fe,q)},[x,O]=await g();try{return await D(x)}catch(P){if(!(P instanceof $)||P.code!=="unknown_session")throw P;return D(await d(O))}}}async function wt(n){let e=await n;if(e.length!==32)throw new Error("transportPublicKey must be 32 bytes");return e}async function Rt(n,e,t){try{return await At(n,e,t)}catch(r){if(!(r instanceof $)||r.code!=="busy")throw r;return await new Promise(s=>setTimeout(s,r.retryAfterMs??1e3)),At(n,e,t)}}async function At(n,e,t){let r=await bt(t,_n),s=await n(`${e}${xt}`,{method:"POST",headers:{"content-type":Q},body:p(new Uint8Array([Oe]),t,r.message1)});if(s.headers.get("content-type")!==Q)throw await St(s);let o=await Xn(s,Ln);return Vn(r,o)}async function Vn(n,e){if(e[0]!==Oe)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!==X+4)throw new Error("The handshake reply is malformed");let o=r.slice(0,X),a=new DataView(r.buffer,r.byteOffset).getUint32(X,!1),[i,l]=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:i,responseKey:l,nextRequestId:1,renewAt:Date.now()+a*1e3-$n,header(g){let d=new Uint8Array(Mn);return d[0]=Oe,d.set(o,1),new DataView(d.buffer).setBigUint64(1+X,BigInt(g),!1),d}}}async function Wn(n,e,t){let r=n.nextRequestId;n.nextRequestId+=1;let s=n.header(r),o=await crypto.subtle.encrypt({name:"AES-GCM",iv:Pt(r,0),additionalData:s},n.requestKey,Fn(e,t));return{requestId:r,header:s,envelope:p(s,new Uint8Array(o))}}function Pt(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 Fn(n,e){let t=vt.encode(JSON.stringify(n)),r=new Uint8Array(4);return new DataView(r.buffer).setUint32(0,t.length,!1),p(r,t,e)}async function Jn(n,e,t,r){if(!n.body)throw new Error("The sealed response has no body");let s=zn(n.body.getReader()),o=0,a=async()=>{let d=await s.next();if(!d)return null;let u;try{u=new Uint8Array(await crypto.subtle.decrypt({name:"AES-GCM",iv:Pt(r,o),additionalData:t},e,d))}catch{throw new Error("A sealed response frame did not open: it was not sealed by the attested node")}return o+=1,{kind:u[0],data:u.slice(1)}},i=await a();if(!i||i.kind!==Nn)throw new Error("The sealed response is malformed");let l=JSON.parse(new TextDecoder().decode(i.data));if(Kn.includes(l.status))return await s.cancel(),new Response(null,{status:l.status,headers:l.headers});let g=new ReadableStream({async pull(d){try{let u=await a();u?u.kind===qn?d.enqueue(u.data):u.kind===Hn?(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(u){d.error(u)}},cancel(){return s.cancel()}});return new Response(g,{status:l.status,headers:l.headers})}function zn(n){let e=new Uint8Array,t=async r=>{for(;e.length<r;){let{done:s,value:o}=await n.read();if(s)return!1;e=p(e,o)}return!0};return{async next(){if(!await t(4))return null;let r=new DataView(e.buffer,e.byteOffset).getUint32(0,!1);if(r>Gn)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 Xn(n,e){if(!n.body)return new Uint8Array;let t=n.body.getReader(),r=new Uint8Array;for(;;){let{done:s,value:o}=await t.read();if(s)return r;if(r=p(r,o),r.length>e)throw await t.cancel(),new Error("The handshake reply is malformed: it is too long")}}async function St(n){let e,t=`Sealed request refused: HTTP ${n.status}`;try{let o=await n.json();e=o?.error?.code,o?.error?.message&&(t=`Sealed request refused: ${o.error.message}`)}catch{}if(e==="stale_transport_key")return new Y;let r=Number(n.headers.get("retry-after")),s=Number.isFinite(r)&&r>0?Math.min(r,5)*1e3:void 0;return new $(n.status,e,t,s)}var je=8,Qn=new TextEncoder().encode("calimero.namespace.v1"),Yn=0,It={GroupCreated:0,GroupReparented:1,GroupDeleted:2,AdminChanged:3,PolicyUpdated:4,MemberJoined:5,KeyDelivery:6,MemberJoinedOpen:7,MemberJoinedAt:8,NamespaceCreated:9,MemberJoinedViaTeeAttestation:10};function Ke(n,e){if(n.length!==32)throw new Error(`${e} must be 32 bytes, got ${n.length}`);return new Uint8Array(n)}function Tt(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 p(new Uint8Array([1]),new Uint8Array(n))}function Dt(n){let e=new TextEncoder().encode(n);return p(R(e.length),e)}function me(n){let e=n.invitation,t=e.admitters??[],r=n.admitter_addrs??[];return p(Ke(e.inviter_identity,"inviter_identity"),Ke(e.group_id,"group_id"),A(e.expiration_timestamp),Ke(e.secret_salt,"secret_salt"),new Uint8Array([e.invited_role]),R(t.length),...t.map((s,o)=>h(s,`admitters[${o}]`,32)),Dt(n.inviter_signature),n.inviter_account?p(new Uint8Array([1]),h(n.inviter_account,"inviter_account",32)):new Uint8Array([0]),R(r.length),...r.map(Dt),Tt(n.application_id,"application_id"),Tt(n.app_key,"app_key"))}async function Et(n){let e=n.parentOpHashes??[],t=h(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)),o=r?p(new Uint8Array([It.MemberJoinedAt]),h(n.member,"member",32),me(n.invitation),A(s),t):p(new Uint8Array([It.MemberJoined]),h(n.member,"member",32),me(n.invitation),t),a=p(new Uint8Array([Yn]),o),i=await C(n.deviceSecret),l=await v(n.deviceSecret),g=p(new Uint8Array([je]),h(n.namespaceId,"namespaceId",32),R(e.length),...e.map((f,y)=>h(f,`parentOpHashes[${y}]`,32)),l,A(n.nonce),a),d=new Uint8Array(await crypto.subtle.sign("Ed25519",i,p(Qn,g))),u=new Uint8Array([0]);return b(p(g,d,u))}var Zn=new TextEncoder().encode("calimero.auth.login.v1"),Ut={webOrigin:0,codeSigningId:1,cli:2};function _t(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 er(n){return p(Uint8Array.from([Ut[n.kind]]),_t(n))}function tr(n){let e=Uint8Array.from([Ut[n.kind]]);if(n.kind==="cli")return e;let t=_t(n);return p(e,R(t.length),t)}async function he(n){let e=h(n.node,"node",32),t=h(n.challenge,"challenge",32),r=h(n.sessionKey,"sessionKey",32),s=await C(n.deviceSecret),o=await v(n.deviceSecret),a=A(n.issuedAt),i=A(n.expiresAt),l=await S(Zn,[e,er(n.audience),t,r,o,a,i]),g=new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},s,l));return b(p(e,tr(n.audience),t,r,o,a,i,g))}var nr=300;async function Be(){let n=b(crypto.getRandomValues(new Uint8Array(32)));return{publicKey:b(await v(n)),secret:n}}function rr(n){switch(n.kind){case"webOrigin":return n.origin;case"codeSigningId":return n.id;case"cli":return"cli"}}async function Mt(n){let e=n.nodeUrl.replace(/\/+$/,""),t=n.fetch??globalThis.fetch,r=n.timeoutMs??1e4,s=async(y,m)=>{let I=new AbortController,T=setTimeout(()=>I.abort(),r),k;try{k=await t(`${e}${y}`,{...m,signal:I.signal})}catch(x){throw new w(0,x instanceof Error?x.name:"NetworkError",`${e}${y}`,new Headers,x instanceof Error?x.message:String(x))}finally{clearTimeout(T)}let D=await k.text().catch(()=>"");if(!k.ok)throw new w(k.status,k.statusText,`${e}${y}`,k.headers,D);return D?JSON.parse(D):{}},o=await s("/auth/challenge",{method:"GET",headers:{Accept:"application/json"}}),a=o.challenge??o.data?.challenge;if(!a)throw new Error("the node issued no challenge");let i=await Be(),l=Math.floor(Date.now()/1e3),g=await he({node:n.node,audience:n.audience,challenge:a,sessionKey:i.publicKey,issuedAt:l,expiresAt:l+(n.ttlSeconds??nr),deviceSecret:n.deviceSecret}),d=await s("/auth/token",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({auth_method:"account_proof",public_key:i.publicKey,client_name:n.clientName??rr(n.audience),timestamp:l,provider_data:{challenge:a,login_statement:g,account_proof:n.accountProof}})}),u=d.access_token??d.data?.access_token,f=d.refresh_token??d.data?.refresh_token;if(!u)throw new Error("the node minted no session");return{accessToken:u,refreshToken:f??"",sessionKey:i.publicKey,sessionSecret:i.secret}}var Nt=[2428,2429,2528,2529],sr="localhost",or=2e3;function qt(n){return`http://${sr}:${n}`}function Ht(n,e){let t=n.endsWith("/")?n:`${n}/`;return new URL(e,t).toString()}async function Gt(n,e={}){let{timeoutMs:t=or,signal:r}=e;if(r?.aborted)return!1;let s=new AbortController,o=()=>s.abort(),a=r;a&&a.addEventListener("abort",o,{once:!0});let i=setTimeout(()=>s.abort(),t);try{let l=Ht(n,"admin-api/health"),g=await fetch(l,{method:"GET",signal:s.signal});if(!g.ok)return!1;try{let d=await g.json(),u=d?.data?.status!==void 0?d?.data?.status:d?.status;return u===void 0?!0:typeof u=="string"&&u.toLowerCase()==="alive"}catch{return!0}}catch{return!1}finally{clearTimeout(i),a&&a.removeEventListener("abort",o)}}async function ir(n={}){let{ports:e=Nt,timeoutMs:t,signal:r}=n;return(await Promise.all(e.map(async o=>{let a=qt(o);return await Gt(a,{timeoutMs:t,signal:r})?a:null}))).filter(o=>o!==null)}export{_ as AdminApiClient,U as AuthApiClient,E as AuthRevokedError,B as CAPABILITIES,N as CloudClient,Nt as DEFAULT_LOCAL_NODE_PORTS,W as EphemeralClient,xt as HANDSHAKE_PATH,w as HTTPError,ge as IntentRefusedError,Me as LocalStorageTokenStore,_e as MemoryTokenStore,pe as MeroJs,z as RelayClient,V as RpcClient,oe as RpcError,Q as SEALED_CONTENT_TYPE,Ct as SEALED_PATH,je as SIGNED_NAMESPACE_OP_SCHEMA_VERSION,$ as SealedTransportError,G as SseClient,Y as StaleTransportKeyError,K as WebHttpClient,L as WsClient,ce as accountForRoot,at as accountRootFromPhrase,M as accountRootFromSecret,dn as admitterAddrsFromNetworkStatus,ke as buildAuthLoginUrl,re as callerProof,be as combineSignals,Vt as compareSemver,Cn as connectCloud,Lr as createAdminApiClient,Xe as createAdminApiClientFromHttpClient,vr as createAuthApiClient,Fe as createAuthApiClientFromHttpClient,Hr as createBrowserAdminApiClient,xr as createBrowserAuthApiClient,H as createBrowserHttpClient,Re as createHttpClient,He as createLocalStorageNonceSource,qe as createMemoryNonceSource,fn as createMeroJs,Gr as createNodeAdminApiClient,Cr as createNodeAuthApiClient,Z as createNodeHttpClient,se as createProofSigner,Bt as createRetryableMethod,Bn as createSealedFetch,we as createTimeoutSignal,Ae as createUniversalHttpClient,Te as deviceCertPayload,ir as discoverLocalNodes,me as encodeSignedInvitation,jn as fetchAttestedTransportKey,it as generateAccountRoot,Be as generateSessionKey,xe as hasCap,Ur as hexEncodeUtf8,Ne as intentHash,ae as jsonCodec,qt as localNodeUrl,Mt as login,nt as mintDeviceId,Ht as nodeEndpoint,ve as parseAuthCallback,Gt as probeNodeHealth,Pe as requestBodyHash,ue as routingProofHeaders,J as signAccountLink,le as signAccountLogin,st as signDeviceCert,he as signLoginStatement,Et as signMemberJoinOp,ne as signRequest,dt as signRoutingChallenge,de as signWarrant,kt as transportKeyBinding,Ce as withCap,ee as withRetry,Pr as withoutCap};
|
|
1
|
+
function we(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 Re(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 $t=new Set(["token_reuse","token_revoked"]);function Ot(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 w=class extends Error{constructor(t,r,s,i,a){let o=Ot(a);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"}toJSON(){return{status:this.status,statusText:this.statusText,url:this.url,headers:Fe(this.headers),bodyText:this.bodyText}}},E=class extends w{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 Fe(n){let e={};return n.forEach((t,r)=>{e[r]=t}),e}function Kt(n){try{return new URL(n).pathname}catch{let e=n.indexOf("?");return e===-1?n:n.slice(0,e)}}var K=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:Fe(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(),l=this.createAbortSignal(t),g=await this.buildHeaders(t?.headers),p;g instanceof Headers?(p={},g.forEach((h,A)=>{p[A]=h})):p=g;let u={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)&&(u.body=t.body);let y;if(r>0&&s!==void 0){let h=t?.timeoutMs||this.transport.timeoutMs;if(h){let A=Date.now()-o,I=Math.max(0,h-A);y=this.createAbortSignal({...t,timeoutMs:I})}else y=this.createAbortSignal(t)}else y=l;if(y&&(u.signal=y),this.transport.credentials!==void 0&&(u.credentials=this.transport.credentials),t?.mode!==void 0&&(u.mode=t.mode),t?.cache!==void 0&&(u.cache=t.cache),t?.redirect!==void 0&&(u.redirect=t.redirect),t?.referrer!==void 0&&(u.referrer=t.referrer),t?.referrerPolicy!==void 0&&(u.referrerPolicy=t.referrerPolicy),t?.integrity!==void 0&&(u.integrity=t.integrity),t?.keepalive!==void 0&&(u.keepalive=t.keepalive),this.transport.getProof){let h=await this.transport.getProof({method:u.method??"GET",path:Kt(a),body:u.body});h&&(p["X-Calimero-Proof"]=h)}try{let h=await this.transport.fetch(a,u);if(!h.ok){let A=await this.getBodyText(h),I=new w(h.status,h.statusText,a,h.headers,A),C=h.headers.get("x-auth-error");if((h.status===401||h.status===403)&&C&&$t.has(C)){if(this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,this.transport.onAuthRevoked)try{await this.transport.onAuthRevoked()}catch{}throw new E(C,h.status,h.statusText,a,h.headers,A)}let D=t?.signal?.aborted===!0;if(h.status===401&&this.transport.refreshToken&&C==="token_expired"&&r<1&&!m&&!D)try{let v=this.refreshTokenPromise;v||(v=this.transport.refreshToken(),this.refreshTokenPromise=v);let O=await v;if(!O||O.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 P=this.onTokenRefreshPromise;P||(P=this.transport.onTokenRefresh(O),this.onTokenRefreshPromise=P),await P,this.refreshTokenPromise=null,this.onTokenRefreshPromise=null;let q=t?.timeoutMs||this.transport.timeoutMs;if(q&&s!==void 0){let ye=Date.now()-o;if(q-ye<=0)throw I}return this.makeRequest(e,t,r+1,o)}catch(v){throw this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,v instanceof Error&&v.message.includes("onTokenRefresh")?v:I}throw I}return this.parseResponse(h,t?.parse)}catch(h){throw h instanceof w||h instanceof Error&&h.message.includes("onTokenRefresh")?h:new w(0,"Network Error",a,new Headers,h instanceof Error?h.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(Re(r)),t.length>0?we(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 Ae(n){return new K(n)}function H(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 Ae(e)}function ee(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 Ae(r)}function xe(n){return typeof window<"u"?H(n):ee(n)}function jt(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 Bt(n){let t=250*Math.pow(2,n-1),r=(Math.random()-.5)*.4*t;return Math.max(0,t+r)}async function te(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,!jt(r,t-s))throw r;let a=Bt(s),g=r.headers?.get?.("Retry-After");if(g){let p=parseInt(g,10);if(!isNaN(p))a=Math.max(a,p*1e3);else{let u=new Date(g);if(!isNaN(u.getTime())){let m=Math.max(0,u.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 Vt(n,e={}){return async(...t)=>te(()=>n(...t),e)}var U=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 j=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 Pr(n){let e=new j;return new U(e)}function Tr(n){let e=new j;return new U(e)}function Ir(n){let e=new j;return new U(e)}function Je(n,e){return new U(n)}var B={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 Ce(n,e){let t=e>>>0;return(n&t)>>>0===t}function ve(n,e){return(n|e)>>>0}function Er(n,e){return(n&~e)>>>0}function c(n){return n?.data}function Wt(n,e){let[t,r]=ze(n),[s,i]=ze(e),a=t.split("."),o=s.split("."),l=Math.max(a.length,o.length);for(let m=0;m<l;m++){let y=Qe(a[m]??"0",o[m]??"0");if(y!==0)return y}if(r===void 0&&i===void 0)return 0;if(r===void 0)return 1;if(i===void 0)return-1;let g=r.split("."),p=i.split("."),u=Math.max(g.length,p.length);for(let m=0;m<u;m++){if(m>=g.length)return-1;if(m>=p.length)return 1;let y=Qe(g[m],p[m]);if(y!==0)return y}return 0}function ze(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 Qe(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 Ft(n,e,t){return te(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 M=class{constructor(e){this.httpClient=e}async healthCheck(){return c(await this.httpClient.get("/admin-api/health"))}async readinessCheck(){return c(await this.httpClient.get("/admin-api/ready"))}async isAuthed(){return this.httpClient.get("/admin-api/is-authed")}async installApplication(e){return c(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 Ft(r.toString(),"versions",t)).json();return(Array.isArray(i)?i:[]).map(a=>a.appVersion).filter(a=>typeof a=="string").sort((a,o)=>Wt(o,a))}async installDevApplication(e){return c(await this.httpClient.post("/admin-api/install-dev-application",e))}async uninstallApplication(e){return c(await this.httpClient.delete(`/admin-api/applications/${e}`))}async listApplications(){return c(await this.httpClient.get("/admin-api/applications"))}async getApplication(e){return c(await this.httpClient.get(`/admin-api/applications/${e}`))}async listApplicationVersions(e){return c(await this.httpClient.get(`/admin-api/applications/${e}/versions`))}async getApplicationAbi(e,t){let r=t?`?service_name=${encodeURIComponent(t)}`:"";return c(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 c(await this.httpClient.post("/admin-api/contexts",t))}async deleteContext(e){return c(await this.httpClient.delete(`/admin-api/contexts/${e}`))}async getContexts(){return c(await this.httpClient.get("/admin-api/contexts"))}async getContext(e){return c(await this.httpClient.get(`/admin-api/contexts/${e}`))}async getContextsForApplication(e){return c(await this.httpClient.get(`/admin-api/contexts/for-application/${e}`))}async generateContextIdentity(){return c(await this.httpClient.post("/admin-api/identity/context",{}))}async getContextIdentities(e){return c(await this.httpClient.get(`/admin-api/contexts/${e}/identities`))}async getContextIdentitiesOwned(e){return c(await this.httpClient.get(`/admin-api/contexts/${e}/identities-owned`))}async joinContext(e){return c(await this.httpClient.post(`/admin-api/contexts/${e}/join`,{}))}async getContextGroup(e){return c(await this.httpClient.get(`/admin-api/contexts/${e}/group`))}async getContextStorage(e){return c(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 c(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=c(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:c(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 c(await this.httpClient.post("/admin-api/alias/create/context",{alias:e.alias,contextId:e.contextId}))}async createApplicationAlias(e){return c(await this.httpClient.post("/admin-api/alias/create/application",{alias:e.alias,applicationId:e.applicationId}))}async lookupContextAlias(e){return c(await this.httpClient.post(`/admin-api/alias/lookup/context/${encodeURIComponent(e)}`,{}))}async lookupApplicationAlias(e){return c(await this.httpClient.post(`/admin-api/alias/lookup/application/${encodeURIComponent(e)}`,{}))}async deleteContextAlias(e){return c(await this.httpClient.post(`/admin-api/alias/delete/context/${encodeURIComponent(e)}`,{}))}async deleteApplicationAlias(e){return c(await this.httpClient.post(`/admin-api/alias/delete/application/${encodeURIComponent(e)}`,{}))}async listContextAliases(){return c(await this.httpClient.get("/admin-api/alias/list/context"))}async listApplicationAliases(){return c(await this.httpClient.get("/admin-api/alias/list/application"))}async createDeviceAlias(e){return c(await this.httpClient.post("/admin-api/alias/create/device",{alias:e.alias,deviceId:e.deviceId}))}async lookupDeviceAlias(e){return c(await this.httpClient.post(`/admin-api/alias/lookup/device/${encodeURIComponent(e)}`,{}))}async deleteDeviceAlias(e){return c(await this.httpClient.post(`/admin-api/alias/delete/device/${encodeURIComponent(e)}`,{}))}async listDeviceAliases(){return c(await this.httpClient.get("/admin-api/alias/list/device"))}async listNamespaces(){return c(await this.httpClient.get("/admin-api/namespaces"))}async getNamespace(e){return c(await this.httpClient.get(`/admin-api/namespaces/${e}`))}async getNodeIdentity(){return c(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 c(await this.httpClient.post(`/admin-api/contexts/${e}/intents`,t))}async queryContext(e,t){return c(await this.httpClient.post(`/admin-api/contexts/${e}/query`,t))}async getIntentRelay(e){return c(await this.httpClient.get(`/admin-api/contexts/${e}/intents`))}async listNamespacesForApplication(e){return c(await this.httpClient.get(`/admin-api/namespaces/for-application/${e}`))}async createNamespace(e){return c(await this.httpClient.post("/admin-api/namespaces",e))}async deleteNamespace(e){return c(await this.httpClient.request(`/admin-api/namespaces/${e}`,{method:"DELETE",body:"{}",headers:{"Content-Type":"application/json"}}))}async createNamespaceInvitation(e,t){return c(await this.httpClient.post(`/admin-api/namespaces/${e}/invite`,t??{}))}async admitJoin(e,t){return c(await this.httpClient.post(`/admin-api/namespaces/${e}/admit`,t,{timeoutMs:65e3}))}async joinNamespace(e,t){let r=c(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 createGroupInNamespace(e,t){return c(await this.httpClient.post(`/admin-api/namespaces/${e}/groups`,t??{}))}async listNamespaceGroups(e){return c(await this.httpClient.get(`/admin-api/namespaces/${e}/groups`))}async initAccountPairing(e){return c(await this.httpClient.post("/admin-api/account/pair-init",e))}async completeAccountPairing(e){return c(await this.httpClient.post("/admin-api/account/pair-complete",e))}async relinkAccountDevice(e,t){return c(await this.httpClient.post(`/admin-api/account/devices/${e}/relink`,t??{}))}async rescopeAccountDevice(e,t){return c(await this.httpClient.put(`/admin-api/account/devices/${encodeURIComponent(e)}/scope`,t))}async signWithAccountRoot(e){return c(await this.httpClient.post("/admin-api/account/sign-with-root",e))}async labelAccountDevice(e,t){return c(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 c(await this.httpClient.post(`/admin-api/namespaces/${e}/account/revoke`,t))}async getGroupInfo(e){return c(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 c(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 c(await this.httpClient.post(`/admin-api/groups/${e}/accounts/${t}/seal`,r))}async listGroupContexts(e){return c(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 c(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(Ce(t,B.CAN_AUTHOR_ON_BEHALF))return{changed:!1,defaultCapabilities:t};let r=ve(t,B.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(Ce(r,B.CAN_AUTHOR_ON_BEHALF))return{changed:!1,capabilities:r};let s=ve(r,B.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 c(await this.httpClient.post(`/admin-api/groups/${e}/sync`,{}))}async upgradeGroup(e,t){return c(await this.httpClient.post(`/admin-api/groups/${e}/upgrade`,t))}async getGroupUpgradeStatus(e){return c(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 c(await this.httpClient.get(`/admin-api/groups/${t}/cascade-status`))}async retryGroupUpgrade(e){return c(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 c(await this.httpClient.post(`/admin-api/groups/${e}/invite`,t??{}))}async joinGroup(e){return c(await this.httpClient.post("/admin-api/groups/join",e))}async joinSubgroupInheritance(e){return c(await this.httpClient.post(`/admin-api/groups/${e}/join-via-inheritance`,{}))}async getTeeInfo(){return c(await this.httpClient.get("/admin-api/tee/info"))}async teeAttest(e){return c(await this.httpClient.post("/admin-api/tee/attest",e))}async teeVerifyQuote(e){return c(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 getCertificate(){return this.httpClient.get("/admin-api/certificate",{parse:"text"})}async createGroup(e){return c(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 Hr(n){return Array.from(new TextEncoder().encode(n),e=>e.toString(16).padStart(2,"0")).join("")}function Kr(n){return new M(H(n))}function jr(n){return new M(ee(n))}function Br(n){return new M(xe(n))}function Xe(n,e){return new M(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 Se(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 Ye=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,112,4,34,4,32]);function R(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 f(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 ne(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 x(n){let e=new Uint8Array(8);return new DataView(e.buffer).setBigUint64(0,BigInt(n),!0),e}function d(...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 T(n,e){let t=[x(n.length),n];for(let r of e)t.push(x(r.length),r);return new Uint8Array(await crypto.subtle.digest("SHA-256",d(...t)))}async function k(n){let e=f(n,"deviceSecret",32),t=d(Ye,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 S(n){let e=f(n,"deviceSecret",32),t=d(Ye,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 Jt=new TextEncoder().encode("calimero.auth.request.v1"),zt=new TextEncoder().encode("calimero.auth.request.body.v1");function Ze(n){let e=new TextEncoder().encode(n);return d(R(e.length),e)}async function Pe(n=new Uint8Array(0)){let e=typeof n=="string"?new TextEncoder().encode(n):n;return T(zt,[e])}async function re(n){let e=await k(n.signerSecret),t=await Pe(n.body),r=x(n.issuedAt),s=x(n.expiresAt),i=new TextEncoder,a=await T(Jt,[i.encode(n.method),i.encode(n.path),t,r,s]),o=new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},e,a));return b(d(Ze(n.method),Ze(n.path),t,r,s,o))}function se(n){let e=ne(n.credential,"credential"),t=ne(n.request,"request signature"),r=n.session===void 0?new Uint8Array([0]):d(new Uint8Array([1]),ne(n.session,"session statement"));return b(d(e,r,t))}function Qt(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 ie(n){let e=n.ttlSeconds??120,t=n.now??(()=>Math.floor(Date.now()/1e3));return async r=>{let s=t();return se({credential:n.credential,session:n.session,request:await re({method:r.method,path:r.path,body:Qt(r.body),issuedAt:s,expiresAt:s+e,signerSecret:n.signerSecret})})}}var oe=class extends Error{constructor(e,t,r,s){super(t),this.name="RpcError",this.code=e,this.data=r,this.type=s}};async function Te(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 oe(s.code??-1,s.message??s.type??"RPC error",s.data,s.type)}return r.result}var V=class{constructor(e){this.httpClient=e.httpClient}async execute(e){let t=await Te(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 Xt=new Set(["MigrationStarted","MigrationProgress","CascadeProgress","MigrationCompleted"]);function et(n){return n.type!==void 0&&Xt.has(n.type)}var Yt=new Set(["token_reuse","token_revoked"]),Zt=new Set([401,403]);function tt(n){let e=n.headers.get("x-auth-error");return!e||!Zt.has(n.status)?null:Yt.has(e)?e:null}var G=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=tt(r),i=await r.text().catch(()=>{});throw s?new E(s,r.status,r.statusText,t,r.headers,i):new w(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 E)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 l of o)if(l.startsWith("data:")){let g=l.slice(5).trim();g&&this.handleMessage(g)}}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=tt(i),o=await i.text().catch(()=>{});this.emit("error",a?new E(a,i.status,i.statusText,`${this.baseUrl}/sse/subscription`,i.headers,o):new w(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 L=ae;function ce(){return{encode(n){return Array.from(new TextEncoder().encode(JSON.stringify(n)))},decode(n){return JSON.parse(new TextDecoder().decode(new Uint8Array(n)))}}}var W=class{constructor(e){this.httpClient=e.httpClient,this.sse=e.sse}async set(e,t,r=ce()){await Te(this.httpClient,"set_ephemeral",{contextId:e,state:r.encode(t)})}subscribe(e,t,r=ce()){let s=i=>{let a=i;if(a.type!=="Ephemeral"||a.contextId!==e)return;let o=a.data;if(!o?.author)return;let l=!!o.removed,g={author:o.author,state:l||o.state===void 0?void 0:r.decode(o.state),removed:l};o.ageMs!==void 0&&(g.ageMs=o.ageMs),t(g)};return this.sse.on("event",s),this.sse.connect().catch(()=>{}),this.sse.subscribe([e]).catch(()=>{}),()=>{this.sse.off("event",s)}}};var en=new TextEncoder().encode("calimero.device.cert.v1"),nt=new TextEncoder().encode("calimero.account.genesis.v1"),tn=new TextEncoder().encode("calimero.device.id.v1"),Ie=2;async function rt(n,e){if(e.length!==16)throw new Error(`nonce must be 16 bytes, got ${e.length}`);let t=f(n,"account",32);return b(await T(tn,[t,e]))}async function De(n){return T(en,[f(n.account,"account",32),f(n.device,"device",32),f(n.signPublicKey,"signPublicKey",32),f(n.kemPublicKey,"kemPublicKey",32),R(n.keyEpoch),R(n.deviceEpoch)])}function st(n){return d(new Uint8Array([Ie]),n.rootPublicKey,R(0),f(n.account,"account",32),f(n.device,"device",32),f(n.signPublicKey,"signPublicKey",32),f(n.kemPublicKey,"kemPublicKey",32),R(n.keyEpoch),R(n.deviceEpoch),n.signature)}async function it(n){let e=await S(n.rootSecret),t=b(await T(nt,[d(new Uint8Array([Ie]),e)])),r=0,s=await De({account:t,device:n.device,signPublicKey:n.signPublicKey,kemPublicKey:n.kemPublicKey,keyEpoch:r,deviceEpoch:n.deviceEpoch}),i=await k(n.rootSecret),a=new Uint8Array(await crypto.subtle.sign("Ed25519",i,s)),o=st({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 le(n){let e=await S(n);return b(await T(nt,[d(new Uint8Array([Ie]),e)]))}var Ee=["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 nn=new TextEncoder().encode("calimero.mdma.account-link.v1\0"),rn=new TextEncoder().encode("calimero.mdma.account-login.v1\0"),F=256,ot=F/32,Ue=(F+ot)/11;async function at(){let n=crypto.getRandomValues(new Uint8Array(F/8));return lt(b(n),await on(n))}async function ct(n){let e=sn(n);return lt(b(await an(e)),e.join(" "))}async function _(n){return f(n,"secret",32),{secret:n,publicKey:b(await S(n)),accountId:await le(n)}}async function J(n){if(!n.nonce)throw new Error("nonce is required to sign an account link");let e=await k(n.rootSecret),t=new Uint8Array(await crypto.subtle.sign("Ed25519",e,d(nn,new TextEncoder().encode(n.nonce))));return dt(t)}async function ue(n){if(!n.nonce)throw new Error("nonce is required to sign an account login");let e=await k(n.rootSecret),t=new Uint8Array(await crypto.subtle.sign("Ed25519",e,d(rn,new TextEncoder().encode(n.nonce))));return dt(t)}async function lt(n,e){return{...await _(n),phrase:e}}function sn(n){let e=n.normalize("NFKD").toLowerCase().trim().split(/\s+/),t=e[0]===""?0:e.length;if(t!==Ue)throw new Error(`recovery phrase must be ${Ue} words, got ${t}`);return e}async function on(n){let e=pt(n)+await ut(n),t=[];for(let r=0;r<Ue;r+=1){let s=Number.parseInt(e.slice(r*11,r*11+11),2);t.push(Ee[s])}return t.join(" ")}async function an(n){let e="";for(let r of n){let s=Ee.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(F/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(F)!==await ut(t))throw new Error("recovery phrase checksum failed \u2014 check for a mistyped or transposed word");return t}async function ut(n){let e=new Uint8Array(await crypto.subtle.digest("SHA-256",n));return pt(e).slice(0,ot)}function pt(n){let e="";for(let t of n)e+=t.toString(2).padStart(8,"0");return e}function dt(n){let e="";for(let t of n)e+=String.fromCharCode(t);return btoa(e)}var cn=new TextEncoder().encode("calimero.mdma.routing-read.v1\0");async function gt(n,e){f(e,"deviceSecret",32);let t=await k(e),r=d(cn,new TextEncoder().encode(n)),s=new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},t,r));return ln(s)}async function pe(n,e){return{"X-Calimero-Credential":e.credential,"X-Calimero-Nonce":n.nonce,"X-Calimero-Signature":await gt(n.nonce,e.deviceSecret)}}function ln(n){let e="";for(let t of n)e+=String.fromCharCode(t);return btoa(e)}var un="https://cloud.calimero.network",pn="x-mdma-session-refresh",dn="x-mdma-session-expires",N=class{constructor(e={}){this.session=null;this.baseUrl=(e.cloudBaseUrl||un).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 _(e),{nonce:r}=await this.getAccountLoginChallenge();return this.submitAccountLogin({rootPublicKey:t.publicKey,nonce:r,signature:await ue({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 pe(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 pe(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 _(e),{nonce:r}=await this.getAccountLinkChallenge();return this.submitAccountLink({accountId:t.accountId,rootPublicKey:t.publicKey,nonce:r,signature:await J({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"),l={};return i&&(l.grant=i),a&&(l.accountId=a),o&&(l.error=o),l}async linkAccountWithGrant(e){let t=await _(e.rootSecret),r=await this.request("POST","/api/cloud/accounts/link",{body:{grant:e.grant,root_public_key:t.publicKey,signature:await J({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(l){throw new w(0,l instanceof Error?l.name:"NetworkError",`${this.baseUrl}${t}`,new Headers,l instanceof Error?l.message:String(l))}finally{clearTimeout(a)}if(this.adoptRollingRefresh(o),!o.ok){let l=await o.text().catch(()=>{});throw new w(o.status,o.statusText,`${this.baseUrl}${t}`,o.headers,l)}if(!(r.parse==="none"||o.status===204))return await o.json()}adoptRollingRefresh(e){let t=e.headers.get(pn);if(!t||!this.session)return;let r=e.headers.get(dn),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 gn(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 l=o.endsWith(s)?o:`${o}${s}`;i.includes(l)||i.push(l)}return i}function mn(n){if(n)return typeof n=="function"?n:ie(n)}var hn="mero-js:token-refresh";function fn(){let e=globalThis.navigator?.locks;return e&&typeof e.request=="function"?e:null}function Me(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 de=class{constructor(e){this.tokenData=null;this.refreshPromise=null;this.rpcClient=null;this.sseClient=null;this.wsClient=null;this.wsWarned=!1;this.config={timeoutMs:1e4,...e},this.tokenStore=e.tokenStore??null,this.tokenStore&&(this.tokenData=this.tokenStore.getTokens());let t=typeof window<"u"&&"__TAURI_INTERNALS__"in window,r=mn(this.config.requestProof);this.httpClient=H({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=Je(this.httpClient,{baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||"",timeoutMs:this.config.timeoutMs}),this.adminClient=Xe(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 V({httpClient:this.httpClient})),this.rpcClient}get events(){return this.sseClient||(this.sseClient=new G({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 W({httpClient:this.httpClient,sse:this.events})),this.ephemeralClient}get cloud(){return this.cloudClient||(this.cloudClient=new N(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 L({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:Me(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=fn();return t?t.request(hn,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:Me(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||Me(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 Se(e,t)}};function yn(n){return new de(n)}var _e=class{constructor(){this.tokens=null}getTokens(){return this.tokens}setTokens(e){this.tokens=e}clear(){this.tokens=null}},bn="mero-tokens",Ne=class{constructor(e=bn){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 wn=new TextEncoder().encode("calimero.warrant.v2"),Rn=new TextEncoder().encode("calimero.warrant.intent.v1"),mt=64,An="00".repeat(32);async function qe(n,e){let t=new TextEncoder().encode(JSON.stringify(e));return T(Rn,[new TextEncoder().encode(n),t])}async function ge(n){let e=f(n.context,"context",32),t=f(n.authorAccount,"authorAccount",32),r=f(n.executor,"executor",32),s=f(n.appVersion??An,"appVersion",32),i=ht(n.accountHeads,"accountHeads"),a=ht(n.governanceFloor,"governanceFloor"),o=await k(n.deviceSecret),l=await S(n.deviceSecret),g=new TextEncoder().encode(n.method),p=await qe(n.method,n.argsJson),u=x(n.nonce),m=x(n.notAfter),y=await T(wn,[e,t,l,r,s,g,p,x(i.length),...i,x(a.length),...a,u,m]),h=new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},o,y));return b(d(e,t,l,r,s,R(g.length),g,p,R(i.length),...i,R(a.length),...a,u,m,h))}function ht(n,e){let t=n??[];if(t.length>mt)throw new Error(`${e} cites ${t.length} heads, over the ${mt} a node accepts`);return t.map((r,s)=>f(r,`${e}[${s}]`,32))}var xn=300,me=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"}},z=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??xn,o=await ge({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}),l=await this.json("POST",`/admin-api/contexts/${encodeURIComponent(e)}/intents`,{method:t,argsJson:r,warrant:o,authorProof:this.config.authorProof});return{rootHash:l.data.rootHash,returns:l.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(l){throw new w(0,l instanceof Error?l.name:"NetworkError",`${this.baseUrl}${t}`,new Headers,l instanceof Error?l.message:String(l))}finally{clearTimeout(a)}if(!o.ok){let l=await o.text().catch(()=>"");if(o.status===400||o.status===403){let g=Cn(l);throw new me(g,/nonce/i.test(g),o.status)}throw new w(o.status,o.statusText,`${this.baseUrl}${t}`,o.headers,l)}return await o.json()}};function Cn(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 He(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 Ge(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)}}}async function vn(n){if(!n.sessionToken&&!n.googleIdToken)throw new Error("connectCloud needs either a sessionToken or a googleIdToken");let e=new N({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=kn(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(Sn(r,s));let a=new z({relayUrl:i.relayUrl,executorAccount:i.executorAccount,authorAccount:n.authorAccount,authorProof:n.authorProof,deviceSecret:n.deviceSecret,nonces:n.nonces??await Pn(n.deviceSecret),ttlSeconds:n.ttlSeconds,fetch:n.fetch,timeoutMs:n.timeoutMs});return{cloud:e,relay:a,namespaceId:r.namespaceId,namespace:r,relayInfo:i,execute:(o,l,g)=>a.execute(o,l,g)}}function kn(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 Sn(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 Pn(n){let e=`mero-js:warrant-nonce:${b(await S(n))}`;try{return Ge(e)}catch{return He(1)}}var Tn="Noise_NK_25519_AESGCM_SHA256",Le=32,In=16,Dn=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,110,4,34,4,32]),Oe=class n{constructor(e){this.k=null;this.n=0;this.ck=e,this.h=e}static async initialize(){let e=new TextEncoder().encode(Tn),t=new Uint8Array(32);return t.set(e),new n(t)}async mixHash(e){this.h=await Un(d(this.h,e))}async mixKey(e){let[t,r]=await bt(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:yt(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:yt(this.n),additionalData:this.h},this.k,e));return this.n+=1,await this.mixHash(e),t}split(){return bt(this.ck,new Uint8Array)}};async function wt(n,e,t){let r=await Oe.initialize();await r.mixHash(e),await r.mixHash(n);let s=await En(t);return await r.mixHash(s.publicKey),await r.mixKey(await ft(s.privateKey,n)),{message1:d(s.publicKey,await r.encryptAndHash(new Uint8Array)),async finish(a){if(a.length<Le+In)throw new Error("Noise: message 2 is too short");let o=a.slice(0,Le);return await r.mixHash(o),await r.mixKey(await ft(s.privateKey,o)),{payload:await r.decryptAndHash(a.slice(Le)),split:await r.split()}}}}async function En(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",d(Dn,n),{name:"X25519"},!0,["deriveBits"]),t=await crypto.subtle.exportKey("jwk",e);return{privateKey:e,publicKey:Mn(t.x)}}async function ft(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 yt(n){let e=new Uint8Array(12);return new DataView(e.buffer).setBigUint64(4,BigInt(n),!1),e}async function Un(n){return new Uint8Array(await crypto.subtle.digest("SHA-256",n))}async function $e(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 bt(n,e){let t=await $e(n,e),r=await $e(t,new Uint8Array([1])),s=await $e(t,d(r,new Uint8Array([2])));return[r,s]}function Mn(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 Ct="/sealed/v2/handshake",vt="/sealed/v2",X="application/vnd.calimero.sealed",Ke=2,_n=new TextEncoder().encode("calimero/sealed-http/v2"),Q=16,Nn=1+Q+8,qn=0,Hn=1,Gn=2,Ln=1+64*1024+16,$n=1024,On=6e4,Kn="calimero.tee-attest.transport-key.v1",jn=[101,204,205,304],kt=new TextEncoder,Y=class extends Error{constructor(){super("The node no longer holds the attested transport key; attest again for the current one");this.name="StaleTransportKeyError"}},$=class extends Error{constructor(t,r,s,i){super(s);this.status=t;this.code=r;this.retryAfterMs=i;this.name="SealedTransportError"}};async function St(n,e){let t=await crypto.subtle.digest("SHA-256",d(kt.encode(Kn),n,e));return new Uint8Array(t)}async function Bn(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=f(s.transportPublicKey,"transportPublicKey",32),a=t.applicationHash?f(t.applicationHash,"applicationHash",32):new Uint8Array(32),o=b(await St(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 Vn(n){let e=new URL(n.baseUrl),t=e.pathname.replace(/\/+$/,""),r=`${e.origin}${t}`,s=n.fetch??((u,m)=>fetch(u,m)),i=typeof n.transportPublicKey=="function"?n.transportPublicKey:void 0,a=i?Promise.resolve().then(i):Promise.resolve(n.transportPublicKey),o,l=async()=>{try{return await At(s,r,await Rt(a))}catch(u){if(!(u instanceof Y)||!i)throw u;return a=Promise.resolve().then(i),At(s,r,await Rt(a))}},g=async()=>{let u=o??p(void 0),m=await u;if(Date.now()<m.renewAt)return[m,u];let y=p(u);return[await y,y]},p=u=>{if(o===u){let m=l();o=m,m.catch(()=>{o===m&&(o=void 0)})}return o};return async(u,m)=>{let y=new Request(u,m),h=new URL(y.url);if(h.origin!==e.origin||!h.pathname.startsWith(`${t}/`))throw new Error(`Refusing to send ${h.href} outside the sealed node at ${n.baseUrl}`);let A=[];y.headers.forEach((P,q)=>A.push([q,P]));let I={method:y.method,path:h.pathname.slice(t.length)+h.search,headers:A},C=new Uint8Array(await y.arrayBuffer()),D=async P=>{let{requestId:q,header:ye,envelope:We}=await Fn(P,I,C),be=await s(`${r}${vt}`,{method:"POST",headers:{"content-type":X},body:We,signal:y.signal});if(be.headers.get("content-type")!==X)throw await Tt(be);return zn(be,P.responseKey,ye,q)},[v,O]=await g();try{return await D(v)}catch(P){if(!(P instanceof $)||P.code!=="unknown_session")throw P;return D(await p(O))}}}async function Rt(n){let e=await n;if(e.length!==32)throw new Error("transportPublicKey must be 32 bytes");return e}async function At(n,e,t){try{return await xt(n,e,t)}catch(r){if(!(r instanceof $)||r.code!=="busy")throw r;return await new Promise(s=>setTimeout(s,r.retryAfterMs??1e3)),xt(n,e,t)}}async function xt(n,e,t){let r=await wt(t,_n),s=await n(`${e}${Ct}`,{method:"POST",headers:{"content-type":X},body:d(new Uint8Array([Ke]),t,r.message1)});if(s.headers.get("content-type")!==X)throw await Tt(s);let i=await Xn(s,$n);return Wn(r,i)}async function Wn(n,e){if(e[0]!==Ke)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!==Q+4)throw new Error("The handshake reply is malformed");let i=r.slice(0,Q),a=new DataView(r.buffer,r.byteOffset).getUint32(Q,!1),[o,l]=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:l,nextRequestId:1,renewAt:Date.now()+a*1e3-On,header(g){let p=new Uint8Array(Nn);return p[0]=Ke,p.set(i,1),new DataView(p.buffer).setBigUint64(1+Q,BigInt(g),!1),p}}}async function Fn(n,e,t){let r=n.nextRequestId;n.nextRequestId+=1;let s=n.header(r),i=await crypto.subtle.encrypt({name:"AES-GCM",iv:Pt(r,0),additionalData:s},n.requestKey,Jn(e,t));return{requestId:r,header:s,envelope:d(s,new Uint8Array(i))}}function Pt(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 Jn(n,e){let t=kt.encode(JSON.stringify(n)),r=new Uint8Array(4);return new DataView(r.buffer).setUint32(0,t.length,!1),d(r,t,e)}async function zn(n,e,t,r){if(!n.body)throw new Error("The sealed response has no body");let s=Qn(n.body.getReader()),i=0,a=async()=>{let p=await s.next();if(!p)return null;let u;try{u=new Uint8Array(await crypto.subtle.decrypt({name:"AES-GCM",iv:Pt(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:u[0],data:u.slice(1)}},o=await a();if(!o||o.kind!==qn)throw new Error("The sealed response is malformed");let l=JSON.parse(new TextDecoder().decode(o.data));if(jn.includes(l.status))return await s.cancel(),new Response(null,{status:l.status,headers:l.headers});let g=new ReadableStream({async pull(p){try{let u=await a();u?u.kind===Hn?p.enqueue(u.data):u.kind===Gn?(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(u){p.error(u)}},cancel(){return s.cancel()}});return new Response(g,{status:l.status,headers:l.headers})}function Qn(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=d(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>Ln)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 Xn(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=d(r,i),r.length>e)throw await t.cancel(),new Error("The handshake reply is malformed: it is too long")}}async function Tt(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 Y;let r=Number(n.headers.get("retry-after")),s=Number.isFinite(r)&&r>0?Math.min(r,5)*1e3:void 0;return new $(n.status,e,t,s)}var Yn=/^[0-9a-f]{96}$/;function Zn(n){let e=Z(n.allowedMrtd,"allowedMrtd");if(e.length===0)throw new Error("allowedMrtd is empty, so no quote would ever be accepted");let t=[Z(n.allowedRtmr0??[],"allowedRtmr0"),Z(n.allowedRtmr1??[],"allowedRtmr1"),Z(n.allowedRtmr2??[],"allowedRtmr2"),Z(n.allowedRtmr3??[],"allowedRtmr3")],r=n.allowedTcbStatuses??["UpToDate"],s=n.now??Date.now;return Object.assign(async({quoteB64:a,nonce:o,reportDataSuffix:l,collateral:g})=>{let p=tr(a),u=g??await n.fetchCollateral?.(p);if(!u)throw new Error("The node sent no collateral for its quote, and no fetchCollateral was given to get it");let m;try{m=n.dcapVerify(p,u,Math.floor(s()/1e3))}catch(A){throw new Error(`The quote did not verify: ${A?.message??String(A)}`)}if(m.status==="Revoked"||!r.includes(m.status))throw new Error(`The platform's TCB status is ${m.status}, which is not accepted`);let y=er(m.report);if(!e.includes(b(y.mrTd)))throw new Error(`MRTD ${b(y.mrTd)} is not an image this verifier trusts`);if([y.rtMr0,y.rtMr1,y.rtMr2,y.rtMr3].forEach((A,I)=>{let C=t[I];if(C.length>0&&!C.includes(b(A)))throw new Error(`RTMR${I} ${b(A)} is not one this verifier trusts`)}),b(y.reportData)!==`${o}${l}`.toLowerCase())throw new Error("The quote does not commit to this nonce and binding");return!0},{includeCollateral:!0})}function Z(n,e){return n.map(t=>{let r=t.trim().toLowerCase();if(!Yn.test(r))throw new Error(`${e} holds ${JSON.stringify(t)}, which is not a 48-byte hex measurement`);return r})}function er(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 tr(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 Be=8,nr=new TextEncoder().encode("calimero.namespace.v1"),rr=0,It={GroupCreated:0,GroupReparented:1,GroupDeleted:2,AdminChanged:3,PolicyUpdated:4,MemberJoined:5,KeyDelivery:6,MemberJoinedOpen:7,MemberJoinedAt:8,NamespaceCreated:9,MemberJoinedViaTeeAttestation:10};function je(n,e){if(n.length!==32)throw new Error(`${e} must be 32 bytes, got ${n.length}`);return new Uint8Array(n)}function Dt(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 d(new Uint8Array([1]),new Uint8Array(n))}function Et(n){let e=new TextEncoder().encode(n);return d(R(e.length),e)}function he(n){let e=n.invitation,t=e.admitters??[],r=n.admitter_addrs??[];return d(je(e.inviter_identity,"inviter_identity"),je(e.group_id,"group_id"),x(e.expiration_timestamp),je(e.secret_salt,"secret_salt"),new Uint8Array([e.invited_role]),R(t.length),...t.map((s,i)=>f(s,`admitters[${i}]`,32)),Et(n.inviter_signature),n.inviter_account?d(new Uint8Array([1]),f(n.inviter_account,"inviter_account",32)):new Uint8Array([0]),R(r.length),...r.map(Et),Dt(n.application_id,"application_id"),Dt(n.app_key,"app_key"))}async function Ut(n){let e=n.parentOpHashes??[],t=f(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?d(new Uint8Array([It.MemberJoinedAt]),f(n.member,"member",32),he(n.invitation),x(s),t):d(new Uint8Array([It.MemberJoined]),f(n.member,"member",32),he(n.invitation),t),a=d(new Uint8Array([rr]),i),o=await k(n.deviceSecret),l=await S(n.deviceSecret),g=d(new Uint8Array([Be]),f(n.namespaceId,"namespaceId",32),R(e.length),...e.map((m,y)=>f(m,`parentOpHashes[${y}]`,32)),l,x(n.nonce),a),p=new Uint8Array(await crypto.subtle.sign("Ed25519",o,d(nr,g))),u=new Uint8Array([0]);return b(d(g,p,u))}var sr=new TextEncoder().encode("calimero.auth.login.v1"),Mt={webOrigin:0,codeSigningId:1,cli:2};function _t(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 ir(n){return d(Uint8Array.from([Mt[n.kind]]),_t(n))}function or(n){let e=Uint8Array.from([Mt[n.kind]]);if(n.kind==="cli")return e;let t=_t(n);return d(e,R(t.length),t)}async function fe(n){let e=f(n.node,"node",32),t=f(n.challenge,"challenge",32),r=f(n.sessionKey,"sessionKey",32),s=await k(n.deviceSecret),i=await S(n.deviceSecret),a=x(n.issuedAt),o=x(n.expiresAt),l=await T(sr,[e,ir(n.audience),t,r,i,a,o]),g=new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},s,l));return b(d(e,or(n.audience),t,r,i,a,o,g))}var ar=300;async function Ve(){let n=b(crypto.getRandomValues(new Uint8Array(32)));return{publicKey:b(await S(n)),secret:n}}function cr(n){switch(n.kind){case"webOrigin":return n.origin;case"codeSigningId":return n.id;case"cli":return"cli"}}async function Nt(n){let e=n.nodeUrl.replace(/\/+$/,""),t=n.fetch??globalThis.fetch,r=n.timeoutMs??1e4,s=async(y,h)=>{let A=new AbortController,I=setTimeout(()=>A.abort(),r),C;try{C=await t(`${e}${y}`,{...h,signal:A.signal})}catch(v){throw new w(0,v instanceof Error?v.name:"NetworkError",`${e}${y}`,new Headers,v instanceof Error?v.message:String(v))}finally{clearTimeout(I)}let D=await C.text().catch(()=>"");if(!C.ok)throw new w(C.status,C.statusText,`${e}${y}`,C.headers,D);return D?JSON.parse(D):{}},i=await s("/auth/challenge",{method:"GET",headers:{Accept:"application/json"}}),a=i.challenge??i.data?.challenge;if(!a)throw new Error("the node issued no challenge");let o=await Ve(),l=Math.floor(Date.now()/1e3),g=await fe({node:n.node,audience:n.audience,challenge:a,sessionKey:o.publicKey,issuedAt:l,expiresAt:l+(n.ttlSeconds??ar),deviceSecret:n.deviceSecret}),p=await s("/auth/token",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({auth_method:"account_proof",public_key:o.publicKey,client_name:n.clientName??cr(n.audience),timestamp:l,provider_data:{challenge:a,login_statement:g,account_proof:n.accountProof}})}),u=p.access_token??p.data?.access_token,m=p.refresh_token??p.data?.refresh_token;if(!u)throw new Error("the node minted no session");return{accessToken:u,refreshToken:m??"",sessionKey:o.publicKey,sessionSecret:o.secret}}var qt=[2428,2429,2528,2529],lr="localhost",ur=2e3;function Ht(n){return`http://${lr}:${n}`}function Gt(n,e){let t=n.endsWith("/")?n:`${n}/`;return new URL(e,t).toString()}async function Lt(n,e={}){let{timeoutMs:t=ur,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 l=Gt(n,"admin-api/health"),g=await fetch(l,{method:"GET",signal:s.signal});if(!g.ok)return!1;try{let p=await g.json(),u=p?.data?.status!==void 0?p?.data?.status:p?.status;return u===void 0?!0:typeof u=="string"&&u.toLowerCase()==="alive"}catch{return!0}}catch{return!1}finally{clearTimeout(o),a&&a.removeEventListener("abort",i)}}async function pr(n={}){let{ports:e=qt,timeoutMs:t,signal:r}=n;return(await Promise.all(e.map(async i=>{let a=Ht(i);return await Lt(a,{timeoutMs:t,signal:r})?a:null}))).filter(i=>i!==null)}export{M as AdminApiClient,U as AuthApiClient,E as AuthRevokedError,B as CAPABILITIES,N as CloudClient,qt as DEFAULT_LOCAL_NODE_PORTS,W as EphemeralClient,Ct as HANDSHAKE_PATH,w as HTTPError,me as IntentRefusedError,Ne as LocalStorageTokenStore,_e as MemoryTokenStore,de as MeroJs,z as RelayClient,V as RpcClient,oe as RpcError,X as SEALED_CONTENT_TYPE,vt as SEALED_PATH,Be as SIGNED_NAMESPACE_OP_SCHEMA_VERSION,$ as SealedTransportError,G as SseClient,Y as StaleTransportKeyError,K as WebHttpClient,L as WsClient,le as accountForRoot,ct as accountRootFromPhrase,_ as accountRootFromSecret,gn as admitterAddrsFromNetworkStatus,Se as buildAuthLoginUrl,se as callerProof,we as combineSignals,Wt as compareSemver,vn as connectCloud,Br as createAdminApiClient,Xe as createAdminApiClientFromHttpClient,Ir as createAuthApiClient,Je as createAuthApiClientFromHttpClient,Kr as createBrowserAdminApiClient,Pr as createBrowserAuthApiClient,H as createBrowserHttpClient,Ae as createHttpClient,Ge as createLocalStorageNonceSource,He as createMemoryNonceSource,yn as createMeroJs,jr as createNodeAdminApiClient,Tr as createNodeAuthApiClient,ee as createNodeHttpClient,ie as createProofSigner,Zn as createQuoteVerifier,Vt as createRetryableMethod,Vn as createSealedFetch,Re as createTimeoutSignal,xe as createUniversalHttpClient,De as deviceCertPayload,pr as discoverLocalNodes,he as encodeSignedInvitation,Bn as fetchAttestedTransportKey,at as generateAccountRoot,Ve as generateSessionKey,Ce as hasCap,Hr as hexEncodeUtf8,qe as intentHash,ce as jsonCodec,Ht as localNodeUrl,Nt as login,rt as mintDeviceId,Gt as nodeEndpoint,ke as parseAuthCallback,Lt as probeNodeHealth,Pe as requestBodyHash,pe as routingProofHeaders,J as signAccountLink,ue as signAccountLogin,it as signDeviceCert,fe as signLoginStatement,Ut as signMemberJoinOp,re as signRequest,gt as signRoutingChallenge,ge as signWarrant,St as transportKeyBinding,ve as withCap,te as withRetry,Er as withoutCap};
|
|
3
3
|
//# sourceMappingURL=index.browser.mjs.map
|