@calimero-network/mero-js 19.1.0 → 19.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin-api/admin-types.d.ts +37 -3
- package/dist/index.browser.mjs +2 -2
- package/dist/index.browser.mjs.map +4 -4
- package/dist/index.cjs +67 -0
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/index.mjs +67 -0
- package/dist/index.mjs.map +4 -4
- package/dist/login/index.d.ts +2 -0
- package/dist/login/index.js +2 -0
- package/dist/login/login.d.ts +101 -0
- package/dist/login/login.js +109 -0
- package/package.json +1 -1
|
@@ -503,6 +503,29 @@ export interface NodeIdentity {
|
|
|
503
503
|
* invite on it should not collapse the two.
|
|
504
504
|
*/
|
|
505
505
|
holdsAccountRoot?: boolean;
|
|
506
|
+
/**
|
|
507
|
+
* Whether this node's device is certified into the account it speaks for.
|
|
508
|
+
*
|
|
509
|
+
* Pair-init mints a device but only pair-complete certifies it, and
|
|
510
|
+
* `holdsAccountRoot` is `false` across both states, so this is what tells
|
|
511
|
+
* them apart. Absent on a node predating the field.
|
|
512
|
+
*/
|
|
513
|
+
deviceCertified?: boolean;
|
|
514
|
+
/**
|
|
515
|
+
* Hex X25519 public agreement key of this node's device, `null` before it
|
|
516
|
+
* has a device row.
|
|
517
|
+
*
|
|
518
|
+
* The same key pairing calls `kemPublicKey`; core's name is kept here.
|
|
519
|
+
*/
|
|
520
|
+
deviceAgreementKey?: string | null;
|
|
521
|
+
/**
|
|
522
|
+
* Hex id of the account namespace this node follows.
|
|
523
|
+
*
|
|
524
|
+
* A holder derives it before the namespace exists so an invite can carry
|
|
525
|
+
* it; a device records it at pair-init. `null` on a node that neither holds
|
|
526
|
+
* a root nor has paired with the id; absent on an old node.
|
|
527
|
+
*/
|
|
528
|
+
accountNamespaceId?: string | null;
|
|
506
529
|
}
|
|
507
530
|
/**
|
|
508
531
|
* @deprecated Use {@link AdminApiClient.getNodeIdentity} instead. Nothing here
|
|
@@ -617,8 +640,7 @@ export interface AccountPairInitRequest {
|
|
|
617
640
|
*/
|
|
618
641
|
accountRootPublicKey: string;
|
|
619
642
|
/**
|
|
620
|
-
* Ids of the namespaces to enroll into, 64 hex characters each.
|
|
621
|
-
* a device certified into nothing listens on no topic.
|
|
643
|
+
* Ids of the namespaces to enroll into, 64 hex characters each.
|
|
622
644
|
*
|
|
623
645
|
* The caller has to supply these, because the joining node cannot discover
|
|
624
646
|
* them - it is a member of nothing and holds no scope key, so it can neither
|
|
@@ -629,8 +651,20 @@ export interface AccountPairInitRequest {
|
|
|
629
651
|
* with the applications the holder scopes `pair-complete` to: a binding
|
|
630
652
|
* published where the device is not listening is picked up whenever it does
|
|
631
653
|
* subscribe, and a subscription the holder never reaches costs nothing.
|
|
654
|
+
*
|
|
655
|
+
* Core refuses only a request that names neither this nor `accountNamespace`.
|
|
656
|
+
* A caller that sends `accountNamespace` may leave this empty.
|
|
632
657
|
*/
|
|
633
|
-
namespaces
|
|
658
|
+
namespaces?: string[];
|
|
659
|
+
/**
|
|
660
|
+
* Hex id of the account namespace to follow - the value
|
|
661
|
+
* {@link NodeIdentity.accountNamespaceId} reports on the holder.
|
|
662
|
+
*
|
|
663
|
+
* The device then learns the account's namespaces from the account namespace
|
|
664
|
+
* itself, so the caller need not know them up front. A caller that does not
|
|
665
|
+
* send this must name at least one namespace above.
|
|
666
|
+
*/
|
|
667
|
+
accountNamespace?: string;
|
|
634
668
|
}
|
|
635
669
|
/**
|
|
636
670
|
* What the joining device minted, for the account holder to certify.
|
package/dist/index.browser.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
function Y(s){let e=s.filter(Boolean);if(e.length===0)return;let t=AbortSignal;if(typeof t.any=="function")try{return t.any(e)}catch{}let n=new AbortController,r=o=>{n.abort(o.target.reason);for(let i of e)i.removeEventListener("abort",r)};for(let o of e){if(o.aborted)return AbortSignal.abort(o.reason);o.addEventListener("abort",r,{once:!0})}return n.signal}function Z(s){if(typeof AbortSignal.timeout=="function")return AbortSignal.timeout(s);let e=new AbortController;return setTimeout(()=>{e.abort(new DOMException("Timeout","TimeoutError"))},s),e.signal}var Oe=new Set(["token_reuse","token_revoked"]);function Le(s){if(s)try{let e=JSON.parse(s)?.error;if(typeof e=="string"&&e.trim()!=="")return e;let t=e?.message;if(typeof t=="string"&&t.trim()!=="")return t}catch{}}var b=class extends Error{constructor(t,n,r,o,i){let a=Le(i);super(a?`HTTP ${t} ${n}: ${a}`:`HTTP ${t} ${n}`);this.status=t;this.statusText=n;this.url=r;this.headers=o;this.bodyText=i;this.name="HTTPError"}toJSON(){return{status:this.status,statusText:this.statusText,url:this.url,headers:fe(this.headers),bodyText:this.bodyText}}},I=class extends b{constructor(t,n,r,o,i,a){super(n,r,o,i,a);this.reason=t;this.name="AuthRevokedError";this.message=`Authentication revoked (${t}): HTTP ${n} ${r}`}};function fe(s){let e={};return s.forEach((t,n)=>{e[n]=t}),e}var U=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,n){return this.request(e,{...n,method:"POST",body:t?JSON.stringify(t):void 0,headers:{"Content-Type":"application/json",...n?.headers}})}async put(e,t,n){return this.request(e,{...n,method:"PUT",body:t?JSON.stringify(t):void 0,headers:{"Content-Type":"application/json",...n?.headers}})}async delete(e,t){return this.request(e,{...t,method:"DELETE"})}async patch(e,t,n){return this.request(e,{...n,method:"PATCH",body:t?JSON.stringify(t):void 0,headers:{"Content-Type":"application/json",...n?.headers}})}async head(e,t){let n=await this.makeRequest(e,{...t,method:"HEAD",parse:"response"});return{headers:fe(n.headers),status:n.status}}async request(e,t){return this.makeRequest(e,t)}async makeRequest(e,t,n=0,r){let i=this.buildUrl(e),a=r??Date.now(),p=this.createAbortSignal(t),u=await this.buildHeaders(t?.headers),m;u instanceof Headers?(m={},u.forEach((l,S)=>{m[S]=l})):m=u;let d={method:t?.method||"GET",headers:m},g=t?.body instanceof ReadableStream||typeof t?.body=="object"&&t?.body!==null&&"getReader"in t.body&&!(t.body instanceof Blob);(t?.body!==void 0&&!g||t?.body!==void 0&&g&&n===0)&&(d.body=t.body);let y;if(n>0&&r!==void 0){let l=t?.timeoutMs||this.transport.timeoutMs;if(l){let S=Date.now()-a,N=Math.max(0,l-S);y=this.createAbortSignal({...t,timeoutMs:N})}else y=this.createAbortSignal(t)}else y=p;y&&(d.signal=y),this.transport.credentials!==void 0&&(d.credentials=this.transport.credentials),t?.mode!==void 0&&(d.mode=t.mode),t?.cache!==void 0&&(d.cache=t.cache),t?.redirect!==void 0&&(d.redirect=t.redirect),t?.referrer!==void 0&&(d.referrer=t.referrer),t?.referrerPolicy!==void 0&&(d.referrerPolicy=t.referrerPolicy),t?.integrity!==void 0&&(d.integrity=t.integrity),t?.keepalive!==void 0&&(d.keepalive=t.keepalive);try{let l=await this.transport.fetch(i,d);if(!l.ok){let S=await this.getBodyText(l),N=new b(l.status,l.statusText,i,l.headers,S),O=l.headers.get("x-auth-error");if((l.status===401||l.status===403)&&O&&Oe.has(O)){if(this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,this.transport.onAuthRevoked)try{await this.transport.onAuthRevoked()}catch{}throw new I(O,l.status,l.statusText,i,l.headers,S)}let $e=t?.signal?.aborted===!0;if(l.status===401&&this.transport.refreshToken&&O==="token_expired"&&n<1&&!g&&!$e)try{let x=this.refreshTokenPromise;x||(x=this.transport.refreshToken(),this.refreshTokenPromise=x);let Q=await x;if(!Q||Q.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 L=this.onTokenRefreshPromise;L||(L=this.transport.onTokenRefresh(Q),this.onTokenRefreshPromise=L),await L,this.refreshTokenPromise=null,this.onTokenRefreshPromise=null;let ge=t?.timeoutMs||this.transport.timeoutMs;if(ge&&r!==void 0){let qe=Date.now()-a;if(ge-qe<=0)throw N}return this.makeRequest(e,t,n+1,a)}catch(x){throw this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,x instanceof Error&&x.message.includes("onTokenRefresh")?x:N}throw N}return this.parseResponse(l,t?.parse)}catch(l){throw l instanceof b||l instanceof Error&&l.message.includes("onTokenRefresh")?l:new b(0,"Network Error",i,new Headers,l instanceof Error?l.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 n=e?.timeoutMs||this.transport.timeoutMs;return n&&t.push(Z(n)),t.length>0?Y(t):void 0}async buildHeaders(e){let t={...this.transport.defaultHeaders};if(this.transport.getAuthToken)try{let n=await this.transport.getAuthToken();n&&n.trim()!==""&&(t.Authorization=`Bearer ${n}`)}catch{}return e&&(e instanceof Headers?e.forEach((n,r)=>{t[r]=n}):Array.isArray(e)?e.forEach(([n,r])=>{t[n]=r}):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 n=await e.text();if(!n)return null;try{return JSON.parse(n)}catch{throw new Error(`Expected a JSON response (status ${e.status}) but body was not JSON: ${n.slice(0,200)}`)}}}}async getBodyText(e){try{let t=await e.text();return t.length>65536?t.slice(0,65536)+"...":t}catch{return""}}};function ee(s){return new U(s)}function D(s){let e={fetch:(t,n)=>globalThis.fetch(t,n),baseUrl:s.baseUrl,getAuthToken:s.getAuthToken,onTokenRefresh:s.onTokenRefresh,refreshToken:s.refreshToken,onAuthRevoked:s.onAuthRevoked,defaultHeaders:s.defaultHeaders,timeoutMs:s.timeoutMs,credentials:s.credentials,defaultAbortSignal:s.defaultAbortSignal};return ee(e)}function j(s){let e=s.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 n={fetch:e===globalThis.fetch?(r,o)=>globalThis.fetch(r,o):(r,o)=>e(r,o),baseUrl:s.baseUrl,getAuthToken:s.getAuthToken,onTokenRefresh:s.onTokenRefresh,refreshToken:s.refreshToken,onAuthRevoked:s.onAuthRevoked,defaultHeaders:s.defaultHeaders,timeoutMs:s.timeoutMs,credentials:s.credentials,defaultAbortSignal:s.defaultAbortSignal};return ee(n)}function te(s){return typeof window<"u"?D(s):j(s)}function je(s,e){if(e<=0)return!1;let n=s?.name;if(n==="TimeoutError")return!0;if(n==="AbortError")return!1;let r=s;if("status"in r&&typeof r.status=="number"){let o=r.status;return o>=500||o===429}return n==="TypeError"}function We(s){let t=250*Math.pow(2,s-1),n=(Math.random()-.5)*.4*t;return Math.max(0,t+n)}async function W(s,e={}){let{attempts:t=3}=e,n;for(let r=1;r<=t;r++)try{return await s(r)}catch(o){if(n=o,!je(n,t-r))throw n;let i=We(r),u=n.headers?.get?.("Retry-After");if(u){let m=parseInt(u,10);if(!isNaN(m))i=Math.max(i,m*1e3);else{let d=new Date(u);if(!isNaN(d.getTime())){let g=Math.max(0,d.getTime()-Date.now());i=Math.max(i,Math.min(g,6e4))}}}await new Promise(m=>setTimeout(m,i))}throw n||new Error("Retry failed without error")}function Be(s,e={}){return async(...t)=>W(()=>s(...t),e)}var k=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 G=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 Nt(s){let e=new G;return new k(e)}function Ut(s){let e=new G;return new k(e)}function Gt(s){let e=new G;return new k(e)}function ye(s,e){return new k(s)}function c(s){return s?.data}function Je(s,e){let[t,n]=be(s),[r,o]=be(e),i=t.split("."),a=r.split("."),p=Math.max(i.length,a.length);for(let g=0;g<p;g++){let y=Ce(i[g]??"0",a[g]??"0");if(y!==0)return y}if(n===void 0&&o===void 0)return 0;if(n===void 0)return 1;if(o===void 0)return-1;let u=n.split("."),m=o.split("."),d=Math.max(u.length,m.length);for(let g=0;g<d;g++){if(g>=u.length)return-1;if(g>=m.length)return 1;let y=Ce(u[g],m[g]);if(y!==0)return y}return 0}function be(s){let e=s.split("+",1)[0],t=e.indexOf("-");return t===-1?[e,void 0]:[e.slice(0,t),e.slice(t+1)]}function Ce(s,e){let t=/^\d+$/.test(s),n=/^\d+$/.test(e);if(t&&n){let r=Number(s)-Number(e);return r<0?-1:r>0?1:0}return t?-1:n?1:s<e?-1:s>e?1:0}async function Ke(s,e,t){return W(async()=>{let n=await fetch(s,{signal:AbortSignal.timeout(1e4)});if(!n.ok){let r=new Error(`registry ${e} fetch failed (${n.status}) for ${t}`);throw r.status=n.status,r}return n},{attempts:3})}var T=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 n=new URL("/api/v2/bundles",new URL(e).origin);n.searchParams.set("package",t);let o=await(await Ke(n.toString(),"versions",t)).json();return(Array.isArray(o)?o:[]).map(i=>i.appVersion).filter(i=>typeof i=="string").sort((i,a)=>Je(a,i))}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 n=t?`?service_name=${encodeURIComponent(t)}`:"";return c(await this.httpClient.get(`/admin-api/applications/${e}/abi${n}`))}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 n=t.toString(),r=n?`/admin-api/blobs?${n}`:"/admin-api/blobs",o=c(await this.httpClient.request(r,{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 n=new URLSearchParams({context_id:t.contextId});return`/admin-api/blobs/${e}?${n.toString()}`}async getBlob(e,t){return this.httpClient.get(this.blobPath(e,t),{parse:"arrayBuffer"})}async getBlobInfo(e,t){let{headers:n}=await this.httpClient.head(this.blobPath(e,t)),r=Number(n["content-length"]);return{blobId:n["x-blob-id"]??e,size:Number.isFinite(r)?r:0,hash:n["x-blob-hash"],mimeType:n["x-blob-mime-type"],source:n["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 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 n=c(await this.httpClient.post(`/admin-api/namespaces/${e}/join`,t,{timeoutMs:65e3}));return n&&n.namespaceId===void 0&&n.groupId!==void 0?{...n,namespaceId:n.groupId}:n}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 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 n=String(e).replace(/[\r\n\t\s]/g,"").slice(0,64);throw new Error(`Invalid listGroupMembers response for group ${n}: 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,n){await this.httpClient.put(`/admin-api/groups/${e}/members/${t}/role`,n)}async getMemberCapabilities(e,t){return c(await this.httpClient.get(`/admin-api/groups/${e}/members/${t}/capabilities`))}async setMemberCapabilities(e,t,n){await this.httpClient.put(`/admin-api/groups/${e}/members/${t}/capabilities`,n)}async setDefaultCapabilities(e,t){await this.httpClient.put(`/admin-api/groups/${e}/settings/default-capabilities`,t)}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 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,n){await this.httpClient.put(`/admin-api/groups/${e}/members/${t}/metadata`,n)}async getMemberMetadata(e,t){return(await this.httpClient.get(`/admin-api/groups/${e}/members/${t}/metadata`))?.data??null}async setContextMetadata(e,t,n){await this.httpClient.put(`/admin-api/groups/${e}/contexts/${t}/metadata`,n)}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 n=await this.httpClient.post(`/admin-api/groups/${e}/reparent`,t);return n?.data??n}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,n){await this.httpClient.put(`/admin-api/groups/${e}/members/${t}/auto-follow`,n)}async abortMigration(e){return this.httpClient.post(`/admin-api/groups/${e}/migration/abort`,{})}};function Bt(s){return new T(D(s))}function Jt(s){return new T(j(s))}function Kt(s){return new T(te(s))}function Re(s,e){return new T(s)}function ne(s){try{let e=s.indexOf("#");if(e===-1)return null;let t=s.substring(e+1),n=new URLSearchParams(t),r=n.get("access_token");return r?{accessToken:r,refreshToken:n.get("refresh_token")??"",applicationId:n.get("application_id")??"",contextId:n.get("context_id")??"",contextIdentity:n.get("context_identity")??"",nodeUrl:n.get("node_url")??""}:null}catch{return null}}function se(s,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)),`${s.replace(/\/+$/,"")}/auth/login?${t.toString()}`}var B=class extends Error{constructor(e,t,n,r){super(t),this.name="RpcError",this.code=e,this.data=n,this.type=r}};async function re(s,e,t){let n=await s.post("/jsonrpc",{jsonrpc:"2.0",id:1,method:e,params:t});if(n.error){let r=n.error;throw new B(r.code??-1,r.message??r.type??"RPC error",r.data,r.type)}return n.result}var H=class{constructor(e){this.httpClient=e.httpClient}async execute(e){let t=await re(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 Ve=new Set(["MigrationStarted","MigrationProgress","CascadeProgress","MigrationCompleted"]);function Ae(s){return s.type!==void 0&&Ve.has(s.type)}var Fe=new Set(["token_reuse","token_revoked"]),E=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}on(e,t){let n=e;if(n in this.listeners){let r=this.listeners[n];r.includes(t)||r.push(t)}}off(e,t){let n=e;if(n in this.listeners){let r=this.listeners[n],o=r.indexOf(t);o!==-1&&r.splice(o,1)}}onAppVersionChanged(e){let t=n=>{if(n.type!=="AppVersionChanged")return;let r=n.data;e({contextId:n.contextId,fromVersion:r?.fromVersion,toVersion:r?.toVersion})};return this.on("event",t),()=>this.off("event",t)}onMigrationEvent(e){let t=n=>{Ae(n)&&e(n)};return this.on("event",t),()=>this.off("event",t)}emit(e,t){let n=e;if(n in this.listeners)for(let r of this.listeners[n])try{r(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`,n=await fetch(t,{headers:{Authorization:`Bearer ${e}`,Accept:"text/event-stream"},signal:this.abortController.signal});if(!n.ok){let r=n.headers.get("x-auth-error"),o=await n.text().catch(()=>{});throw n.status===401&&r&&Fe.has(r)?new I(r,n.status,n.statusText,t,n.headers,o):new b(n.status,n.statusText,t,n.headers,o)}if(!n.body)throw new Error("SSE response has no body");this.readStream(n.body).catch(r=>{if(this.closed)return;let o=r instanceof Error?r:new Error(String(r));this.emit("error",o),this.scheduleReconnect()})}catch(e){if(this.closed)return;let t=e instanceof Error?e:new Error(String(e));this.emit("error",t),this.scheduleReconnect()}}}async readStream(e){let t=e.getReader(),n=new TextDecoder,r="";try{for(;;){let{done:o,value:i}=await t.read();if(o)break;r+=n.decode(i,{stream:!0});let a=r.split(`
|
|
2
|
-
`);r=a.pop()??"";for(let p of a)if(p.startsWith("data:")){let u=p.slice(5).trim();u&&this.handleMessage(u)}}if(r+=n.decode(),r.startsWith("data:")){let o=r.slice(5).trim();o&&this.handleMessage(o)}}catch(o){if(this.closed)return;let i=o instanceof Error?o:new Error(String(o));this.emit("error",i)}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 n=t.result.data;if(Array.isArray(n))try{let r=new Uint8Array(n),o=new TextDecoder().decode(r);n=JSON.parse(o)}catch{}if(t.result.contextId){this.emit("event",{contextId:t.result.contextId,type:t.result.type,data:n});return}t.result.groupId&&this.emit("event",{groupId:t.result.groupId,type:t.result.type,data:n})}catch{}}async subscribe(e){let t=Array.isArray(e)?{contextIds:e}:e,n=(t.contextIds??[]).filter(o=>!this.subscribedContextIds.has(o)),r=(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);(n.length>0||r.length>0)&&this.sessionId&&await this.sendSubscription("subscribe",{contextIds:n,groupIds:r})}async unsubscribe(e){let t=Array.isArray(e)?{contextIds:e}:e,n=(t.contextIds??[]).filter(o=>this.subscribedContextIds.has(o)),r=(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);(n.length>0||r.length>0)&&this.sessionId&&await this.sendSubscription("unsubscribe",{contextIds:n,groupIds:r})}async sendSubscription(e,t){try{let n=await this.getAuthToken(),r={};t.contextIds&&t.contextIds.length>0&&(r.contextIds=t.contextIds),t.groupIds&&t.groupIds.length>0&&(r.groupIds=t.groupIds);let o=await fetch(`${this.baseUrl}/sse/subscription`,{method:"POST",headers:{Authorization:`Bearer ${n}`,"Content-Type":"application/json"},body:JSON.stringify({id:this.sessionId,method:e,params:r})});o.ok||this.emit("error",new Error(`SSE ${e} failed: ${o.status}`))}catch(n){this.emit("error",n instanceof Error?n: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 J=class J{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 n=e;if(n in this.listeners){let r=this.listeners[n];r.includes(t)||r.push(t)}}off(e,t){let n=e;if(n in this.listeners){let r=this.listeners[n],o=r.indexOf(t);o!==-1&&r.splice(o,1)}}emit(e,t){let n=e;if(n in this.listeners)for(let r of this.listeners[n])try{r(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=n=>{this.handleMessage(n.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 n=t.result.data;if(Array.isArray(n))try{let r=new Uint8Array(n),o=new TextDecoder().decode(r);n=JSON.parse(o)}catch{}if(t.result.contextId){this.emit("event",{contextId:t.result.contextId,type:t.result.type,data:n});return}t.result.groupId&&this.emit("event",{groupId:t.result.groupId,type:t.result.type,data:n})}catch{}}subscribe(e){let t=Array.isArray(e)?{contextIds:e}:e;for(let n of t.contextIds??[])this.subscribedContextIds.add(n);for(let n of t.groupIds??[])this.subscribedGroupIds.add(n);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 n of t.contextIds??[])this.subscribedContextIds.delete(n);for(let n of t.groupIds??[])this.subscribedGroupIds.delete(n);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 n={};return e.length>0&&(n.contextIds=e),t.length>0&&(n.groupIds=t),n}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),J.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()}};J.MAX_BACKOFF_MS=3e4;var M=J;function K(){return{encode(s){return Array.from(new TextEncoder().encode(JSON.stringify(s)))},decode(s){return JSON.parse(new TextDecoder().decode(new Uint8Array(s)))}}}var $=class{constructor(e){this.httpClient=e.httpClient,this.sse=e.sse}async set(e,t,n=K()){await re(this.httpClient,"set_ephemeral",{contextId:e,state:n.encode(t)})}subscribe(e,t,n=K()){let r=o=>{let i=o;if(i.type!=="Ephemeral"||i.contextId!==e)return;let a=i.data;if(!a?.author)return;let p=!!a.removed,u={author:a.author,state:p||a.state===void 0?void 0:n.decode(a.state),removed:p};a.ageMs!==void 0&&(u.ageMs=a.ageMs),t(u)};return this.sse.on("event",r),this.sse.connect().catch(()=>{}),this.sse.subscribe([e]).catch(()=>{}),()=>{this.sse.off("event",r)}}};var ze="https://cloud.calimero.network",Xe="x-mdma-session-refresh",Qe="x-mdma-session-expires",P=class{constructor(e={}){this.session=null;this.baseUrl=(e.cloudBaseUrl||ze).replace(/\/+$/,""),this.onSession=e.onSession;let t=e.fetch;this.fetchImpl=t?(n,r)=>t(n,r):(n,r)=>globalThis.fetch(n,r),this.timeoutMs=e.timeoutMs??1e4,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 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(n=>({peerId:String(n.peer_id??""),relayUrl:n.relay_url??null,executorAccount:n.executor_account??null,status:String(n.status??""),authorshipReady:n.authorship_ready===!0,lastSeenAt:n.last_seen_at??null,confirmedAt:n.confirmed_at??null}))}async findExecutingRelay(e){return(await this.getNamespaceRelays(e)).find(n=>n.authorshipReady&&n.relayUrl!==null&&n.executorAccount!==null)??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(n=>{let r=n;return{namespaceId:String(r.namespace_id??""),status:String(r.status??""),authorshipReady:r.authorship_ready===!0,fresh:r.fresh===!0,confirmedAt:r.confirmed_at??null,lastSeenAt:r.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){return this.request("POST",`/api/cloud/namespaces/${encodeURIComponent(e)}/enable-ha`,{body:{}})}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()}`)}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,n={}){if(!n.anonymous&&!this.session)throw new Error("Not signed in to Calimero Cloud: call signInWithGoogle() or construct the client with a sessionToken");let r={Accept:"application/json"};n.body!==void 0&&(r["Content-Type"]="application/json"),!n.anonymous&&this.session&&(r.Authorization=`Bearer ${this.session.sessionToken}`);let o=new AbortController,i=setTimeout(()=>o.abort(),this.timeoutMs),a;try{a=await this.fetchImpl(`${this.baseUrl}${t}`,{method:e,headers:r,body:n.body===void 0?void 0:JSON.stringify(n.body),signal:o.signal})}catch(p){throw new b(0,p instanceof Error?p.name:"NetworkError",`${this.baseUrl}${t}`,new Headers,p instanceof Error?p.message:String(p))}finally{clearTimeout(i)}if(this.adoptRollingRefresh(a),!a.ok){let p=await a.text().catch(()=>{});throw new b(a.status,a.statusText,`${this.baseUrl}${t}`,a.headers,p)}if(!(n.parse==="none"||a.status===204))return await a.json()}adoptRollingRefresh(e){let t=e.headers.get(Xe);if(!t||!this.session)return;let n=e.headers.get(Qe),r=Number(n);this.session={sessionToken:t,expiresAt:Number.isFinite(r)&&r>0?r:this.session.expiresAt,user:this.session.user},this.notifySession(this.session)}};var Ye="mero-js:token-refresh";function Ze(){let e=globalThis.navigator?.locks;return e&&typeof e.request=="function"?e:null}function oe(s,e){try{let t=s.split(".");if(t.length===3){let n=t[1].replace(/-/g,"+").replace(/_/g,"/");for(;n.length%4;)n+="=";let r=JSON.parse(atob(n));if(typeof r.exp=="number")return r.exp*1e3}}catch{}return e}var V=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;this.httpClient=D({baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||"",refreshToken:async()=>(await this.performTokenRefresh()).access_token,onTokenRefresh:async n=>{this.tokenData&&(this.tokenData.access_token=n,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=ye(this.httpClient,{baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||"",timeoutMs:this.config.timeoutMs}),this.adminClient=Re(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 H({httpClient:this.httpClient})),this.rpcClient}get events(){return this.sseClient||(this.sseClient=new E({baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||""})),this.sseClient}get ephemeral(){return this.ephemeralClient||(this.ephemeralClient=new $({httpClient:this.httpClient,sse:this.events})),this.ephemeralClient}get cloud(){return this.cloudClient||(this.cloudClient=new P(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 M({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 n={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}},r=await this.authClient.generateTokens(n),o=r.data.access_token;return this.tokenData={access_token:o,refresh_token:r.data.refresh_token,expires_at:oe(o,Date.now()+36e5)},this.tokenStore?.setTokens(this.tokenData),this.tokenData}catch(n){throw new Error(`Authentication failed: ${n instanceof Error?n.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=Ze();return t?t.request(Ye,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 n=await this.authClient.refreshToken({access_token:this.tokenData.access_token,refresh_token:this.tokenData.refresh_token}),r=n.data.access_token;return this.tokenData={access_token:r,refresh_token:n.data.refresh_token,expires_at:oe(r,Date.now()+36e5)},this.tokenStore?.setTokens(this.tokenData),this.tokenData}catch(n){throw new Error(`Token refresh failed: ${n instanceof Error?n.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||oe(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 ne(e)}static buildAuthLoginUrl(e,t){return se(e,t)}};function et(s){return new V(s)}var ie=class{constructor(){this.tokens=null}getTokens(){return this.tokens}setTokens(e){this.tokens=e}clear(){this.tokens=null}},tt="mero-tokens",ae=class{constructor(e=tt){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 we=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,112,4,34,4,32]);function C(s){let e=new Uint8Array(4);return new DataView(e.buffer).setUint32(0,s,!0),e}function A(s){return Array.from(s,e=>e.toString(16).padStart(2,"0")).join("")}function h(s,e,t){let n=s.trim();if(!/^[0-9a-fA-F]*$/.test(n)||n.length!==t*2)throw new Error(`${e} must be ${t*2} hex characters, got ${n.length}`);let r=new Uint8Array(t);for(let o=0;o<t;o+=1)r[o]=Number.parseInt(n.slice(o*2,o*2+2),16);return r}function R(s){let e=new Uint8Array(8);return new DataView(e.buffer).setBigUint64(0,BigInt(s),!0),e}function f(...s){let e=new Uint8Array(s.reduce((n,r)=>n+r.length,0)),t=0;for(let n of s)e.set(n,t),t+=n.length;return e}async function v(s,e){let t=[R(s.length),s];for(let n of e)t.push(R(n.length),n);return new Uint8Array(await crypto.subtle.digest("SHA-256",f(...t)))}async function _(s){let e=h(s,"deviceSecret",32),t=f(we,e);try{return await crypto.subtle.importKey("pkcs8",t,{name:"Ed25519"},!1,["sign"])}catch(n){let r=n instanceof Error?`: ${n.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`"+r)}}async function w(s){let e=h(s,"deviceSecret",32),t=f(we,e),n=await crypto.subtle.importKey("pkcs8",t,{name:"Ed25519"},!0,["sign"]),o=(await crypto.subtle.exportKey("jwk",n)).x;return Uint8Array.from(atob(o.replace(/-/g,"+").replace(/_/g,"/")),i=>i.charCodeAt(0))}var nt=new TextEncoder().encode("calimero.warrant.v2"),st=new TextEncoder().encode("calimero.warrant.intent.v1"),xe=64,rt="00".repeat(32);async function ce(s,e){let t=new TextEncoder().encode(JSON.stringify(e));return v(st,[new TextEncoder().encode(s),t])}async function F(s){let e=h(s.context,"context",32),t=h(s.authorAccount,"authorAccount",32),n=h(s.executor,"executor",32),r=h(s.appVersion??rt,"appVersion",32),o=ve(s.accountHeads,"accountHeads"),i=ve(s.governanceFloor,"governanceFloor"),a=await _(s.deviceSecret),p=await w(s.deviceSecret),u=new TextEncoder().encode(s.method),m=await ce(s.method,s.argsJson),d=R(s.nonce),g=R(s.notAfter),y=await v(nt,[e,t,p,n,r,u,m,R(o.length),...o,R(i.length),...i,d,g]),l=new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},a,y));return A(f(e,t,p,n,r,C(u.length),u,m,C(o.length),...o,C(i.length),...i,d,g,l))}function ve(s,e){let t=s??[];if(t.length>xe)throw new Error(`${e} cites ${t.length} heads, over the ${xe} a node accepts`);return t.map((n,r)=>h(n,`${e}[${r}]`,32))}var ot=300,z=class extends Error{constructor(t,n,r){super(`relay refused the intent (HTTP ${r}): ${t}`);this.reason=t;this.retryable=n;this.status=r;this.name="IntentRefusedError"}},q=class{constructor(e){this.config=e,this.baseUrl=e.relayUrl.replace(/\/+$/,""),this.executorAccount=e.executorAccount;let t=e.fetch;this.fetchImpl=t?(n,r)=>t(n,r):(n,r)=>globalThis.fetch(n,r),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,n={}){let r=this.executorAccount??(await this.describe(e)).executorAccount,o=await this.config.nonces.next(),i=this.config.ttlSeconds??ot,a=await F({context:e,authorAccount:this.config.authorAccount,executor:r,method:t,argsJson:n,nonce:o,notAfter:BigInt(Math.floor(Date.now()/1e3))+BigInt(i),deviceSecret:this.config.deviceSecret}),p=await this.json("POST",`/admin-api/contexts/${encodeURIComponent(e)}/intents`,{method:t,argsJson:n,warrant:a,authorProof:this.config.authorProof});return{rootHash:p.data.rootHash,returns:p.data.returns??null}}async json(e,t,n){let r={Accept:"application/json"};n!==void 0&&(r["Content-Type"]="application/json");let o=new AbortController,i=setTimeout(()=>o.abort(),this.timeoutMs),a;try{a=await this.fetchImpl(`${this.baseUrl}${t}`,{method:e,headers:r,body:n===void 0?void 0:JSON.stringify(n),signal:o.signal})}catch(p){throw new b(0,p instanceof Error?p.name:"NetworkError",`${this.baseUrl}${t}`,new Headers,p instanceof Error?p.message:String(p))}finally{clearTimeout(i)}if(!a.ok){let p=await a.text().catch(()=>"");if(a.status===400||a.status===403){let u=it(p);throw new z(u,/nonce/i.test(u),a.status)}throw new b(a.status,a.statusText,`${this.baseUrl}${t}`,a.headers,p)}return await a.json()}};function it(s){if(!s)return"no reason given";try{let e=JSON.parse(s);for(let t of[e.error,e.message])if(typeof t=="string"&&t)return t}catch{}return s}function pe(s=1){let e=BigInt(s);if(e<1n)throw new Error("nonce sequence starts at 1");return{next(){let t=e;return e+=1n,Promise.resolve(t)}}}function ue(s,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 n=t.getItem(s),r=0n;if(n!==null&&n!=="")try{let i=BigInt(n);i>0n&&(r=i)}catch{r=0n}let o=r+1n;return t.setItem(s,o.toString()),Promise.resolve(o)}}}async function at(s){if(!s.sessionToken&&!s.googleIdToken)throw new Error("connectCloud needs either a sessionToken or a googleIdToken");let e=new P({cloudBaseUrl:s.cloudBaseUrl,sessionToken:s.sessionToken,onSession:s.onSession,fetch:s.fetch,timeoutMs:s.timeoutMs});!s.sessionToken&&s.googleIdToken&&await e.signInWithGoogle(s.googleIdToken);let t=await e.getMyNamespaces(),n=ct(t,s.namespaceId),r=await e.getNamespaceRelays(n.namespaceId),o=r.find(a=>a.authorshipReady&&a.relayUrl!==null&&a.executorAccount!==null)??null;if(!o)throw new Error(pt(n,r));let i=new q({relayUrl:o.relayUrl,executorAccount:o.executorAccount,authorAccount:s.authorAccount,authorProof:s.authorProof,deviceSecret:s.deviceSecret,nonces:s.nonces??await ut(s.deviceSecret),ttlSeconds:s.ttlSeconds,fetch:s.fetch,timeoutMs:s.timeoutMs});return{cloud:e,relay:i,namespaceId:n.namespaceId,namespace:n,relayInfo:o,execute:(a,p,u)=>i.execute(a,p,u)}}function ct(s,e){if(e){let t=s.find(n=>n.namespaceId===e);if(!t)throw new Error(`this account owns no namespace ${e}; it owns: ${s.map(n=>n.namespaceId).join(", ")||"(none)"}`);return t}if(s.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(s.length>1)throw new Error(`this account owns ${s.length} namespaces \u2014 pass namespaceId to say which: ${s.map(t=>t.namespaceId).join(", ")}`);return s[0]}function pt(s,e){if(e.length===0)return s.haStatus==="enabled"?`namespace ${s.namespaceId} has HA enabled but no relay has been assigned to it yet \u2014 retry shortly`:`namespace ${s.namespaceId} has no relays: enable HA on it in the cloud to have an attested node assigned`;let t=e.filter(n=>!n.authorshipReady);return t.length===e.length?`every relay on namespace ${s.namespaceId} is waiting for the authorship grant: an admin of the namespace must grant CAN_AUTHOR_ON_BEHALF to ${t.map(n=>n.executorAccount??n.peerId).join(", ")||"the relay account"}`:`namespace ${s.namespaceId} has ${e.length} relay(s), but none reported both a URL and an executor account yet \u2014 retry shortly`}async function ut(s){let e=`mero-js:warrant-nonce:${A(await w(s))}`;try{return ue(e)}catch{return pe(1)}}var lt=new TextEncoder().encode("calimero.device.cert.v1"),ke=new TextEncoder().encode("calimero.account.genesis.v1"),dt=new TextEncoder().encode("calimero.device.id.v1"),le=2;async function Te(s,e){if(e.length!==16)throw new Error(`nonce must be 16 bytes, got ${e.length}`);let t=h(s,"account",32);return A(await v(dt,[t,e]))}async function de(s){return v(lt,[h(s.account,"account",32),h(s.device,"device",32),h(s.signPublicKey,"signPublicKey",32),h(s.kemPublicKey,"kemPublicKey",32),C(s.keyEpoch),C(s.deviceEpoch)])}function Pe(s){return f(new Uint8Array([le]),s.rootPublicKey,C(0),h(s.account,"account",32),h(s.device,"device",32),h(s.signPublicKey,"signPublicKey",32),h(s.kemPublicKey,"kemPublicKey",32),C(s.keyEpoch),C(s.deviceEpoch),s.signature)}async function Se(s){let e=await w(s.rootSecret),t=A(await v(ke,[f(new Uint8Array([le]),e)])),n=0,r=await de({account:t,device:s.device,signPublicKey:s.signPublicKey,kemPublicKey:s.kemPublicKey,keyEpoch:n,deviceEpoch:s.deviceEpoch}),o=await _(s.rootSecret),i=new Uint8Array(await crypto.subtle.sign("Ed25519",o,r)),a=Pe({rootPublicKey:e,account:t,device:s.device,signPublicKey:s.signPublicKey,kemPublicKey:s.kemPublicKey,keyEpoch:n,deviceEpoch:s.deviceEpoch,signature:i});return A(a)}async function Ie(s){let e=await w(s);return A(await v(ke,[f(new Uint8Array([le]),e)]))}var me=8,ht=new TextEncoder().encode("calimero.namespace.v1"),mt=0,De={GroupCreated:0,GroupReparented:1,GroupDeleted:2,AdminChanged:3,PolicyUpdated:4,MemberJoined:5,KeyDelivery:6,MemberJoinedOpen:7,MemberJoinedAt:8,NamespaceCreated:9,MemberJoinedViaTeeAttestation:10};function he(s,e){if(s.length!==32)throw new Error(`${e} must be 32 bytes, got ${s.length}`);return new Uint8Array(s)}function Ee(s,e){if(s==null)return new Uint8Array([0]);if(s.length!==32)throw new Error(`${e} must be 32 bytes, got ${s.length}`);return f(new Uint8Array([1]),new Uint8Array(s))}function Me(s){let e=new TextEncoder().encode(s);return f(C(e.length),e)}function X(s){let e=s.invitation,t=e.admitters??[],n=s.admitter_addrs??[];return f(he(e.inviter_identity,"inviter_identity"),he(e.group_id,"group_id"),R(e.expiration_timestamp),he(e.secret_salt,"secret_salt"),new Uint8Array([e.invited_role]),C(t.length),...t.map((r,o)=>h(r,`admitters[${o}]`,32)),Me(s.inviter_signature),s.inviter_account?f(new Uint8Array([1]),h(s.inviter_account,"inviter_account",32)):new Uint8Array([0]),C(n.length),...n.map(Me),Ee(s.application_id,"application_id"),Ee(s.app_key,"app_key"))}async function _e(s){let e=s.parentOpHashes??[],t=h(s.credential,"credential",s.credential.length/2),n=BigInt(s.invitation.invitation.expiration_timestamp??0)!==0n,r=s.joinedAt??BigInt(Math.floor(Date.now()/1e3)),o=n?f(new Uint8Array([De.MemberJoinedAt]),h(s.member,"member",32),X(s.invitation),R(r),t):f(new Uint8Array([De.MemberJoined]),h(s.member,"member",32),X(s.invitation),t),i=f(new Uint8Array([mt]),o),a=await _(s.deviceSecret),p=await w(s.deviceSecret),u=f(new Uint8Array([me]),h(s.namespaceId,"namespaceId",32),C(e.length),...e.map((g,y)=>h(g,`parentOpHashes[${y}]`,32)),p,R(s.nonce),i),m=new Uint8Array(await crypto.subtle.sign("Ed25519",a,f(ht,u))),d=new Uint8Array([0]);return A(f(u,m,d))}var Xn={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 Qn(s,e){let t=e>>>0;return(s&t)>>>0===t}function Yn(s,e){return(s|e)>>>0}function Zn(s,e){return(s&~e)>>>0}var Ne=[2428,2429,2528,2529],gt="localhost",ft=2e3;function Ue(s){return`http://${gt}:${s}`}function Ge(s,e){let t=s.endsWith("/")?s:`${s}/`;return new URL(e,t).toString()}async function He(s,e={}){let{timeoutMs:t=ft,signal:n}=e;if(n?.aborted)return!1;let r=new AbortController,o=()=>r.abort(),i=n;i&&i.addEventListener("abort",o,{once:!0});let a=setTimeout(()=>r.abort(),t);try{let p=Ge(s,"admin-api/health"),u=await fetch(p,{method:"GET",signal:r.signal});if(!u.ok)return!1;try{let m=await u.json(),d=m?.data?.status!==void 0?m?.data?.status:m?.status;return d===void 0?!0:typeof d=="string"&&d.toLowerCase()==="alive"}catch{return!0}}catch{return!1}finally{clearTimeout(a),i&&i.removeEventListener("abort",o)}}async function yt(s={}){let{ports:e=Ne,timeoutMs:t,signal:n}=s;return(await Promise.all(e.map(async o=>{let i=Ue(o);return await He(i,{timeoutMs:t,signal:n})?i:null}))).filter(o=>o!==null)}export{T as AdminApiClient,k as AuthApiClient,I as AuthRevokedError,Xn as CAPABILITIES,P as CloudClient,Ne as DEFAULT_LOCAL_NODE_PORTS,$ as EphemeralClient,b as HTTPError,z as IntentRefusedError,ae as LocalStorageTokenStore,ie as MemoryTokenStore,V as MeroJs,q as RelayClient,H as RpcClient,B as RpcError,me as SIGNED_NAMESPACE_OP_SCHEMA_VERSION,E as SseClient,U as WebHttpClient,M as WsClient,Ie as accountForRoot,se as buildAuthLoginUrl,Y as combineSignals,Je as compareSemver,at as connectCloud,Kt as createAdminApiClient,Re as createAdminApiClientFromHttpClient,Gt as createAuthApiClient,ye as createAuthApiClientFromHttpClient,Bt as createBrowserAdminApiClient,Nt as createBrowserAuthApiClient,D as createBrowserHttpClient,ee as createHttpClient,ue as createLocalStorageNonceSource,pe as createMemoryNonceSource,et as createMeroJs,Jt as createNodeAdminApiClient,Ut as createNodeAuthApiClient,j as createNodeHttpClient,Be as createRetryableMethod,Z as createTimeoutSignal,te as createUniversalHttpClient,de as deviceCertPayload,yt as discoverLocalNodes,X as encodeSignedInvitation,Qn as hasCap,ce as intentHash,K as jsonCodec,Ue as localNodeUrl,Te as mintDeviceId,Ge as nodeEndpoint,ne as parseAuthCallback,He as probeNodeHealth,Se as signDeviceCert,_e as signMemberJoinOp,F as signWarrant,Yn as withCap,W as withRetry,Zn as withoutCap};
|
|
1
|
+
function Y(s){let e=s.filter(Boolean);if(e.length===0)return;let t=AbortSignal;if(typeof t.any=="function")try{return t.any(e)}catch{}let n=new AbortController,r=o=>{n.abort(o.target.reason);for(let i of e)i.removeEventListener("abort",r)};for(let o of e){if(o.aborted)return AbortSignal.abort(o.reason);o.addEventListener("abort",r,{once:!0})}return n.signal}function Z(s){if(typeof AbortSignal.timeout=="function")return AbortSignal.timeout(s);let e=new AbortController;return setTimeout(()=>{e.abort(new DOMException("Timeout","TimeoutError"))},s),e.signal}var We=new Set(["token_reuse","token_revoked"]);function Ke(s){if(s)try{let e=JSON.parse(s)?.error;if(typeof e=="string"&&e.trim()!=="")return e;let t=e?.message;if(typeof t=="string"&&t.trim()!=="")return t}catch{}}var C=class extends Error{constructor(t,n,r,o,i){let a=Ke(i);super(a?`HTTP ${t} ${n}: ${a}`:`HTTP ${t} ${n}`);this.status=t;this.statusText=n;this.url=r;this.headers=o;this.bodyText=i;this.name="HTTPError"}toJSON(){return{status:this.status,statusText:this.statusText,url:this.url,headers:fe(this.headers),bodyText:this.bodyText}}},D=class extends C{constructor(t,n,r,o,i,a){super(n,r,o,i,a);this.reason=t;this.name="AuthRevokedError";this.message=`Authentication revoked (${t}): HTTP ${n} ${r}`}};function fe(s){let e={};return s.forEach((t,n)=>{e[n]=t}),e}var N=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,n){return this.request(e,{...n,method:"POST",body:t?JSON.stringify(t):void 0,headers:{"Content-Type":"application/json",...n?.headers}})}async put(e,t,n){return this.request(e,{...n,method:"PUT",body:t?JSON.stringify(t):void 0,headers:{"Content-Type":"application/json",...n?.headers}})}async delete(e,t){return this.request(e,{...t,method:"DELETE"})}async patch(e,t,n){return this.request(e,{...n,method:"PATCH",body:t?JSON.stringify(t):void 0,headers:{"Content-Type":"application/json",...n?.headers}})}async head(e,t){let n=await this.makeRequest(e,{...t,method:"HEAD",parse:"response"});return{headers:fe(n.headers),status:n.status}}async request(e,t){return this.makeRequest(e,t)}async makeRequest(e,t,n=0,r){let i=this.buildUrl(e),a=r??Date.now(),p=this.createAbortSignal(t),u=await this.buildHeaders(t?.headers),g;u instanceof Headers?(g={},u.forEach((d,I)=>{g[I]=d})):g=u;let h={method:t?.method||"GET",headers:g},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&&n===0)&&(h.body=t.body);let b;if(n>0&&r!==void 0){let d=t?.timeoutMs||this.transport.timeoutMs;if(d){let I=Date.now()-a,U=Math.max(0,d-I);b=this.createAbortSignal({...t,timeoutMs:U})}else b=this.createAbortSignal(t)}else b=p;b&&(h.signal=b),this.transport.credentials!==void 0&&(h.credentials=this.transport.credentials),t?.mode!==void 0&&(h.mode=t.mode),t?.cache!==void 0&&(h.cache=t.cache),t?.redirect!==void 0&&(h.redirect=t.redirect),t?.referrer!==void 0&&(h.referrer=t.referrer),t?.referrerPolicy!==void 0&&(h.referrerPolicy=t.referrerPolicy),t?.integrity!==void 0&&(h.integrity=t.integrity),t?.keepalive!==void 0&&(h.keepalive=t.keepalive);try{let d=await this.transport.fetch(i,h);if(!d.ok){let I=await this.getBodyText(d),U=new C(d.status,d.statusText,i,d.headers,I),O=d.headers.get("x-auth-error");if((d.status===401||d.status===403)&&O&&We.has(O)){if(this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,this.transport.onAuthRevoked)try{await this.transport.onAuthRevoked()}catch{}throw new D(O,d.status,d.statusText,i,d.headers,I)}let Le=t?.signal?.aborted===!0;if(d.status===401&&this.transport.refreshToken&&O==="token_expired"&&n<1&&!f&&!Le)try{let v=this.refreshTokenPromise;v||(v=this.transport.refreshToken(),this.refreshTokenPromise=v);let Q=await v;if(!Q||Q.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 L=this.onTokenRefreshPromise;L||(L=this.transport.onTokenRefresh(Q),this.onTokenRefreshPromise=L),await L,this.refreshTokenPromise=null,this.onTokenRefreshPromise=null;let ge=t?.timeoutMs||this.transport.timeoutMs;if(ge&&r!==void 0){let je=Date.now()-a;if(ge-je<=0)throw U}return this.makeRequest(e,t,n+1,a)}catch(v){throw this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,v instanceof Error&&v.message.includes("onTokenRefresh")?v:U}throw U}return this.parseResponse(d,t?.parse)}catch(d){throw d instanceof C||d instanceof Error&&d.message.includes("onTokenRefresh")?d:new C(0,"Network Error",i,new Headers,d instanceof Error?d.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 n=e?.timeoutMs||this.transport.timeoutMs;return n&&t.push(Z(n)),t.length>0?Y(t):void 0}async buildHeaders(e){let t={...this.transport.defaultHeaders};if(this.transport.getAuthToken)try{let n=await this.transport.getAuthToken();n&&n.trim()!==""&&(t.Authorization=`Bearer ${n}`)}catch{}return e&&(e instanceof Headers?e.forEach((n,r)=>{t[r]=n}):Array.isArray(e)?e.forEach(([n,r])=>{t[n]=r}):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 n=await e.text();if(!n)return null;try{return JSON.parse(n)}catch{throw new Error(`Expected a JSON response (status ${e.status}) but body was not JSON: ${n.slice(0,200)}`)}}}}async getBodyText(e){try{let t=await e.text();return t.length>65536?t.slice(0,65536)+"...":t}catch{return""}}};function ee(s){return new N(s)}function E(s){let e={fetch:(t,n)=>globalThis.fetch(t,n),baseUrl:s.baseUrl,getAuthToken:s.getAuthToken,onTokenRefresh:s.onTokenRefresh,refreshToken:s.refreshToken,onAuthRevoked:s.onAuthRevoked,defaultHeaders:s.defaultHeaders,timeoutMs:s.timeoutMs,credentials:s.credentials,defaultAbortSignal:s.defaultAbortSignal};return ee(e)}function j(s){let e=s.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 n={fetch:e===globalThis.fetch?(r,o)=>globalThis.fetch(r,o):(r,o)=>e(r,o),baseUrl:s.baseUrl,getAuthToken:s.getAuthToken,onTokenRefresh:s.onTokenRefresh,refreshToken:s.refreshToken,onAuthRevoked:s.onAuthRevoked,defaultHeaders:s.defaultHeaders,timeoutMs:s.timeoutMs,credentials:s.credentials,defaultAbortSignal:s.defaultAbortSignal};return ee(n)}function te(s){return typeof window<"u"?E(s):j(s)}function Be(s,e){if(e<=0)return!1;let n=s?.name;if(n==="TimeoutError")return!0;if(n==="AbortError")return!1;let r=s;if("status"in r&&typeof r.status=="number"){let o=r.status;return o>=500||o===429}return n==="TypeError"}function Je(s){let t=250*Math.pow(2,s-1),n=(Math.random()-.5)*.4*t;return Math.max(0,t+n)}async function W(s,e={}){let{attempts:t=3}=e,n;for(let r=1;r<=t;r++)try{return await s(r)}catch(o){if(n=o,!Be(n,t-r))throw n;let i=Je(r),u=n.headers?.get?.("Retry-After");if(u){let g=parseInt(u,10);if(!isNaN(g))i=Math.max(i,g*1e3);else{let h=new Date(u);if(!isNaN(h.getTime())){let f=Math.max(0,h.getTime()-Date.now());i=Math.max(i,Math.min(f,6e4))}}}await new Promise(g=>setTimeout(g,i))}throw n||new Error("Retry failed without error")}function Ve(s,e={}){return async(...t)=>W(()=>s(...t),e)}var T=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 G=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 Ot(s){let e=new G;return new T(e)}function Lt(s){let e=new G;return new T(e)}function jt(s){let e=new G;return new T(e)}function ye(s,e){return new T(s)}function c(s){return s?.data}function Fe(s,e){let[t,n]=be(s),[r,o]=be(e),i=t.split("."),a=r.split("."),p=Math.max(i.length,a.length);for(let f=0;f<p;f++){let b=Ce(i[f]??"0",a[f]??"0");if(b!==0)return b}if(n===void 0&&o===void 0)return 0;if(n===void 0)return 1;if(o===void 0)return-1;let u=n.split("."),g=o.split("."),h=Math.max(u.length,g.length);for(let f=0;f<h;f++){if(f>=u.length)return-1;if(f>=g.length)return 1;let b=Ce(u[f],g[f]);if(b!==0)return b}return 0}function be(s){let e=s.split("+",1)[0],t=e.indexOf("-");return t===-1?[e,void 0]:[e.slice(0,t),e.slice(t+1)]}function Ce(s,e){let t=/^\d+$/.test(s),n=/^\d+$/.test(e);if(t&&n){let r=Number(s)-Number(e);return r<0?-1:r>0?1:0}return t?-1:n?1:s<e?-1:s>e?1:0}async function ze(s,e,t){return W(async()=>{let n=await fetch(s,{signal:AbortSignal.timeout(1e4)});if(!n.ok){let r=new Error(`registry ${e} fetch failed (${n.status}) for ${t}`);throw r.status=n.status,r}return n},{attempts:3})}var P=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 n=new URL("/api/v2/bundles",new URL(e).origin);n.searchParams.set("package",t);let o=await(await ze(n.toString(),"versions",t)).json();return(Array.isArray(o)?o:[]).map(i=>i.appVersion).filter(i=>typeof i=="string").sort((i,a)=>Fe(a,i))}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 n=t?`?service_name=${encodeURIComponent(t)}`:"";return c(await this.httpClient.get(`/admin-api/applications/${e}/abi${n}`))}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 n=t.toString(),r=n?`/admin-api/blobs?${n}`:"/admin-api/blobs",o=c(await this.httpClient.request(r,{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 n=new URLSearchParams({context_id:t.contextId});return`/admin-api/blobs/${e}?${n.toString()}`}async getBlob(e,t){return this.httpClient.get(this.blobPath(e,t),{parse:"arrayBuffer"})}async getBlobInfo(e,t){let{headers:n}=await this.httpClient.head(this.blobPath(e,t)),r=Number(n["content-length"]);return{blobId:n["x-blob-id"]??e,size:Number.isFinite(r)?r:0,hash:n["x-blob-hash"],mimeType:n["x-blob-mime-type"],source:n["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 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 n=c(await this.httpClient.post(`/admin-api/namespaces/${e}/join`,t,{timeoutMs:65e3}));return n&&n.namespaceId===void 0&&n.groupId!==void 0?{...n,namespaceId:n.groupId}:n}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 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 n=String(e).replace(/[\r\n\t\s]/g,"").slice(0,64);throw new Error(`Invalid listGroupMembers response for group ${n}: 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,n){await this.httpClient.put(`/admin-api/groups/${e}/members/${t}/role`,n)}async getMemberCapabilities(e,t){return c(await this.httpClient.get(`/admin-api/groups/${e}/members/${t}/capabilities`))}async setMemberCapabilities(e,t,n){await this.httpClient.put(`/admin-api/groups/${e}/members/${t}/capabilities`,n)}async setDefaultCapabilities(e,t){await this.httpClient.put(`/admin-api/groups/${e}/settings/default-capabilities`,t)}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 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,n){await this.httpClient.put(`/admin-api/groups/${e}/members/${t}/metadata`,n)}async getMemberMetadata(e,t){return(await this.httpClient.get(`/admin-api/groups/${e}/members/${t}/metadata`))?.data??null}async setContextMetadata(e,t,n){await this.httpClient.put(`/admin-api/groups/${e}/contexts/${t}/metadata`,n)}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 n=await this.httpClient.post(`/admin-api/groups/${e}/reparent`,t);return n?.data??n}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,n){await this.httpClient.put(`/admin-api/groups/${e}/members/${t}/auto-follow`,n)}async abortMigration(e){return this.httpClient.post(`/admin-api/groups/${e}/migration/abort`,{})}};function Xt(s){return new P(E(s))}function Qt(s){return new P(j(s))}function Yt(s){return new P(te(s))}function Re(s,e){return new P(s)}function ne(s){try{let e=s.indexOf("#");if(e===-1)return null;let t=s.substring(e+1),n=new URLSearchParams(t),r=n.get("access_token");return r?{accessToken:r,refreshToken:n.get("refresh_token")??"",applicationId:n.get("application_id")??"",contextId:n.get("context_id")??"",contextIdentity:n.get("context_identity")??"",nodeUrl:n.get("node_url")??""}:null}catch{return null}}function se(s,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)),`${s.replace(/\/+$/,"")}/auth/login?${t.toString()}`}var K=class extends Error{constructor(e,t,n,r){super(t),this.name="RpcError",this.code=e,this.data=n,this.type=r}};async function re(s,e,t){let n=await s.post("/jsonrpc",{jsonrpc:"2.0",id:1,method:e,params:t});if(n.error){let r=n.error;throw new K(r.code??-1,r.message??r.type??"RPC error",r.data,r.type)}return n.result}var H=class{constructor(e){this.httpClient=e.httpClient}async execute(e){let t=await re(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 Xe=new Set(["MigrationStarted","MigrationProgress","CascadeProgress","MigrationCompleted"]);function Ae(s){return s.type!==void 0&&Xe.has(s.type)}var Qe=new Set(["token_reuse","token_revoked"]),M=class{constructor(e){this.sessionId=null;this.abortController=null;this.reconnectTimer=null;this.subscribedContextIds=new Set;this.subscribedGroupIds=new Set;this.closed=!1;this.listeners={connect:[],event:[],error:[]};this.baseUrl=e.baseUrl.replace(/\/+$/,""),this.getAuthToken=e.getAuthToken,this.reconnectDelayMs=e.reconnectDelayMs??3e3}on(e,t){let n=e;if(n in this.listeners){let r=this.listeners[n];r.includes(t)||r.push(t)}}off(e,t){let n=e;if(n in this.listeners){let r=this.listeners[n],o=r.indexOf(t);o!==-1&&r.splice(o,1)}}onAppVersionChanged(e){let t=n=>{if(n.type!=="AppVersionChanged")return;let r=n.data;e({contextId:n.contextId,fromVersion:r?.fromVersion,toVersion:r?.toVersion})};return this.on("event",t),()=>this.off("event",t)}onMigrationEvent(e){let t=n=>{Ae(n)&&e(n)};return this.on("event",t),()=>this.off("event",t)}emit(e,t){let n=e;if(n in this.listeners)for(let r of this.listeners[n])try{r(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`,n=await fetch(t,{headers:{Authorization:`Bearer ${e}`,Accept:"text/event-stream"},signal:this.abortController.signal});if(!n.ok){let r=n.headers.get("x-auth-error"),o=await n.text().catch(()=>{});throw n.status===401&&r&&Qe.has(r)?new D(r,n.status,n.statusText,t,n.headers,o):new C(n.status,n.statusText,t,n.headers,o)}if(!n.body)throw new Error("SSE response has no body");this.readStream(n.body).catch(r=>{if(this.closed)return;let o=r instanceof Error?r:new Error(String(r));this.emit("error",o),this.scheduleReconnect()})}catch(e){if(this.closed)return;let t=e instanceof Error?e:new Error(String(e));this.emit("error",t),this.scheduleReconnect()}}}async readStream(e){let t=e.getReader(),n=new TextDecoder,r="";try{for(;;){let{done:o,value:i}=await t.read();if(o)break;r+=n.decode(i,{stream:!0});let a=r.split(`
|
|
2
|
+
`);r=a.pop()??"";for(let p of a)if(p.startsWith("data:")){let u=p.slice(5).trim();u&&this.handleMessage(u)}}if(r+=n.decode(),r.startsWith("data:")){let o=r.slice(5).trim();o&&this.handleMessage(o)}}catch(o){if(this.closed)return;let i=o instanceof Error?o:new Error(String(o));this.emit("error",i)}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 n=t.result.data;if(Array.isArray(n))try{let r=new Uint8Array(n),o=new TextDecoder().decode(r);n=JSON.parse(o)}catch{}if(t.result.contextId){this.emit("event",{contextId:t.result.contextId,type:t.result.type,data:n});return}t.result.groupId&&this.emit("event",{groupId:t.result.groupId,type:t.result.type,data:n})}catch{}}async subscribe(e){let t=Array.isArray(e)?{contextIds:e}:e,n=(t.contextIds??[]).filter(o=>!this.subscribedContextIds.has(o)),r=(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);(n.length>0||r.length>0)&&this.sessionId&&await this.sendSubscription("subscribe",{contextIds:n,groupIds:r})}async unsubscribe(e){let t=Array.isArray(e)?{contextIds:e}:e,n=(t.contextIds??[]).filter(o=>this.subscribedContextIds.has(o)),r=(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);(n.length>0||r.length>0)&&this.sessionId&&await this.sendSubscription("unsubscribe",{contextIds:n,groupIds:r})}async sendSubscription(e,t){try{let n=await this.getAuthToken(),r={};t.contextIds&&t.contextIds.length>0&&(r.contextIds=t.contextIds),t.groupIds&&t.groupIds.length>0&&(r.groupIds=t.groupIds);let o=await fetch(`${this.baseUrl}/sse/subscription`,{method:"POST",headers:{Authorization:`Bearer ${n}`,"Content-Type":"application/json"},body:JSON.stringify({id:this.sessionId,method:e,params:r})});o.ok||this.emit("error",new Error(`SSE ${e} failed: ${o.status}`))}catch(n){this.emit("error",n instanceof Error?n: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 B=class B{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 n=e;if(n in this.listeners){let r=this.listeners[n];r.includes(t)||r.push(t)}}off(e,t){let n=e;if(n in this.listeners){let r=this.listeners[n],o=r.indexOf(t);o!==-1&&r.splice(o,1)}}emit(e,t){let n=e;if(n in this.listeners)for(let r of this.listeners[n])try{r(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=n=>{this.handleMessage(n.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 n=t.result.data;if(Array.isArray(n))try{let r=new Uint8Array(n),o=new TextDecoder().decode(r);n=JSON.parse(o)}catch{}if(t.result.contextId){this.emit("event",{contextId:t.result.contextId,type:t.result.type,data:n});return}t.result.groupId&&this.emit("event",{groupId:t.result.groupId,type:t.result.type,data:n})}catch{}}subscribe(e){let t=Array.isArray(e)?{contextIds:e}:e;for(let n of t.contextIds??[])this.subscribedContextIds.add(n);for(let n of t.groupIds??[])this.subscribedGroupIds.add(n);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 n of t.contextIds??[])this.subscribedContextIds.delete(n);for(let n of t.groupIds??[])this.subscribedGroupIds.delete(n);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 n={};return e.length>0&&(n.contextIds=e),t.length>0&&(n.groupIds=t),n}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),B.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()}};B.MAX_BACKOFF_MS=3e4;var _=B;function J(){return{encode(s){return Array.from(new TextEncoder().encode(JSON.stringify(s)))},decode(s){return JSON.parse(new TextDecoder().decode(new Uint8Array(s)))}}}var $=class{constructor(e){this.httpClient=e.httpClient,this.sse=e.sse}async set(e,t,n=J()){await re(this.httpClient,"set_ephemeral",{contextId:e,state:n.encode(t)})}subscribe(e,t,n=J()){let r=o=>{let i=o;if(i.type!=="Ephemeral"||i.contextId!==e)return;let a=i.data;if(!a?.author)return;let p=!!a.removed,u={author:a.author,state:p||a.state===void 0?void 0:n.decode(a.state),removed:p};a.ageMs!==void 0&&(u.ageMs=a.ageMs),t(u)};return this.sse.on("event",r),this.sse.connect().catch(()=>{}),this.sse.subscribe([e]).catch(()=>{}),()=>{this.sse.off("event",r)}}};var Ye="https://cloud.calimero.network",Ze="x-mdma-session-refresh",et="x-mdma-session-expires",S=class{constructor(e={}){this.session=null;this.baseUrl=(e.cloudBaseUrl||Ye).replace(/\/+$/,""),this.onSession=e.onSession;let t=e.fetch;this.fetchImpl=t?(n,r)=>t(n,r):(n,r)=>globalThis.fetch(n,r),this.timeoutMs=e.timeoutMs??1e4,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 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(n=>({peerId:String(n.peer_id??""),relayUrl:n.relay_url??null,executorAccount:n.executor_account??null,status:String(n.status??""),authorshipReady:n.authorship_ready===!0,lastSeenAt:n.last_seen_at??null,confirmedAt:n.confirmed_at??null}))}async findExecutingRelay(e){return(await this.getNamespaceRelays(e)).find(n=>n.authorshipReady&&n.relayUrl!==null&&n.executorAccount!==null)??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(n=>{let r=n;return{namespaceId:String(r.namespace_id??""),status:String(r.status??""),authorshipReady:r.authorship_ready===!0,fresh:r.fresh===!0,confirmedAt:r.confirmed_at??null,lastSeenAt:r.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){return this.request("POST",`/api/cloud/namespaces/${encodeURIComponent(e)}/enable-ha`,{body:{}})}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()}`)}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,n={}){if(!n.anonymous&&!this.session)throw new Error("Not signed in to Calimero Cloud: call signInWithGoogle() or construct the client with a sessionToken");let r={Accept:"application/json"};n.body!==void 0&&(r["Content-Type"]="application/json"),!n.anonymous&&this.session&&(r.Authorization=`Bearer ${this.session.sessionToken}`);let o=new AbortController,i=setTimeout(()=>o.abort(),this.timeoutMs),a;try{a=await this.fetchImpl(`${this.baseUrl}${t}`,{method:e,headers:r,body:n.body===void 0?void 0:JSON.stringify(n.body),signal:o.signal})}catch(p){throw new C(0,p instanceof Error?p.name:"NetworkError",`${this.baseUrl}${t}`,new Headers,p instanceof Error?p.message:String(p))}finally{clearTimeout(i)}if(this.adoptRollingRefresh(a),!a.ok){let p=await a.text().catch(()=>{});throw new C(a.status,a.statusText,`${this.baseUrl}${t}`,a.headers,p)}if(!(n.parse==="none"||a.status===204))return await a.json()}adoptRollingRefresh(e){let t=e.headers.get(Ze);if(!t||!this.session)return;let n=e.headers.get(et),r=Number(n);this.session={sessionToken:t,expiresAt:Number.isFinite(r)&&r>0?r:this.session.expiresAt,user:this.session.user},this.notifySession(this.session)}};var tt="mero-js:token-refresh";function nt(){let e=globalThis.navigator?.locks;return e&&typeof e.request=="function"?e:null}function oe(s,e){try{let t=s.split(".");if(t.length===3){let n=t[1].replace(/-/g,"+").replace(/_/g,"/");for(;n.length%4;)n+="=";let r=JSON.parse(atob(n));if(typeof r.exp=="number")return r.exp*1e3}}catch{}return e}var V=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;this.httpClient=E({baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||"",refreshToken:async()=>(await this.performTokenRefresh()).access_token,onTokenRefresh:async n=>{this.tokenData&&(this.tokenData.access_token=n,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=ye(this.httpClient,{baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||"",timeoutMs:this.config.timeoutMs}),this.adminClient=Re(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 H({httpClient:this.httpClient})),this.rpcClient}get events(){return this.sseClient||(this.sseClient=new M({baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||""})),this.sseClient}get ephemeral(){return this.ephemeralClient||(this.ephemeralClient=new $({httpClient:this.httpClient,sse:this.events})),this.ephemeralClient}get cloud(){return this.cloudClient||(this.cloudClient=new S(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 _({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 n={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}},r=await this.authClient.generateTokens(n),o=r.data.access_token;return this.tokenData={access_token:o,refresh_token:r.data.refresh_token,expires_at:oe(o,Date.now()+36e5)},this.tokenStore?.setTokens(this.tokenData),this.tokenData}catch(n){throw new Error(`Authentication failed: ${n instanceof Error?n.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=nt();return t?t.request(tt,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 n=await this.authClient.refreshToken({access_token:this.tokenData.access_token,refresh_token:this.tokenData.refresh_token}),r=n.data.access_token;return this.tokenData={access_token:r,refresh_token:n.data.refresh_token,expires_at:oe(r,Date.now()+36e5)},this.tokenStore?.setTokens(this.tokenData),this.tokenData}catch(n){throw new Error(`Token refresh failed: ${n instanceof Error?n.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||oe(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 ne(e)}static buildAuthLoginUrl(e,t){return se(e,t)}};function st(s){return new V(s)}var ie=class{constructor(){this.tokens=null}getTokens(){return this.tokens}setTokens(e){this.tokens=e}clear(){this.tokens=null}},rt="mero-tokens",ae=class{constructor(e=rt){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 we=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,112,4,34,4,32]);function y(s){let e=new Uint8Array(4);return new DataView(e.buffer).setUint32(0,s,!0),e}function A(s){return Array.from(s,e=>e.toString(16).padStart(2,"0")).join("")}function l(s,e,t){let n=s.trim();if(!/^[0-9a-fA-F]*$/.test(n)||n.length!==t*2)throw new Error(`${e} must be ${t*2} hex characters, got ${n.length}`);let r=new Uint8Array(t);for(let o=0;o<t;o+=1)r[o]=Number.parseInt(n.slice(o*2,o*2+2),16);return r}function R(s){let e=new Uint8Array(8);return new DataView(e.buffer).setBigUint64(0,BigInt(s),!0),e}function m(...s){let e=new Uint8Array(s.reduce((n,r)=>n+r.length,0)),t=0;for(let n of s)e.set(n,t),t+=n.length;return e}async function x(s,e){let t=[R(s.length),s];for(let n of e)t.push(R(n.length),n);return new Uint8Array(await crypto.subtle.digest("SHA-256",m(...t)))}async function k(s){let e=l(s,"deviceSecret",32),t=m(we,e);try{return await crypto.subtle.importKey("pkcs8",t,{name:"Ed25519"},!1,["sign"])}catch(n){let r=n instanceof Error?`: ${n.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`"+r)}}async function w(s){let e=l(s,"deviceSecret",32),t=m(we,e),n=await crypto.subtle.importKey("pkcs8",t,{name:"Ed25519"},!0,["sign"]),o=(await crypto.subtle.exportKey("jwk",n)).x;return Uint8Array.from(atob(o.replace(/-/g,"+").replace(/_/g,"/")),i=>i.charCodeAt(0))}var ot=new TextEncoder().encode("calimero.warrant.v2"),it=new TextEncoder().encode("calimero.warrant.intent.v1"),xe=64,at="00".repeat(32);async function ce(s,e){let t=new TextEncoder().encode(JSON.stringify(e));return x(it,[new TextEncoder().encode(s),t])}async function F(s){let e=l(s.context,"context",32),t=l(s.authorAccount,"authorAccount",32),n=l(s.executor,"executor",32),r=l(s.appVersion??at,"appVersion",32),o=ve(s.accountHeads,"accountHeads"),i=ve(s.governanceFloor,"governanceFloor"),a=await k(s.deviceSecret),p=await w(s.deviceSecret),u=new TextEncoder().encode(s.method),g=await ce(s.method,s.argsJson),h=R(s.nonce),f=R(s.notAfter),b=await x(ot,[e,t,p,n,r,u,g,R(o.length),...o,R(i.length),...i,h,f]),d=new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},a,b));return A(m(e,t,p,n,r,y(u.length),u,g,y(o.length),...o,y(i.length),...i,h,f,d))}function ve(s,e){let t=s??[];if(t.length>xe)throw new Error(`${e} cites ${t.length} heads, over the ${xe} a node accepts`);return t.map((n,r)=>l(n,`${e}[${r}]`,32))}var ct=300,z=class extends Error{constructor(t,n,r){super(`relay refused the intent (HTTP ${r}): ${t}`);this.reason=t;this.retryable=n;this.status=r;this.name="IntentRefusedError"}},q=class{constructor(e){this.config=e,this.baseUrl=e.relayUrl.replace(/\/+$/,""),this.executorAccount=e.executorAccount;let t=e.fetch;this.fetchImpl=t?(n,r)=>t(n,r):(n,r)=>globalThis.fetch(n,r),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,n={}){let r=this.executorAccount??(await this.describe(e)).executorAccount,o=await this.config.nonces.next(),i=this.config.ttlSeconds??ct,a=await F({context:e,authorAccount:this.config.authorAccount,executor:r,method:t,argsJson:n,nonce:o,notAfter:BigInt(Math.floor(Date.now()/1e3))+BigInt(i),deviceSecret:this.config.deviceSecret}),p=await this.json("POST",`/admin-api/contexts/${encodeURIComponent(e)}/intents`,{method:t,argsJson:n,warrant:a,authorProof:this.config.authorProof});return{rootHash:p.data.rootHash,returns:p.data.returns??null}}async json(e,t,n){let r={Accept:"application/json"};n!==void 0&&(r["Content-Type"]="application/json");let o=new AbortController,i=setTimeout(()=>o.abort(),this.timeoutMs),a;try{a=await this.fetchImpl(`${this.baseUrl}${t}`,{method:e,headers:r,body:n===void 0?void 0:JSON.stringify(n),signal:o.signal})}catch(p){throw new C(0,p instanceof Error?p.name:"NetworkError",`${this.baseUrl}${t}`,new Headers,p instanceof Error?p.message:String(p))}finally{clearTimeout(i)}if(!a.ok){let p=await a.text().catch(()=>"");if(a.status===400||a.status===403){let u=pt(p);throw new z(u,/nonce/i.test(u),a.status)}throw new C(a.status,a.statusText,`${this.baseUrl}${t}`,a.headers,p)}return await a.json()}};function pt(s){if(!s)return"no reason given";try{let e=JSON.parse(s);for(let t of[e.error,e.message])if(typeof t=="string"&&t)return t}catch{}return s}function pe(s=1){let e=BigInt(s);if(e<1n)throw new Error("nonce sequence starts at 1");return{next(){let t=e;return e+=1n,Promise.resolve(t)}}}function ue(s,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 n=t.getItem(s),r=0n;if(n!==null&&n!=="")try{let i=BigInt(n);i>0n&&(r=i)}catch{r=0n}let o=r+1n;return t.setItem(s,o.toString()),Promise.resolve(o)}}}async function ut(s){if(!s.sessionToken&&!s.googleIdToken)throw new Error("connectCloud needs either a sessionToken or a googleIdToken");let e=new S({cloudBaseUrl:s.cloudBaseUrl,sessionToken:s.sessionToken,onSession:s.onSession,fetch:s.fetch,timeoutMs:s.timeoutMs});!s.sessionToken&&s.googleIdToken&&await e.signInWithGoogle(s.googleIdToken);let t=await e.getMyNamespaces(),n=lt(t,s.namespaceId),r=await e.getNamespaceRelays(n.namespaceId),o=r.find(a=>a.authorshipReady&&a.relayUrl!==null&&a.executorAccount!==null)??null;if(!o)throw new Error(dt(n,r));let i=new q({relayUrl:o.relayUrl,executorAccount:o.executorAccount,authorAccount:s.authorAccount,authorProof:s.authorProof,deviceSecret:s.deviceSecret,nonces:s.nonces??await ht(s.deviceSecret),ttlSeconds:s.ttlSeconds,fetch:s.fetch,timeoutMs:s.timeoutMs});return{cloud:e,relay:i,namespaceId:n.namespaceId,namespace:n,relayInfo:o,execute:(a,p,u)=>i.execute(a,p,u)}}function lt(s,e){if(e){let t=s.find(n=>n.namespaceId===e);if(!t)throw new Error(`this account owns no namespace ${e}; it owns: ${s.map(n=>n.namespaceId).join(", ")||"(none)"}`);return t}if(s.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(s.length>1)throw new Error(`this account owns ${s.length} namespaces \u2014 pass namespaceId to say which: ${s.map(t=>t.namespaceId).join(", ")}`);return s[0]}function dt(s,e){if(e.length===0)return s.haStatus==="enabled"?`namespace ${s.namespaceId} has HA enabled but no relay has been assigned to it yet \u2014 retry shortly`:`namespace ${s.namespaceId} has no relays: enable HA on it in the cloud to have an attested node assigned`;let t=e.filter(n=>!n.authorshipReady);return t.length===e.length?`every relay on namespace ${s.namespaceId} is waiting for the authorship grant: an admin of the namespace must grant CAN_AUTHOR_ON_BEHALF to ${t.map(n=>n.executorAccount??n.peerId).join(", ")||"the relay account"}`:`namespace ${s.namespaceId} has ${e.length} relay(s), but none reported both a URL and an executor account yet \u2014 retry shortly`}async function ht(s){let e=`mero-js:warrant-nonce:${A(await w(s))}`;try{return ue(e)}catch{return pe(1)}}var mt=new TextEncoder().encode("calimero.device.cert.v1"),ke=new TextEncoder().encode("calimero.account.genesis.v1"),gt=new TextEncoder().encode("calimero.device.id.v1"),le=2;async function Te(s,e){if(e.length!==16)throw new Error(`nonce must be 16 bytes, got ${e.length}`);let t=l(s,"account",32);return A(await x(gt,[t,e]))}async function de(s){return x(mt,[l(s.account,"account",32),l(s.device,"device",32),l(s.signPublicKey,"signPublicKey",32),l(s.kemPublicKey,"kemPublicKey",32),y(s.keyEpoch),y(s.deviceEpoch)])}function Pe(s){return m(new Uint8Array([le]),s.rootPublicKey,y(0),l(s.account,"account",32),l(s.device,"device",32),l(s.signPublicKey,"signPublicKey",32),l(s.kemPublicKey,"kemPublicKey",32),y(s.keyEpoch),y(s.deviceEpoch),s.signature)}async function Se(s){let e=await w(s.rootSecret),t=A(await x(ke,[m(new Uint8Array([le]),e)])),n=0,r=await de({account:t,device:s.device,signPublicKey:s.signPublicKey,kemPublicKey:s.kemPublicKey,keyEpoch:n,deviceEpoch:s.deviceEpoch}),o=await k(s.rootSecret),i=new Uint8Array(await crypto.subtle.sign("Ed25519",o,r)),a=Pe({rootPublicKey:e,account:t,device:s.device,signPublicKey:s.signPublicKey,kemPublicKey:s.kemPublicKey,keyEpoch:n,deviceEpoch:s.deviceEpoch,signature:i});return A(a)}async function Ie(s){let e=await w(s);return A(await x(ke,[m(new Uint8Array([le]),e)]))}var me=8,ft=new TextEncoder().encode("calimero.namespace.v1"),yt=0,De={GroupCreated:0,GroupReparented:1,GroupDeleted:2,AdminChanged:3,PolicyUpdated:4,MemberJoined:5,KeyDelivery:6,MemberJoinedOpen:7,MemberJoinedAt:8,NamespaceCreated:9,MemberJoinedViaTeeAttestation:10};function he(s,e){if(s.length!==32)throw new Error(`${e} must be 32 bytes, got ${s.length}`);return new Uint8Array(s)}function Ee(s,e){if(s==null)return new Uint8Array([0]);if(s.length!==32)throw new Error(`${e} must be 32 bytes, got ${s.length}`);return m(new Uint8Array([1]),new Uint8Array(s))}function Me(s){let e=new TextEncoder().encode(s);return m(y(e.length),e)}function X(s){let e=s.invitation,t=e.admitters??[],n=s.admitter_addrs??[];return m(he(e.inviter_identity,"inviter_identity"),he(e.group_id,"group_id"),R(e.expiration_timestamp),he(e.secret_salt,"secret_salt"),new Uint8Array([e.invited_role]),y(t.length),...t.map((r,o)=>l(r,`admitters[${o}]`,32)),Me(s.inviter_signature),s.inviter_account?m(new Uint8Array([1]),l(s.inviter_account,"inviter_account",32)):new Uint8Array([0]),y(n.length),...n.map(Me),Ee(s.application_id,"application_id"),Ee(s.app_key,"app_key"))}async function _e(s){let e=s.parentOpHashes??[],t=l(s.credential,"credential",s.credential.length/2),n=BigInt(s.invitation.invitation.expiration_timestamp??0)!==0n,r=s.joinedAt??BigInt(Math.floor(Date.now()/1e3)),o=n?m(new Uint8Array([De.MemberJoinedAt]),l(s.member,"member",32),X(s.invitation),R(r),t):m(new Uint8Array([De.MemberJoined]),l(s.member,"member",32),X(s.invitation),t),i=m(new Uint8Array([yt]),o),a=await k(s.deviceSecret),p=await w(s.deviceSecret),u=m(new Uint8Array([me]),l(s.namespaceId,"namespaceId",32),y(e.length),...e.map((f,b)=>l(f,`parentOpHashes[${b}]`,32)),p,R(s.nonce),i),g=new Uint8Array(await crypto.subtle.sign("Ed25519",a,m(ft,u))),h=new Uint8Array([0]);return A(m(u,g,h))}var bt=new TextEncoder().encode("calimero.auth.login.v1"),Ue={webOrigin:0,codeSigningId:1,cli:2};function Ne(s){let e=new TextEncoder;switch(s.kind){case"webOrigin":return e.encode(s.origin);case"codeSigningId":return e.encode(s.id);case"cli":return new Uint8Array(0)}}function Ct(s){return m(Uint8Array.from([Ue[s.kind]]),Ne(s))}function Rt(s){let e=Uint8Array.from([Ue[s.kind]]);if(s.kind==="cli")return e;let t=Ne(s);return m(e,y(t.length),t)}async function Ge(s){let e=l(s.node,"node",32),t=l(s.challenge,"challenge",32),n=l(s.sessionKey,"sessionKey",32),r=await k(s.deviceSecret),o=await w(s.deviceSecret),i=R(s.issuedAt),a=R(s.expiresAt),p=await x(bt,[e,Ct(s.audience),t,n,o,i,a]),u=new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},r,p));return A(m(e,Rt(s.audience),t,n,o,i,a,u))}var is={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 as(s,e){let t=e>>>0;return(s&t)>>>0===t}function cs(s,e){return(s|e)>>>0}function ps(s,e){return(s&~e)>>>0}var He=[2428,2429,2528,2529],At="localhost",wt=2e3;function $e(s){return`http://${At}:${s}`}function qe(s,e){let t=s.endsWith("/")?s:`${s}/`;return new URL(e,t).toString()}async function Oe(s,e={}){let{timeoutMs:t=wt,signal:n}=e;if(n?.aborted)return!1;let r=new AbortController,o=()=>r.abort(),i=n;i&&i.addEventListener("abort",o,{once:!0});let a=setTimeout(()=>r.abort(),t);try{let p=qe(s,"admin-api/health"),u=await fetch(p,{method:"GET",signal:r.signal});if(!u.ok)return!1;try{let g=await u.json(),h=g?.data?.status!==void 0?g?.data?.status:g?.status;return h===void 0?!0:typeof h=="string"&&h.toLowerCase()==="alive"}catch{return!0}}catch{return!1}finally{clearTimeout(a),i&&i.removeEventListener("abort",o)}}async function xt(s={}){let{ports:e=He,timeoutMs:t,signal:n}=s;return(await Promise.all(e.map(async o=>{let i=$e(o);return await Oe(i,{timeoutMs:t,signal:n})?i:null}))).filter(o=>o!==null)}export{P as AdminApiClient,T as AuthApiClient,D as AuthRevokedError,is as CAPABILITIES,S as CloudClient,He as DEFAULT_LOCAL_NODE_PORTS,$ as EphemeralClient,C as HTTPError,z as IntentRefusedError,ae as LocalStorageTokenStore,ie as MemoryTokenStore,V as MeroJs,q as RelayClient,H as RpcClient,K as RpcError,me as SIGNED_NAMESPACE_OP_SCHEMA_VERSION,M as SseClient,N as WebHttpClient,_ as WsClient,Ie as accountForRoot,se as buildAuthLoginUrl,Y as combineSignals,Fe as compareSemver,ut as connectCloud,Yt as createAdminApiClient,Re as createAdminApiClientFromHttpClient,jt as createAuthApiClient,ye as createAuthApiClientFromHttpClient,Xt as createBrowserAdminApiClient,Ot as createBrowserAuthApiClient,E as createBrowserHttpClient,ee as createHttpClient,ue as createLocalStorageNonceSource,pe as createMemoryNonceSource,st as createMeroJs,Qt as createNodeAdminApiClient,Lt as createNodeAuthApiClient,j as createNodeHttpClient,Ve as createRetryableMethod,Z as createTimeoutSignal,te as createUniversalHttpClient,de as deviceCertPayload,xt as discoverLocalNodes,X as encodeSignedInvitation,as as hasCap,ce as intentHash,J as jsonCodec,$e as localNodeUrl,Te as mintDeviceId,qe as nodeEndpoint,ne as parseAuthCallback,Oe as probeNodeHealth,Se as signDeviceCert,Ge as signLoginStatement,_e as signMemberJoinOp,F as signWarrant,cs as withCap,W as withRetry,ps as withoutCap};
|
|
3
3
|
//# sourceMappingURL=index.browser.mjs.map
|