@calimero-network/mero-js 15.1.0 → 15.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-client.d.ts +19 -1
- package/dist/admin-api/admin-client.js +20 -0
- package/dist/admin-api/admin-types.d.ts +69 -0
- package/dist/device-cert/device-cert.d.ts +24 -0
- package/dist/device-cert/device-cert.js +27 -7
- package/dist/device-cert/index.d.ts +1 -1
- package/dist/device-cert/index.js +1 -1
- package/dist/index.browser.mjs +2 -2
- package/dist/index.browser.mjs.map +4 -4
- package/dist/index.cjs +152 -13
- package/dist/index.cjs.map +3 -3
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/index.mjs +152 -13
- package/dist/index.mjs.map +3 -3
- package/dist/namespace-op/index.d.ts +2 -0
- package/dist/namespace-op/index.js +3 -0
- package/dist/namespace-op/namespace-op.d.ts +64 -0
- package/dist/namespace-op/namespace-op.js +109 -0
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { HttpClient } from '../http-client/index.js';
|
|
2
|
-
import type { HealthStatus, AdminAuthStatus, InstallApplicationRequest, InstallApplicationResponseData, InstallDevApplicationRequest, UninstallApplicationResponseData, ListApplicationsResponseData, GetApplicationResponseData, ApplicationVersionEntry, GetApplicationAbiResponseData, GetLatestVersionResponseData, ListPackagesResponseData, ListVersionsResponseData, CreateContextRequest, CreateContextResponseData, DeleteContextRequest, DeleteContextResponseData, GetContextsResponseData, Context, GenerateContextIdentityResponseData, GetContextIdentitiesResponseData, JoinContextResponseData, JoinSubgroupInheritanceResponseData, ContextGroupResponseData, ContextStorageResponseData, InviteSpecializedNodeRequest, InviteSpecializedNodeResponseData, UpdateContextApplicationRequest, ResyncContextRequest, ResyncContextResponseData, ContextsWithExecutorsResponseData, UploadBlobRequest, UploadBlobResponseData, DeleteBlobResponseData, ListBlobsResponseData, GetBlobInfoResponseData, CreateContextAliasRequest, CreateApplicationAliasRequest, CreateAliasResponseData, LookupAliasResponseData, DeleteAliasResponseData, ListAliasesResponseData, ListNamespacesResponseData, CreateNamespaceRequest, CreateNamespaceResponseData, DeleteNamespaceRequest, DeleteNamespaceResponseData, CreateNamespaceInvitationRequest, CreateNamespaceInvitationResponseData, CreateRecursiveInvitationResponseData, JoinNamespaceRequest, JoinNamespaceResponseData, CreateGroupInNamespaceRequest, CreateGroupInNamespaceResponseData, SubgroupEntry, Namespace, NamespaceIdentity, NodeIdentity, GroupInfoResponseData, DeleteGroupRequest, DeleteGroupResponseData, ListGroupMembersResponseData, ListGroupContextsResponseData, AddGroupMembersRequest, RemoveGroupMembersRequest, UpdateMemberRoleRequest, MemberCapabilities, SetMemberCapabilitiesRequest, SetDefaultCapabilitiesRequest, SetSubgroupVisibilityRequest, SetTeeAdmissionPolicyRequest, GetTeeAdmissionPolicyResponseData, SetGroupMetadataRequest, SetMemberMetadataRequest, SetContextMetadataRequest, MetadataRecord, SyncGroupRequest, SyncGroupResponseData, UpgradeGroupRequest, UpgradeGroupResponseData, GroupUpgradeStatusResponseData, MigrationStatus, CascadeStatusEntry, RetryGroupUpgradeRequest, RetryGroupUpgradeResponseData, ReparentGroupRequest, ReparentGroupResponseData, DetachContextFromGroupRequest, CreateGroupInvitationRequest, CreateGroupInvitationResponseData, CreateRecursiveGroupInvitationResponseData, JoinGroupRequest, JoinGroupResponseData, TeeInfoResponseData, TeeAttestRequest, TeeAttestResponseData, TeeVerifyQuoteRequest, TeeVerifyQuoteResponseData, PerformIntentRequest, PerformIntentResponseData } from './admin-types.js';
|
|
2
|
+
import type { HealthStatus, AdminAuthStatus, InstallApplicationRequest, InstallApplicationResponseData, InstallDevApplicationRequest, UninstallApplicationResponseData, ListApplicationsResponseData, GetApplicationResponseData, ApplicationVersionEntry, GetApplicationAbiResponseData, GetLatestVersionResponseData, ListPackagesResponseData, ListVersionsResponseData, CreateContextRequest, CreateContextResponseData, DeleteContextRequest, DeleteContextResponseData, GetContextsResponseData, Context, GenerateContextIdentityResponseData, GetContextIdentitiesResponseData, JoinContextResponseData, JoinSubgroupInheritanceResponseData, ContextGroupResponseData, ContextStorageResponseData, InviteSpecializedNodeRequest, InviteSpecializedNodeResponseData, UpdateContextApplicationRequest, ResyncContextRequest, ResyncContextResponseData, ContextsWithExecutorsResponseData, UploadBlobRequest, UploadBlobResponseData, DeleteBlobResponseData, ListBlobsResponseData, GetBlobInfoResponseData, CreateContextAliasRequest, CreateApplicationAliasRequest, CreateAliasResponseData, LookupAliasResponseData, DeleteAliasResponseData, ListAliasesResponseData, ListNamespacesResponseData, CreateNamespaceRequest, CreateNamespaceResponseData, DeleteNamespaceRequest, DeleteNamespaceResponseData, CreateNamespaceInvitationRequest, CreateNamespaceInvitationResponseData, CreateRecursiveInvitationResponseData, JoinNamespaceRequest, JoinNamespaceResponseData, CreateGroupInNamespaceRequest, CreateGroupInNamespaceResponseData, SubgroupEntry, Namespace, NamespaceIdentity, NodeIdentity, GroupInfoResponseData, DeleteGroupRequest, DeleteGroupResponseData, ListGroupMembersResponseData, ListGroupContextsResponseData, AddGroupMembersRequest, RemoveGroupMembersRequest, UpdateMemberRoleRequest, MemberCapabilities, SetMemberCapabilitiesRequest, SetDefaultCapabilitiesRequest, SetSubgroupVisibilityRequest, SetTeeAdmissionPolicyRequest, GetTeeAdmissionPolicyResponseData, SetGroupMetadataRequest, SetMemberMetadataRequest, SetContextMetadataRequest, MetadataRecord, SyncGroupRequest, SyncGroupResponseData, UpgradeGroupRequest, UpgradeGroupResponseData, GroupUpgradeStatusResponseData, MigrationStatus, CascadeStatusEntry, RetryGroupUpgradeRequest, RetryGroupUpgradeResponseData, ReparentGroupRequest, ReparentGroupResponseData, DetachContextFromGroupRequest, CreateGroupInvitationRequest, CreateGroupInvitationResponseData, CreateRecursiveGroupInvitationResponseData, JoinGroupRequest, JoinGroupResponseData, TeeInfoResponseData, TeeAttestRequest, TeeAttestResponseData, TeeVerifyQuoteRequest, TeeVerifyQuoteResponseData, PerformIntentRequest, PerformIntentResponseData, AdmitJoinRequest, AdmitJoinResponseData } from './admin-types.js';
|
|
3
3
|
/**
|
|
4
4
|
* Compare two version strings by SemVer 2.0 precedence, ascending: negative if
|
|
5
5
|
* `a < b`, positive if `a > b`, `0` if equal. Build metadata (`+...`) is stripped
|
|
@@ -159,6 +159,24 @@ export declare class AdminApiClient {
|
|
|
159
159
|
createNamespace(request: CreateNamespaceRequest): Promise<CreateNamespaceResponseData>;
|
|
160
160
|
deleteNamespace(namespaceId: string, request?: DeleteNamespaceRequest): Promise<DeleteNamespaceResponseData>;
|
|
161
161
|
createNamespaceInvitation(namespaceId: string, request?: CreateNamespaceInvitationRequest): Promise<CreateNamespaceInvitationResponseData | CreateRecursiveInvitationResponseData>;
|
|
162
|
+
/**
|
|
163
|
+
* Present a join this caller signed to a node the inviter named as an
|
|
164
|
+
* admitter.
|
|
165
|
+
*
|
|
166
|
+
* For a member with no node. `joinNamespace` publishes the membership op from
|
|
167
|
+
* the node making the call; this hands an already-signed op to somebody else's
|
|
168
|
+
* node to publish. The distinction matters because a keyholder has nowhere to
|
|
169
|
+
* publish from.
|
|
170
|
+
*
|
|
171
|
+
* The op must be signed by the **device key** in the credential it carries —
|
|
172
|
+
* every peer checks that when applying a join. So the admitter cannot author
|
|
173
|
+
* this, only carry it: a hostile one can refuse, and nothing else. It cannot
|
|
174
|
+
* admit a different account, change the group, or grant a role.
|
|
175
|
+
*
|
|
176
|
+
* @param namespaceId the namespace being joined, 64 hex
|
|
177
|
+
* @param request the invitation and the hex-encoded signed op
|
|
178
|
+
*/
|
|
179
|
+
admitJoin(namespaceId: string, request: AdmitJoinRequest): Promise<AdmitJoinResponseData>;
|
|
162
180
|
joinNamespace(namespaceId: string, request: JoinNamespaceRequest): Promise<JoinNamespaceResponseData>;
|
|
163
181
|
createGroupInNamespace(namespaceId: string, request?: CreateGroupInNamespaceRequest): Promise<CreateGroupInNamespaceResponseData>;
|
|
164
182
|
listNamespaceGroups(namespaceId: string): Promise<SubgroupEntry[]>;
|
|
@@ -466,6 +466,26 @@ export class AdminApiClient {
|
|
|
466
466
|
async createNamespaceInvitation(namespaceId, request) {
|
|
467
467
|
return unwrap(await this.httpClient.post(`/admin-api/namespaces/${namespaceId}/invite`, request ?? {}));
|
|
468
468
|
}
|
|
469
|
+
/**
|
|
470
|
+
* Present a join this caller signed to a node the inviter named as an
|
|
471
|
+
* admitter.
|
|
472
|
+
*
|
|
473
|
+
* For a member with no node. `joinNamespace` publishes the membership op from
|
|
474
|
+
* the node making the call; this hands an already-signed op to somebody else's
|
|
475
|
+
* node to publish. The distinction matters because a keyholder has nowhere to
|
|
476
|
+
* publish from.
|
|
477
|
+
*
|
|
478
|
+
* The op must be signed by the **device key** in the credential it carries —
|
|
479
|
+
* every peer checks that when applying a join. So the admitter cannot author
|
|
480
|
+
* this, only carry it: a hostile one can refuse, and nothing else. It cannot
|
|
481
|
+
* admit a different account, change the group, or grant a role.
|
|
482
|
+
*
|
|
483
|
+
* @param namespaceId the namespace being joined, 64 hex
|
|
484
|
+
* @param request the invitation and the hex-encoded signed op
|
|
485
|
+
*/
|
|
486
|
+
async admitJoin(namespaceId, request) {
|
|
487
|
+
return unwrap(await this.httpClient.post(`/admin-api/namespaces/${namespaceId}/admit`, request, { timeoutMs: 65000 }));
|
|
488
|
+
}
|
|
469
489
|
async joinNamespace(namespaceId, request) {
|
|
470
490
|
const data = unwrap(await this.httpClient.post(`/admin-api/namespaces/${namespaceId}/join`, request, { timeoutMs: 65000 }));
|
|
471
491
|
// core 0.11.0-rc.25 renamed this response's `groupId` to `namespaceId`
|
|
@@ -240,6 +240,18 @@ export interface GroupInvitationFromAdmin {
|
|
|
240
240
|
/** Per-invitation nonce; core keeps the legacy `secret_salt` wire name. */
|
|
241
241
|
readonly secret_salt: number[];
|
|
242
242
|
readonly invited_role: number;
|
|
243
|
+
/**
|
|
244
|
+
* Accounts permitted to admit a claim of this invitation, 64 hex characters
|
|
245
|
+
* each — the same spelling every other account-addressing field uses.
|
|
246
|
+
*
|
|
247
|
+
* Empty means admission by broadcast: the joiner announces itself on the
|
|
248
|
+
* namespace topic and any ready peer answers — which publishes the invitation
|
|
249
|
+
* to every subscriber of that topic. Naming admitters keeps it off the topic,
|
|
250
|
+
* and the joiner presents it to one of them directly.
|
|
251
|
+
*
|
|
252
|
+
* Inside the inviter's signature, so it cannot be redirected.
|
|
253
|
+
*/
|
|
254
|
+
readonly admitters?: readonly string[];
|
|
243
255
|
}
|
|
244
256
|
/**
|
|
245
257
|
* An invitation blob the node signed. **Opaque: pass it through unchanged.**
|
|
@@ -260,6 +272,22 @@ export interface GroupInvitationFromAdmin {
|
|
|
260
272
|
export interface SignedGroupOpenInvitation {
|
|
261
273
|
readonly invitation: GroupInvitationFromAdmin;
|
|
262
274
|
readonly inviter_signature: string;
|
|
275
|
+
/**
|
|
276
|
+
* Where to reach the accounts in {@link GroupInvitationFromAdmin.admitters}.
|
|
277
|
+
*
|
|
278
|
+
* Outside the signature, like the other bootstrap hints: an account is reached
|
|
279
|
+
* through a peer id, and a joiner that has synced nothing cannot resolve one.
|
|
280
|
+
* A wrong hint costs a failed connection — the admitting node still has to be
|
|
281
|
+
* in the signed list for its admission to count.
|
|
282
|
+
*
|
|
283
|
+
* `{ multiaddr }` for a joiner that runs a node, `{ url }` for one that holds
|
|
284
|
+
* only a key and reaches the admin API over HTTPS.
|
|
285
|
+
*/
|
|
286
|
+
readonly admitter_hints?: ReadonlyArray<{
|
|
287
|
+
readonly multiaddr: string;
|
|
288
|
+
} | {
|
|
289
|
+
readonly url: string;
|
|
290
|
+
}>;
|
|
263
291
|
/**
|
|
264
292
|
* The account the inviter acts as, as 64 hex characters — not the
|
|
265
293
|
* `inviter_identity` key inside the signed body is written in. Governance
|
|
@@ -275,6 +303,12 @@ export interface SignedGroupOpenInvitation {
|
|
|
275
303
|
/** Unsigned bootstrap field; absent on invitations from older nodes. */
|
|
276
304
|
readonly application_id?: number[];
|
|
277
305
|
/** Unsigned bootstrap field; absent on invitations from older nodes. */
|
|
306
|
+
/**
|
|
307
|
+
* The wire name is `app_key`; core's Rust field is `bytecode_id` behind a
|
|
308
|
+
* `rename` that covers both directions, and core pins this spelling in a test.
|
|
309
|
+
* `Option<[u8; 32]>` crosses JSON as an array of byte values, not as hex —
|
|
310
|
+
* unlike `AccountId`, which has its own hex representation.
|
|
311
|
+
*/
|
|
278
312
|
readonly app_key?: number[];
|
|
279
313
|
/** @internal Brand — never present at runtime, never write it. */
|
|
280
314
|
readonly __nodeSigned: never;
|
|
@@ -798,6 +832,18 @@ export interface CreateGroupInvitationRequest {
|
|
|
798
832
|
requester?: string;
|
|
799
833
|
expirationTimestamp?: number;
|
|
800
834
|
recursive?: boolean;
|
|
835
|
+
/**
|
|
836
|
+
* Accounts permitted to admit a claim of this invitation, 64 hex each.
|
|
837
|
+
*
|
|
838
|
+
* Omitted or empty leaves admission open to broadcast, which publishes the
|
|
839
|
+
* invitation to every subscriber of the namespace topic. Naming admitters
|
|
840
|
+
* keeps it off the topic: the joiner presents the claim to one of them and
|
|
841
|
+
* every other peer refuses to answer for it.
|
|
842
|
+
*
|
|
843
|
+
* Core signs this list into the invitation, so it cannot be redirected after
|
|
844
|
+
* the fact.
|
|
845
|
+
*/
|
|
846
|
+
admitters?: string[];
|
|
801
847
|
}
|
|
802
848
|
export interface CreateGroupInvitationResponseData {
|
|
803
849
|
invitation: SignedGroupOpenInvitation;
|
|
@@ -884,3 +930,26 @@ export interface AdminApiClientConfig {
|
|
|
884
930
|
getAuthToken?: () => Promise<string | undefined>;
|
|
885
931
|
timeoutMs?: number;
|
|
886
932
|
}
|
|
933
|
+
/** A join signed by its subject, handed to an admitter to publish. */
|
|
934
|
+
export interface AdmitJoinRequest {
|
|
935
|
+
/** The invitation being claimed. Must name the admitter in `admitters`. */
|
|
936
|
+
readonly invitation: SignedGroupOpenInvitation;
|
|
937
|
+
/**
|
|
938
|
+
* The signed `SignedNamespaceOp`, borsh-encoded and hex.
|
|
939
|
+
*
|
|
940
|
+
* Signed by the joiner's device key, which is what stops an admitter
|
|
941
|
+
* substituting a different member: peers check the op's signer against the
|
|
942
|
+
* credential the op carries.
|
|
943
|
+
*/
|
|
944
|
+
readonly signedOp: string;
|
|
945
|
+
}
|
|
946
|
+
/** What the admitter did with it. */
|
|
947
|
+
export interface AdmitJoinResponseData {
|
|
948
|
+
/**
|
|
949
|
+
* Whether the op reached the namespace topic.
|
|
950
|
+
*
|
|
951
|
+
* Not "joined" — membership lands when peers apply the op, which the admitter
|
|
952
|
+
* neither performs nor waits for.
|
|
953
|
+
*/
|
|
954
|
+
readonly published: boolean;
|
|
955
|
+
}
|
|
@@ -39,6 +39,30 @@ export declare function deviceCertPayload(input: {
|
|
|
39
39
|
keyEpoch: number;
|
|
40
40
|
deviceEpoch: number;
|
|
41
41
|
}): Promise<Uint8Array>;
|
|
42
|
+
/**
|
|
43
|
+
* Borsh-encode an `AccountProof<DeviceCert>` — what core calls a
|
|
44
|
+
* `JoinAccountCredential`.
|
|
45
|
+
*
|
|
46
|
+
* Extracted so the device-cert path and the namespace-op signer encode this from
|
|
47
|
+
* one implementation. Two copies of a borsh layout drift silently: the encoding
|
|
48
|
+
* is only checked by a peer rejecting a signature, which points at the signature
|
|
49
|
+
* rather than at whichever copy went stale.
|
|
50
|
+
*
|
|
51
|
+
* Layout is `AccountProof { genesis, chain, statement }`:
|
|
52
|
+
* `AccountGenesis` (version u8 + root pk 32) + `chain` (empty Vec, u32 len) +
|
|
53
|
+
* `DeviceCert` (account 32 + device 32 + sign pk 32 + kem pk 32 + key_epoch u32
|
|
54
|
+
* + device_epoch u32 + signature 64) = 237 bytes with an empty chain.
|
|
55
|
+
*/
|
|
56
|
+
export declare function accountProofBytes(input: {
|
|
57
|
+
rootPublicKey: Uint8Array;
|
|
58
|
+
account: string;
|
|
59
|
+
device: string;
|
|
60
|
+
signPublicKey: string;
|
|
61
|
+
kemPublicKey: string;
|
|
62
|
+
keyEpoch: number;
|
|
63
|
+
deviceEpoch: number;
|
|
64
|
+
signature: Uint8Array;
|
|
65
|
+
}): Uint8Array;
|
|
42
66
|
/**
|
|
43
67
|
* Certify a device, returning the hex credential `merod account sign-cert`
|
|
44
68
|
* prints — a borsh-encoded `AccountProof<DeviceCert>`.
|
|
@@ -52,6 +52,23 @@ export async function deviceCertPayload(input) {
|
|
|
52
52
|
u32le(input.deviceEpoch),
|
|
53
53
|
]);
|
|
54
54
|
}
|
|
55
|
+
/**
|
|
56
|
+
* Borsh-encode an `AccountProof<DeviceCert>` — what core calls a
|
|
57
|
+
* `JoinAccountCredential`.
|
|
58
|
+
*
|
|
59
|
+
* Extracted so the device-cert path and the namespace-op signer encode this from
|
|
60
|
+
* one implementation. Two copies of a borsh layout drift silently: the encoding
|
|
61
|
+
* is only checked by a peer rejecting a signature, which points at the signature
|
|
62
|
+
* rather than at whichever copy went stale.
|
|
63
|
+
*
|
|
64
|
+
* Layout is `AccountProof { genesis, chain, statement }`:
|
|
65
|
+
* `AccountGenesis` (version u8 + root pk 32) + `chain` (empty Vec, u32 len) +
|
|
66
|
+
* `DeviceCert` (account 32 + device 32 + sign pk 32 + kem pk 32 + key_epoch u32
|
|
67
|
+
* + device_epoch u32 + signature 64) = 237 bytes with an empty chain.
|
|
68
|
+
*/
|
|
69
|
+
export function accountProofBytes(input) {
|
|
70
|
+
return concat(new Uint8Array([ACCOUNT_GENESIS_VERSION]), input.rootPublicKey, u32le(0), fromHex(input.account, 'account', 32), fromHex(input.device, 'device', 32), fromHex(input.signPublicKey, 'signPublicKey', 32), fromHex(input.kemPublicKey, 'kemPublicKey', 32), u32le(input.keyEpoch), u32le(input.deviceEpoch), input.signature);
|
|
71
|
+
}
|
|
55
72
|
/**
|
|
56
73
|
* Certify a device, returning the hex credential `merod account sign-cert`
|
|
57
74
|
* prints — a borsh-encoded `AccountProof<DeviceCert>`.
|
|
@@ -92,13 +109,16 @@ export async function signDeviceCert(input) {
|
|
|
92
109
|
});
|
|
93
110
|
const key = await importSigningKey(input.rootSecret);
|
|
94
111
|
const signature = new Uint8Array(await crypto.subtle.sign('Ed25519', key, payload));
|
|
95
|
-
const credential =
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
112
|
+
const credential = accountProofBytes({
|
|
113
|
+
rootPublicKey,
|
|
114
|
+
account,
|
|
115
|
+
device: input.device,
|
|
116
|
+
signPublicKey: input.signPublicKey,
|
|
117
|
+
kemPublicKey: input.kemPublicKey,
|
|
118
|
+
keyEpoch,
|
|
119
|
+
deviceEpoch: input.deviceEpoch,
|
|
120
|
+
signature,
|
|
121
|
+
});
|
|
102
122
|
return hex(credential);
|
|
103
123
|
}
|
|
104
124
|
/** The account this root owns — the content address of its genesis. */
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { signDeviceCert, mintDeviceId, deviceCertPayload, accountForRoot, } from './device-cert.js';
|
|
1
|
+
export { signDeviceCert, mintDeviceId, deviceCertPayload, accountForRoot, accountProofBytes, } from './device-cert.js';
|
|
2
2
|
export type { DeviceCertInput } from './device-cert.js';
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Offline device certification — the account-root half of the keyholder story.
|
|
2
|
-
export { signDeviceCert, mintDeviceId, deviceCertPayload, accountForRoot, } from './device-cert.js';
|
|
2
|
+
export { signDeviceCert, mintDeviceId, deviceCertPayload, accountForRoot, accountProofBytes, } from './device-cert.js';
|
package/dist/index.browser.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
function J(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=i=>{n.abort(i.target.reason);for(let a of e)a.removeEventListener("abort",r)};for(let i of e){if(i.aborted)return AbortSignal.abort(i.reason);i.addEventListener("abort",r,{once:!0})}return n.signal}function F(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 De=new Set(["token_reuse","token_revoked"]);function Pe(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 y=class extends Error{constructor(t,n,r,i,a){let p=Pe(a);super(p?`HTTP ${t} ${n}: ${p}`:`HTTP ${t} ${n}`);this.status=t;this.statusText=n;this.url=r;this.headers=i;this.bodyText=a;this.name="HTTPError"}toJSON(){return{status:this.status,statusText:this.statusText,url:this.url,headers:pe(this.headers),bodyText:this.bodyText}}},v=class extends y{constructor(t,n,r,i,a,p){super(n,r,i,a,p);this.reason=t;this.name="AuthRevokedError";this.message=`Authentication revoked (${t}): HTTP ${n} ${r}`}};function pe(s){let e={};return s.forEach((t,n)=>{e[n]=t}),e}var E=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:pe(n.headers),status:n.status}}async request(e,t){return this.makeRequest(e,t)}async makeRequest(e,t,n=0,r){let a=this.buildUrl(e),p=r??Date.now(),h=this.createAbortSignal(t),l=await this.buildHeaders(t?.headers),u;l instanceof Headers?(u={},l.forEach((c,A)=>{u[A]=c})):u=l;let d={method:t?.method||"GET",headers:u},m=t?.body instanceof ReadableStream||typeof t?.body=="object"&&t?.body!==null&&"getReader"in t.body&&!(t.body instanceof Blob);(t?.body!==void 0&&!m||t?.body!==void 0&&m&&n===0)&&(d.body=t.body);let f;if(n>0&&r!==void 0){let c=t?.timeoutMs||this.transport.timeoutMs;if(c){let A=Date.now()-p,I=Math.max(0,c-A);f=this.createAbortSignal({...t,timeoutMs:I})}else f=this.createAbortSignal(t)}else f=h;f&&(d.signal=f),this.transport.credentials!==void 0&&(d.credentials=this.transport.credentials),t?.mode!==void 0&&(d.mode=t.mode),t?.cache!==void 0&&(d.cache=t.cache),t?.redirect!==void 0&&(d.redirect=t.redirect),t?.referrer!==void 0&&(d.referrer=t.referrer),t?.referrerPolicy!==void 0&&(d.referrerPolicy=t.referrerPolicy),t?.integrity!==void 0&&(d.integrity=t.integrity),t?.keepalive!==void 0&&(d.keepalive=t.keepalive);try{let c=await this.transport.fetch(a,d);if(!c.ok){let A=await this.getBodyText(c),I=new y(c.status,c.statusText,a,c.headers,A),$=c.headers.get("x-auth-error");if((c.status===401||c.status===403)&&$&&De.has($)){if(this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,this.transport.onAuthRevoked)try{await this.transport.onAuthRevoked()}catch{}throw new v($,c.status,c.statusText,a,c.headers,A)}let ve=t?.signal?.aborted===!0;if(c.status===401&&this.transport.refreshToken&&$==="token_expired"&&n<1&&!m&&!ve)try{let C=this.refreshTokenPromise;C||(C=this.transport.refreshToken(),this.refreshTokenPromise=C);let B=await C;if(!B||B.trim()==="")throw this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,new Error("Refresh token returned empty token");if(!this.transport.onTokenRefresh)throw this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,new Error("onTokenRefresh callback is required when refreshToken is provided. The callback must update the token storage so getAuthToken() returns the new token.");let _=this.onTokenRefreshPromise;_||(_=this.transport.onTokenRefresh(B),this.onTokenRefreshPromise=_),await _,this.refreshTokenPromise=null,this.onTokenRefreshPromise=null;let ae=t?.timeoutMs||this.transport.timeoutMs;if(ae&&r!==void 0){let Te=Date.now()-p;if(ae-Te<=0)throw I}return this.makeRequest(e,t,n+1,p)}catch(C){throw this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,C instanceof Error&&C.message.includes("onTokenRefresh")?C:I}throw I}return this.parseResponse(c,t?.parse)}catch(c){throw c instanceof y||c instanceof Error&&c.message.includes("onTokenRefresh")?c:new y(0,"Network Error",a,new Headers,c instanceof Error?c.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(F(n)),t.length>0?J(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 z(s){return new E(s)}function T(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 z(e)}function q(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,i)=>globalThis.fetch(r,i):(r,i)=>e(r,i),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 z(n)}function Q(s){return typeof window<"u"?T(s):q(s)}function Se(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 i=r.status;return i>=500||i===429}return n==="TypeError"}function Ie(s){let t=250*Math.pow(2,s-1),n=(Math.random()-.5)*.4*t;return Math.max(0,t+n)}async function L(s,e={}){let{attempts:t=3}=e,n;for(let r=1;r<=t;r++)try{return await s(r)}catch(i){if(n=i,!Se(n,t-r))throw n;let a=Ie(r),l=n.headers?.get?.("Retry-After");if(l){let u=parseInt(l,10);if(!isNaN(u))a=Math.max(a,u*1e3);else{let d=new Date(l);if(!isNaN(d.getTime())){let m=Math.max(0,d.getTime()-Date.now());a=Math.max(a,Math.min(m,6e4))}}}await new Promise(u=>setTimeout(u,a))}throw n||new Error("Retry failed without error")}function Ee(s,e={}){return async(...t)=>L(()=>s(...t),e)}var w=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 M=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 pt(s){let e=new M;return new w(e)}function ct(s){let e=new M;return new w(e)}function lt(s){let e=new M;return new w(e)}function ce(s,e){return new w(s)}function o(s){return s?.data}function Me(s,e){let[t,n]=le(s),[r,i]=le(e),a=t.split("."),p=r.split("."),h=Math.max(a.length,p.length);for(let m=0;m<h;m++){let f=ue(a[m]??"0",p[m]??"0");if(f!==0)return f}if(n===void 0&&i===void 0)return 0;if(n===void 0)return 1;if(i===void 0)return-1;let l=n.split("."),u=i.split("."),d=Math.max(l.length,u.length);for(let m=0;m<d;m++){if(m>=l.length)return-1;if(m>=u.length)return 1;let f=ue(l[m],u[m]);if(f!==0)return f}return 0}function le(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 ue(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 de(s,e,t){return L(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 k=class{constructor(e){this.httpClient=e}async healthCheck(){return o(await this.httpClient.get("/admin-api/health"))}async isAuthed(){return this.httpClient.get("/admin-api/is-authed")}async installApplication(e){return o(await this.httpClient.post("/admin-api/install-application",e))}async installFromRegistry(e,t,n){let r=new URL(e).origin,i=new URL(`/api/v2/bundles/${encodeURIComponent(t)}/${encodeURIComponent(n)}`,r).toString(),p=await(await de(i,"manifest",`${t}@${n}`)).json(),h=encodeURIComponent(p.package),l=encodeURIComponent(p.appVersion),u=`${r}/artifacts/${h}/${l}/${h}-${l}.mpk`;return this.installApplication({url:u,package:p.package,version:p.appVersion,metadata:[]})}async getRegistryVersions(e,t){let n=new URL("/api/v2/bundles",new URL(e).origin);n.searchParams.set("package",t);let i=await(await de(n.toString(),"versions",t)).json();return(Array.isArray(i)?i:[]).map(a=>a.appVersion).filter(a=>typeof a=="string").sort((a,p)=>Me(p,a))}async installDevApplication(e){return o(await this.httpClient.post("/admin-api/install-dev-application",e))}async uninstallApplication(e){return o(await this.httpClient.delete(`/admin-api/applications/${e}`))}async listApplications(){return o(await this.httpClient.get("/admin-api/applications"))}async getApplication(e){return o(await this.httpClient.get(`/admin-api/applications/${e}`))}async listApplicationVersions(e){return o(await this.httpClient.get(`/admin-api/applications/${e}/versions`))}async getApplicationAbi(e,t){let n=t?`?service_name=${encodeURIComponent(t)}`:"";return o(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 o(await this.httpClient.post("/admin-api/contexts",t))}async deleteContext(e,t){return o(t?await this.httpClient.request(`/admin-api/contexts/${e}`,{method:"DELETE",body:JSON.stringify(t),headers:{"Content-Type":"application/json"}}):await this.httpClient.delete(`/admin-api/contexts/${e}`))}async getContexts(){return o(await this.httpClient.get("/admin-api/contexts"))}async getContext(e){return o(await this.httpClient.get(`/admin-api/contexts/${e}`))}async getContextsForApplication(e){return o(await this.httpClient.get(`/admin-api/contexts/for-application/${e}`))}async generateContextIdentity(){return o(await this.httpClient.post("/admin-api/identity/context",{}))}async getContextIdentities(e){return o(await this.httpClient.get(`/admin-api/contexts/${e}/identities`))}async getContextIdentitiesOwned(e){return o(await this.httpClient.get(`/admin-api/contexts/${e}/identities-owned`))}async joinContext(e){return o(await this.httpClient.post(`/admin-api/contexts/${e}/join`,{}))}async getContextGroup(e){return o(await this.httpClient.get(`/admin-api/contexts/${e}/group`))}async getContextStorage(e){return o(await this.httpClient.get(`/admin-api/contexts/${e}/storage`))}async syncContext(e){await this.httpClient.post(`/admin-api/contexts/sync/${e??""}`,{})}async resyncContext(e,t={}){return await this.httpClient.post(`/admin-api/contexts/${e}/resync`,t)??{contextId:e,resyncStarted:!0}}async inviteSpecializedNode(e){return o(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",i=o(await this.httpClient.request(r,{method:"PUT",body:e.data,headers:{"Content-Type":"application/octet-stream"}}));return{blobId:i.blob_id,size:i.size}}async deleteBlob(e){let t=await this.httpClient.delete(`/admin-api/blobs/${e}`);return{blobId:t.blob_id,deleted:t.deleted}}async listBlobs(){return{blobs:o(await this.httpClient.get("/admin-api/blobs")).blobs.map(t=>({blobId:t.blob_id,size:t.size}))}}async getBlob(e){return this.httpClient.get(`/admin-api/blobs/${e}`,{parse:"arrayBuffer"})}async getBlobInfo(e){let{headers:t}=await this.httpClient.head(`/admin-api/blobs/${e}`),n=Number(t["content-length"]);return{blobId:t["x-blob-id"]??e,size:Number.isFinite(n)?n:0,hash:t["x-blob-hash"],mimeType:t["x-blob-mime-type"]}}async createContextAlias(e){return o(await this.httpClient.post("/admin-api/alias/create/context",{alias:e.alias,contextId:e.contextId}))}async createApplicationAlias(e){return o(await this.httpClient.post("/admin-api/alias/create/application",{alias:e.alias,applicationId:e.applicationId}))}async lookupContextAlias(e){return o(await this.httpClient.post(`/admin-api/alias/lookup/context/${encodeURIComponent(e)}`,{}))}async lookupApplicationAlias(e){return o(await this.httpClient.post(`/admin-api/alias/lookup/application/${encodeURIComponent(e)}`,{}))}async deleteContextAlias(e){return o(await this.httpClient.post(`/admin-api/alias/delete/context/${encodeURIComponent(e)}`,{}))}async deleteApplicationAlias(e){return o(await this.httpClient.post(`/admin-api/alias/delete/application/${encodeURIComponent(e)}`,{}))}async listContextAliases(){return o(await this.httpClient.get("/admin-api/alias/list/context"))}async listApplicationAliases(){return o(await this.httpClient.get("/admin-api/alias/list/application"))}async listNamespaces(){return o(await this.httpClient.get("/admin-api/namespaces"))}async getNamespace(e){return o(await this.httpClient.get(`/admin-api/namespaces/${e}`))}async getNodeIdentity(){return o(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 o(await this.httpClient.post(`/admin-api/contexts/${e}/intents`,t))}async listNamespacesForApplication(e){return o(await this.httpClient.get(`/admin-api/namespaces/for-application/${e}`))}async createNamespace(e){return o(await this.httpClient.post("/admin-api/namespaces",{upgradePolicy:"LazyOnAccess",...e}))}async deleteNamespace(e,t){return o(await this.httpClient.request(`/admin-api/namespaces/${e}`,{method:"DELETE",body:JSON.stringify(t??{}),headers:{"Content-Type":"application/json"}}))}async createNamespaceInvitation(e,t){return o(await this.httpClient.post(`/admin-api/namespaces/${e}/invite`,t??{}))}async joinNamespace(e,t){let n=o(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 o(await this.httpClient.post(`/admin-api/namespaces/${e}/groups`,t??{}))}async listNamespaceGroups(e){return o(await this.httpClient.get(`/admin-api/namespaces/${e}/groups`))}async getGroupInfo(e){return o(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,t){return o(await this.httpClient.request(`/admin-api/groups/${e}`,{method:"DELETE",body:JSON.stringify(t??{}),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 o(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 o(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,t){return o(await this.httpClient.post(`/admin-api/groups/${e}/sync`,t??{}))}async upgradeGroup(e,t){return o(await this.httpClient.post(`/admin-api/groups/${e}/upgrade`,t))}async getGroupUpgradeStatus(e){return o(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 o(await this.httpClient.get(`/admin-api/groups/${t}/cascade-status`))}async retryGroupUpgrade(e,t){return o(await this.httpClient.post(`/admin-api/groups/${e}/upgrade/retry`,t??{}))}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,n){await this.httpClient.post(`/admin-api/groups/${e}/contexts/${t}/remove`,n??{})}async createGroupInvitation(e,t){return o(await this.httpClient.post(`/admin-api/groups/${e}/invite`,t??{}))}async joinGroup(e){return o(await this.httpClient.post("/admin-api/groups/join",e))}async joinSubgroupInheritance(e){return o(await this.httpClient.post(`/admin-api/groups/${e}/join-via-inheritance`,{}))}async getTeeInfo(){return o(await this.httpClient.get("/admin-api/tee/info"))}async teeAttest(e){return o(await this.httpClient.post("/admin-api/tee/attest",e))}async teeVerifyQuote(e){return o(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 o(await this.httpClient.post("/admin-api/groups",{upgradePolicy:"LazyOnAccess",...e}))}async leaveGroup(e,t){await this.httpClient.post(`/admin-api/groups/${e}/leave`,t??{})}async leaveContext(e,t){await this.httpClient.post(`/admin-api/contexts/${e}/leave`,t??{})}async leaveNamespace(e,t){await this.httpClient.post(`/admin-api/namespaces/${e}/leave`,t??{})}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,t){return this.httpClient.post(`/admin-api/groups/${e}/migration/abort`,t??{})}};function bt(s){return new k(T(s))}function Ct(s){return new k(q(s))}function Rt(s){return new k(Q(s))}function he(s,e){return new k(s)}function X(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 Y(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 O=class extends Error{constructor(e,t,n,r){super(t),this.name="RpcError",this.code=e,this.data=n,this.type=r}};async function Z(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 O(r.code??-1,r.message??r.type??"RPC error",r.data,r.type)}return n.result}var G=class{constructor(e){this.httpClient=e.httpClient}async execute(e){let t=await Z(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 Ge=new Set(["MigrationStarted","MigrationProgress","CascadeProgress","MigrationCompleted"]);function me(s){return s.type!==void 0&&Ge.has(s.type)}var Ue=new Set(["token_reuse","token_revoked"]),D=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],i=r.indexOf(t);i!==-1&&r.splice(i,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=>{me(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"),i=await n.text().catch(()=>{});throw n.status===401&&r&&Ue.has(r)?new v(r,n.status,n.statusText,t,n.headers,i):new y(n.status,n.statusText,t,n.headers,i)}if(!n.body)throw new Error("SSE response has no body");this.readStream(n.body).catch(r=>{if(this.closed)return;let i=r instanceof Error?r:new Error(String(r));this.emit("error",i),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:i,value:a}=await t.read();if(i)break;r+=n.decode(a,{stream:!0});let p=r.split(`
|
|
2
|
-
`);r=p.pop()??"";for(let h of p)if(h.startsWith("data:")){let l=h.slice(5).trim();l&&this.handleMessage(l)}}if(r+=n.decode(),r.startsWith("data:")){let i=r.slice(5).trim();i&&this.handleMessage(i)}}catch(i){if(this.closed)return;let a=i instanceof Error?i:new Error(String(i));this.emit("error",a)}this.closed||this.scheduleReconnect()}handleMessage(e){try{let t=JSON.parse(e);if(t.type==="connect"&&t.session_id){this.sessionId=t.session_id,this.emit("connect",t.session_id),(this.subscribedContextIds.size>0||this.subscribedGroupIds.size>0)&&this.sendSubscription("subscribe",{contextIds:[...this.subscribedContextIds],groupIds:[...this.subscribedGroupIds]});return}if(!t.result)return;let n=t.result.data;if(Array.isArray(n))try{let r=new Uint8Array(n),i=new TextDecoder().decode(r);n=JSON.parse(i)}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(i=>!this.subscribedContextIds.has(i)),r=(t.groupIds??[]).filter(i=>!this.subscribedGroupIds.has(i));for(let i of t.contextIds??[])this.subscribedContextIds.add(i);for(let i of t.groupIds??[])this.subscribedGroupIds.add(i);(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(i=>this.subscribedContextIds.has(i)),r=(t.groupIds??[]).filter(i=>this.subscribedGroupIds.has(i));for(let i of t.contextIds??[])this.subscribedContextIds.delete(i);for(let i of t.groupIds??[])this.subscribedGroupIds.delete(i);(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 i=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})});i.ok||this.emit("error",new Error(`SSE ${e} failed: ${i.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 W=class W{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],i=r.indexOf(t);i!==-1&&r.splice(i,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),i=new TextDecoder().decode(r);n=JSON.parse(i)}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),W.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()}};W.MAX_BACKOFF_MS=3e4;var P=W;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 U=class{constructor(e){this.httpClient=e.httpClient,this.sse=e.sse}async set(e,t,n=j()){await Z(this.httpClient,"set_ephemeral",{contextId:e,state:n.encode(t)})}subscribe(e,t,n=j()){let r=i=>{let a=i;if(a.type!=="Ephemeral"||a.contextId!==e)return;let p=a.data;if(!p?.author)return;let h=!!p.removed,l={author:p.author,state:h||p.state===void 0?void 0:n.decode(p.state),removed:h};p.ageMs!==void 0&&(l.ageMs=p.ageMs),t(l)};return this.sse.on("event",r),this.sse.connect().catch(()=>{}),this.sse.subscribe([e]).catch(()=>{}),()=>{this.sse.off("event",r)}}};var He="mero-js:token-refresh";function Ne(){let e=globalThis.navigator?.locks;return e&&typeof e.request=="function"?e:null}function ee(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 K=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=T({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=ce(this.httpClient,{baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||"",timeoutMs:this.config.timeoutMs}),this.adminClient=he(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 G({httpClient:this.httpClient})),this.rpcClient}get events(){return this.sseClient||(this.sseClient=new D({baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||""})),this.sseClient}get ephemeral(){return this.ephemeralClient||(this.ephemeralClient=new U({httpClient:this.httpClient,sse:this.events})),this.ephemeralClient}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 P({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),i=r.data.access_token;return this.tokenData={access_token:i,refresh_token:r.data.refresh_token,expires_at:ee(i,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=Ne();return t?t.request(He,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:ee(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||ee(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 X(e)}static buildAuthLoginUrl(e,t){return Y(e,t)}};function $e(s){return new K(s)}var te=class{constructor(){this.tokens=null}getTokens(){return this.tokens}setTokens(e){this.tokens=e}clear(){this.tokens=null}},_e="mero-tokens",ne=class{constructor(e=_e){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 se=class{constructor(e={}){this.baseUrl=(e.cloudBaseUrl||"https://cloud.calimero.network").replace(/\/+$/,"")}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()}`)}};var ge=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,112,4,34,4,32]);function S(s){let e=new Uint8Array(4);return new DataView(e.buffer).setUint32(0,s,!0),e}function x(s){return Array.from(s,e=>e.toString(16).padStart(2,"0")).join("")}function g(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 i=0;i<t;i+=1)r[i]=Number.parseInt(n.slice(i*2,i*2+2),16);return r}function H(s){let e=new Uint8Array(8);return new DataView(e.buffer).setBigUint64(0,BigInt(s),!0),e}function b(...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 R(s,e){let t=[H(s.length),s];for(let n of e)t.push(H(n.length),n);return new Uint8Array(await crypto.subtle.digest("SHA-256",b(...t)))}async function V(s){let e=g(s,"deviceSecret",32),t=b(ge,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 N(s){let e=g(s,"deviceSecret",32),t=b(ge,e),n=await crypto.subtle.importKey("pkcs8",t,{name:"Ed25519"},!0,["sign"]),i=(await crypto.subtle.exportKey("jwk",n)).x;return Uint8Array.from(atob(i.replace(/-/g,"+").replace(/_/g,"/")),a=>a.charCodeAt(0))}var qe=new TextEncoder().encode("calimero.warrant.v1"),Le=new TextEncoder().encode("calimero.warrant.intent.v1");async function re(s,e){let t=new TextEncoder().encode(JSON.stringify(e));return R(Le,[new TextEncoder().encode(s),t])}async function fe(s){let e=g(s.context,"context",32),t=g(s.authorAccount,"authorAccount",32),n=g(s.executor,"executor",32),r=await V(s.deviceSecret),i=await N(s.deviceSecret),a=await re(s.method,s.argsJson),p=H(s.nonce),h=H(s.notAfter),l=await R(qe,[e,t,i,n,a,p,h]),u=new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},r,l));return x(b(e,t,i,n,a,p,h,u))}var Oe=new TextEncoder().encode("calimero.device.cert.v1"),ye=new TextEncoder().encode("calimero.account.genesis.v1"),We=new TextEncoder().encode("calimero.device.id.v1"),ie=1;async function be(s,e){if(e.length!==16)throw new Error(`nonce must be 16 bytes, got ${e.length}`);let t=g(s,"account",32);return x(await R(We,[t,e]))}async function oe(s){return R(Oe,[g(s.account,"account",32),g(s.device,"device",32),g(s.signPublicKey,"signPublicKey",32),g(s.kemPublicKey,"kemPublicKey",32),S(s.keyEpoch),S(s.deviceEpoch)])}async function Ce(s){let e=await N(s.rootSecret),t=x(await R(ye,[b(new Uint8Array([ie]),e)])),n=0,r=await oe({account:t,device:s.device,signPublicKey:s.signPublicKey,kemPublicKey:s.kemPublicKey,keyEpoch:n,deviceEpoch:s.deviceEpoch}),i=await V(s.rootSecret),a=new Uint8Array(await crypto.subtle.sign("Ed25519",i,r)),p=b(new Uint8Array([ie]),e,S(0),g(t,"account",32),g(s.device,"device",32),g(s.signPublicKey,"signPublicKey",32),g(s.kemPublicKey,"kemPublicKey",32),S(n),S(s.deviceEpoch),a);return x(p)}async function Re(s){let e=await N(s);return x(await R(ye,[b(new Uint8Array([ie]),e)]))}var rn={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};function on(s,e){let t=e>>>0;return(s&t)>>>0===t}function an(s,e){return(s|e)>>>0}function pn(s,e){return(s&~e)>>>0}var we=[2428,2429,2528,2529],je="localhost",Ke=2e3;function ke(s){return`http://${je}:${s}`}function xe(s,e){let t=s.endsWith("/")?s:`${s}/`;return new URL(e,t).toString()}async function Ae(s,e={}){let{timeoutMs:t=Ke,signal:n}=e;if(n?.aborted)return!1;let r=new AbortController,i=()=>r.abort(),a=n;a&&a.addEventListener("abort",i,{once:!0});let p=setTimeout(()=>r.abort(),t);try{let h=xe(s,"admin-api/health"),l=await fetch(h,{method:"GET",signal:r.signal});if(!l.ok)return!1;try{let u=await l.json(),d=u?.data?.status!==void 0?u?.data?.status:u?.status;return d===void 0?!0:typeof d=="string"&&d.toLowerCase()==="alive"}catch{return!0}}catch{return!1}finally{clearTimeout(p),a&&a.removeEventListener("abort",i)}}async function Ve(s={}){let{ports:e=we,timeoutMs:t,signal:n}=s;return(await Promise.all(e.map(async i=>{let a=ke(i);return await Ae(a,{timeoutMs:t,signal:n})?a:null}))).filter(i=>i!==null)}export{k as AdminApiClient,w as AuthApiClient,v as AuthRevokedError,rn as CAPABILITIES,se as CloudClient,we as DEFAULT_LOCAL_NODE_PORTS,U as EphemeralClient,y as HTTPError,ne as LocalStorageTokenStore,te as MemoryTokenStore,K as MeroJs,G as RpcClient,O as RpcError,D as SseClient,E as WebHttpClient,P as WsClient,Re as accountForRoot,Y as buildAuthLoginUrl,J as combineSignals,Me as compareSemver,Rt as createAdminApiClient,he as createAdminApiClientFromHttpClient,lt as createAuthApiClient,ce as createAuthApiClientFromHttpClient,bt as createBrowserAdminApiClient,pt as createBrowserAuthApiClient,T as createBrowserHttpClient,z as createHttpClient,$e as createMeroJs,Ct as createNodeAdminApiClient,ct as createNodeAuthApiClient,q as createNodeHttpClient,Ee as createRetryableMethod,F as createTimeoutSignal,Q as createUniversalHttpClient,oe as deviceCertPayload,Ve as discoverLocalNodes,on as hasCap,re as intentHash,j as jsonCodec,ke as localNodeUrl,be as mintDeviceId,xe as nodeEndpoint,X as parseAuthCallback,Ae as probeNodeHealth,Ce as signDeviceCert,fe as signWarrant,an as withCap,L as withRetry,pn as withoutCap};
|
|
1
|
+
function B(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=i=>{n.abort(i.target.reason);for(let a of e)a.removeEventListener("abort",r)};for(let i of e){if(i.aborted)return AbortSignal.abort(i.reason);i.addEventListener("abort",r,{once:!0})}return n.signal}function F(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 _e=new Set(["token_reuse","token_revoked"]);function Ne(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,i,a){let c=Ne(a);super(c?`HTTP ${t} ${n}: ${c}`:`HTTP ${t} ${n}`);this.status=t;this.statusText=n;this.url=r;this.headers=i;this.bodyText=a;this.name="HTTPError"}toJSON(){return{status:this.status,statusText:this.statusText,url:this.url,headers:de(this.headers),bodyText:this.bodyText}}},D=class extends C{constructor(t,n,r,i,a,c){super(n,r,i,a,c);this.reason=t;this.name="AuthRevokedError";this.message=`Authentication revoked (${t}): HTTP ${n} ${r}`}};function de(s){let e={};return s.forEach((t,n)=>{e[n]=t}),e}var G=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:de(n.headers),status:n.status}}async request(e,t){return this.makeRequest(e,t)}async makeRequest(e,t,n=0,r){let a=this.buildUrl(e),c=r??Date.now(),g=this.createAbortSignal(t),p=await this.buildHeaders(t?.headers),u;p instanceof Headers?(u={},p.forEach((l,P)=>{u[P]=l})):u=p;let h={method:t?.method||"GET",headers:u},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 y;if(n>0&&r!==void 0){let l=t?.timeoutMs||this.transport.timeoutMs;if(l){let P=Date.now()-c,U=Math.max(0,l-P);y=this.createAbortSignal({...t,timeoutMs:U})}else y=this.createAbortSignal(t)}else y=g;y&&(h.signal=y),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 l=await this.transport.fetch(a,h);if(!l.ok){let P=await this.getBodyText(l),U=new C(l.status,l.statusText,a,l.headers,P),$=l.headers.get("x-auth-error");if((l.status===401||l.status===403)&&$&&_e.has($)){if(this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,this.transport.onAuthRevoked)try{await this.transport.onAuthRevoked()}catch{}throw new D($,l.status,l.statusText,a,l.headers,P)}let Ue=t?.signal?.aborted===!0;if(l.status===401&&this.transport.refreshToken&&$==="token_expired"&&n<1&&!f&&!Ue)try{let w=this.refreshTokenPromise;w||(w=this.transport.refreshToken(),this.refreshTokenPromise=w);let V=await w;if(!V||V.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 q=this.onTokenRefreshPromise;q||(q=this.transport.onTokenRefresh(V),this.onTokenRefreshPromise=q),await q,this.refreshTokenPromise=null,this.onTokenRefreshPromise=null;let ue=t?.timeoutMs||this.transport.timeoutMs;if(ue&&r!==void 0){let Ge=Date.now()-c;if(ue-Ge<=0)throw U}return this.makeRequest(e,t,n+1,c)}catch(w){throw this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,w instanceof Error&&w.message.includes("onTokenRefresh")?w:U}throw U}return this.parseResponse(l,t?.parse)}catch(l){throw l instanceof C||l instanceof Error&&l.message.includes("onTokenRefresh")?l:new C(0,"Network Error",a,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(F(n)),t.length>0?B(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 z(s){return new G(s)}function S(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 z(e)}function L(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,i)=>globalThis.fetch(r,i):(r,i)=>e(r,i),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 z(n)}function Q(s){return typeof window<"u"?S(s):L(s)}function He(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 i=r.status;return i>=500||i===429}return n==="TypeError"}function $e(s){let t=250*Math.pow(2,s-1),n=(Math.random()-.5)*.4*t;return Math.max(0,t+n)}async function O(s,e={}){let{attempts:t=3}=e,n;for(let r=1;r<=t;r++)try{return await s(r)}catch(i){if(n=i,!He(n,t-r))throw n;let a=$e(r),p=n.headers?.get?.("Retry-After");if(p){let u=parseInt(p,10);if(!isNaN(u))a=Math.max(a,u*1e3);else{let h=new Date(p);if(!isNaN(h.getTime())){let f=Math.max(0,h.getTime()-Date.now());a=Math.max(a,Math.min(f,6e4))}}}await new Promise(u=>setTimeout(u,a))}throw n||new Error("Retry failed without error")}function qe(s,e={}){return async(...t)=>O(()=>s(...t),e)}var v=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 _=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 Ct(s){let e=new _;return new v(e)}function Rt(s){let e=new _;return new v(e)}function wt(s){let e=new _;return new v(e)}function he(s,e){return new v(s)}function o(s){return s?.data}function Le(s,e){let[t,n]=me(s),[r,i]=me(e),a=t.split("."),c=r.split("."),g=Math.max(a.length,c.length);for(let f=0;f<g;f++){let y=ge(a[f]??"0",c[f]??"0");if(y!==0)return y}if(n===void 0&&i===void 0)return 0;if(n===void 0)return 1;if(i===void 0)return-1;let p=n.split("."),u=i.split("."),h=Math.max(p.length,u.length);for(let f=0;f<h;f++){if(f>=p.length)return-1;if(f>=u.length)return 1;let y=ge(p[f],u[f]);if(y!==0)return y}return 0}function me(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 ge(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 fe(s,e,t){return O(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 x=class{constructor(e){this.httpClient=e}async healthCheck(){return o(await this.httpClient.get("/admin-api/health"))}async isAuthed(){return this.httpClient.get("/admin-api/is-authed")}async installApplication(e){return o(await this.httpClient.post("/admin-api/install-application",e))}async installFromRegistry(e,t,n){let r=new URL(e).origin,i=new URL(`/api/v2/bundles/${encodeURIComponent(t)}/${encodeURIComponent(n)}`,r).toString(),c=await(await fe(i,"manifest",`${t}@${n}`)).json(),g=encodeURIComponent(c.package),p=encodeURIComponent(c.appVersion),u=`${r}/artifacts/${g}/${p}/${g}-${p}.mpk`;return this.installApplication({url:u,package:c.package,version:c.appVersion,metadata:[]})}async getRegistryVersions(e,t){let n=new URL("/api/v2/bundles",new URL(e).origin);n.searchParams.set("package",t);let i=await(await fe(n.toString(),"versions",t)).json();return(Array.isArray(i)?i:[]).map(a=>a.appVersion).filter(a=>typeof a=="string").sort((a,c)=>Le(c,a))}async installDevApplication(e){return o(await this.httpClient.post("/admin-api/install-dev-application",e))}async uninstallApplication(e){return o(await this.httpClient.delete(`/admin-api/applications/${e}`))}async listApplications(){return o(await this.httpClient.get("/admin-api/applications"))}async getApplication(e){return o(await this.httpClient.get(`/admin-api/applications/${e}`))}async listApplicationVersions(e){return o(await this.httpClient.get(`/admin-api/applications/${e}/versions`))}async getApplicationAbi(e,t){let n=t?`?service_name=${encodeURIComponent(t)}`:"";return o(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 o(await this.httpClient.post("/admin-api/contexts",t))}async deleteContext(e,t){return o(t?await this.httpClient.request(`/admin-api/contexts/${e}`,{method:"DELETE",body:JSON.stringify(t),headers:{"Content-Type":"application/json"}}):await this.httpClient.delete(`/admin-api/contexts/${e}`))}async getContexts(){return o(await this.httpClient.get("/admin-api/contexts"))}async getContext(e){return o(await this.httpClient.get(`/admin-api/contexts/${e}`))}async getContextsForApplication(e){return o(await this.httpClient.get(`/admin-api/contexts/for-application/${e}`))}async generateContextIdentity(){return o(await this.httpClient.post("/admin-api/identity/context",{}))}async getContextIdentities(e){return o(await this.httpClient.get(`/admin-api/contexts/${e}/identities`))}async getContextIdentitiesOwned(e){return o(await this.httpClient.get(`/admin-api/contexts/${e}/identities-owned`))}async joinContext(e){return o(await this.httpClient.post(`/admin-api/contexts/${e}/join`,{}))}async getContextGroup(e){return o(await this.httpClient.get(`/admin-api/contexts/${e}/group`))}async getContextStorage(e){return o(await this.httpClient.get(`/admin-api/contexts/${e}/storage`))}async syncContext(e){await this.httpClient.post(`/admin-api/contexts/sync/${e??""}`,{})}async resyncContext(e,t={}){return await this.httpClient.post(`/admin-api/contexts/${e}/resync`,t)??{contextId:e,resyncStarted:!0}}async inviteSpecializedNode(e){return o(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",i=o(await this.httpClient.request(r,{method:"PUT",body:e.data,headers:{"Content-Type":"application/octet-stream"}}));return{blobId:i.blob_id,size:i.size}}async deleteBlob(e){let t=await this.httpClient.delete(`/admin-api/blobs/${e}`);return{blobId:t.blob_id,deleted:t.deleted}}async listBlobs(){return{blobs:o(await this.httpClient.get("/admin-api/blobs")).blobs.map(t=>({blobId:t.blob_id,size:t.size}))}}async getBlob(e){return this.httpClient.get(`/admin-api/blobs/${e}`,{parse:"arrayBuffer"})}async getBlobInfo(e){let{headers:t}=await this.httpClient.head(`/admin-api/blobs/${e}`),n=Number(t["content-length"]);return{blobId:t["x-blob-id"]??e,size:Number.isFinite(n)?n:0,hash:t["x-blob-hash"],mimeType:t["x-blob-mime-type"]}}async createContextAlias(e){return o(await this.httpClient.post("/admin-api/alias/create/context",{alias:e.alias,contextId:e.contextId}))}async createApplicationAlias(e){return o(await this.httpClient.post("/admin-api/alias/create/application",{alias:e.alias,applicationId:e.applicationId}))}async lookupContextAlias(e){return o(await this.httpClient.post(`/admin-api/alias/lookup/context/${encodeURIComponent(e)}`,{}))}async lookupApplicationAlias(e){return o(await this.httpClient.post(`/admin-api/alias/lookup/application/${encodeURIComponent(e)}`,{}))}async deleteContextAlias(e){return o(await this.httpClient.post(`/admin-api/alias/delete/context/${encodeURIComponent(e)}`,{}))}async deleteApplicationAlias(e){return o(await this.httpClient.post(`/admin-api/alias/delete/application/${encodeURIComponent(e)}`,{}))}async listContextAliases(){return o(await this.httpClient.get("/admin-api/alias/list/context"))}async listApplicationAliases(){return o(await this.httpClient.get("/admin-api/alias/list/application"))}async listNamespaces(){return o(await this.httpClient.get("/admin-api/namespaces"))}async getNamespace(e){return o(await this.httpClient.get(`/admin-api/namespaces/${e}`))}async getNodeIdentity(){return o(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 o(await this.httpClient.post(`/admin-api/contexts/${e}/intents`,t))}async listNamespacesForApplication(e){return o(await this.httpClient.get(`/admin-api/namespaces/for-application/${e}`))}async createNamespace(e){return o(await this.httpClient.post("/admin-api/namespaces",{upgradePolicy:"LazyOnAccess",...e}))}async deleteNamespace(e,t){return o(await this.httpClient.request(`/admin-api/namespaces/${e}`,{method:"DELETE",body:JSON.stringify(t??{}),headers:{"Content-Type":"application/json"}}))}async createNamespaceInvitation(e,t){return o(await this.httpClient.post(`/admin-api/namespaces/${e}/invite`,t??{}))}async admitJoin(e,t){return o(await this.httpClient.post(`/admin-api/namespaces/${e}/admit`,t,{timeoutMs:65e3}))}async joinNamespace(e,t){let n=o(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 o(await this.httpClient.post(`/admin-api/namespaces/${e}/groups`,t??{}))}async listNamespaceGroups(e){return o(await this.httpClient.get(`/admin-api/namespaces/${e}/groups`))}async getGroupInfo(e){return o(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,t){return o(await this.httpClient.request(`/admin-api/groups/${e}`,{method:"DELETE",body:JSON.stringify(t??{}),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 o(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 o(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,t){return o(await this.httpClient.post(`/admin-api/groups/${e}/sync`,t??{}))}async upgradeGroup(e,t){return o(await this.httpClient.post(`/admin-api/groups/${e}/upgrade`,t))}async getGroupUpgradeStatus(e){return o(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 o(await this.httpClient.get(`/admin-api/groups/${t}/cascade-status`))}async retryGroupUpgrade(e,t){return o(await this.httpClient.post(`/admin-api/groups/${e}/upgrade/retry`,t??{}))}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,n){await this.httpClient.post(`/admin-api/groups/${e}/contexts/${t}/remove`,n??{})}async createGroupInvitation(e,t){return o(await this.httpClient.post(`/admin-api/groups/${e}/invite`,t??{}))}async joinGroup(e){return o(await this.httpClient.post("/admin-api/groups/join",e))}async joinSubgroupInheritance(e){return o(await this.httpClient.post(`/admin-api/groups/${e}/join-via-inheritance`,{}))}async getTeeInfo(){return o(await this.httpClient.get("/admin-api/tee/info"))}async teeAttest(e){return o(await this.httpClient.post("/admin-api/tee/attest",e))}async teeVerifyQuote(e){return o(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 o(await this.httpClient.post("/admin-api/groups",{upgradePolicy:"LazyOnAccess",...e}))}async leaveGroup(e,t){await this.httpClient.post(`/admin-api/groups/${e}/leave`,t??{})}async leaveContext(e,t){await this.httpClient.post(`/admin-api/contexts/${e}/leave`,t??{})}async leaveNamespace(e,t){await this.httpClient.post(`/admin-api/namespaces/${e}/leave`,t??{})}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,t){return this.httpClient.post(`/admin-api/groups/${e}/migration/abort`,t??{})}};function St(s){return new x(S(s))}function Et(s){return new x(L(s))}function It(s){return new x(Q(s))}function ye(s,e){return new x(s)}function X(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 Y(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 W=class extends Error{constructor(e,t,n,r){super(t),this.name="RpcError",this.code=e,this.data=n,this.type=r}};async function Z(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 W(r.code??-1,r.message??r.type??"RPC error",r.data,r.type)}return n.result}var N=class{constructor(e){this.httpClient=e.httpClient}async execute(e){let t=await Z(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 Oe=new Set(["MigrationStarted","MigrationProgress","CascadeProgress","MigrationCompleted"]);function be(s){return s.type!==void 0&&Oe.has(s.type)}var We=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],i=r.indexOf(t);i!==-1&&r.splice(i,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=>{be(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"),i=await n.text().catch(()=>{});throw n.status===401&&r&&We.has(r)?new D(r,n.status,n.statusText,t,n.headers,i):new C(n.status,n.statusText,t,n.headers,i)}if(!n.body)throw new Error("SSE response has no body");this.readStream(n.body).catch(r=>{if(this.closed)return;let i=r instanceof Error?r:new Error(String(r));this.emit("error",i),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:i,value:a}=await t.read();if(i)break;r+=n.decode(a,{stream:!0});let c=r.split(`
|
|
2
|
+
`);r=c.pop()??"";for(let g of c)if(g.startsWith("data:")){let p=g.slice(5).trim();p&&this.handleMessage(p)}}if(r+=n.decode(),r.startsWith("data:")){let i=r.slice(5).trim();i&&this.handleMessage(i)}}catch(i){if(this.closed)return;let a=i instanceof Error?i:new Error(String(i));this.emit("error",a)}this.closed||this.scheduleReconnect()}handleMessage(e){try{let t=JSON.parse(e);if(t.type==="connect"&&t.session_id){this.sessionId=t.session_id,this.emit("connect",t.session_id),(this.subscribedContextIds.size>0||this.subscribedGroupIds.size>0)&&this.sendSubscription("subscribe",{contextIds:[...this.subscribedContextIds],groupIds:[...this.subscribedGroupIds]});return}if(!t.result)return;let n=t.result.data;if(Array.isArray(n))try{let r=new Uint8Array(n),i=new TextDecoder().decode(r);n=JSON.parse(i)}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(i=>!this.subscribedContextIds.has(i)),r=(t.groupIds??[]).filter(i=>!this.subscribedGroupIds.has(i));for(let i of t.contextIds??[])this.subscribedContextIds.add(i);for(let i of t.groupIds??[])this.subscribedGroupIds.add(i);(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(i=>this.subscribedContextIds.has(i)),r=(t.groupIds??[]).filter(i=>this.subscribedGroupIds.has(i));for(let i of t.contextIds??[])this.subscribedContextIds.delete(i);for(let i of t.groupIds??[])this.subscribedGroupIds.delete(i);(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 i=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})});i.ok||this.emit("error",new Error(`SSE ${e} failed: ${i.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],i=r.indexOf(t);i!==-1&&r.splice(i,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),i=new TextDecoder().decode(r);n=JSON.parse(i)}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 I=j;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 H=class{constructor(e){this.httpClient=e.httpClient,this.sse=e.sse}async set(e,t,n=J()){await Z(this.httpClient,"set_ephemeral",{contextId:e,state:n.encode(t)})}subscribe(e,t,n=J()){let r=i=>{let a=i;if(a.type!=="Ephemeral"||a.contextId!==e)return;let c=a.data;if(!c?.author)return;let g=!!c.removed,p={author:c.author,state:g||c.state===void 0?void 0:n.decode(c.state),removed:g};c.ageMs!==void 0&&(p.ageMs=c.ageMs),t(p)};return this.sse.on("event",r),this.sse.connect().catch(()=>{}),this.sse.subscribe([e]).catch(()=>{}),()=>{this.sse.off("event",r)}}};var je="mero-js:token-refresh";function Je(){let e=globalThis.navigator?.locks;return e&&typeof e.request=="function"?e:null}function ee(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 K=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=S({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=he(this.httpClient,{baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||"",timeoutMs:this.config.timeoutMs}),this.adminClient=ye(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 N({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 H({httpClient:this.httpClient,sse:this.events})),this.ephemeralClient}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 I({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),i=r.data.access_token;return this.tokenData={access_token:i,refresh_token:r.data.refresh_token,expires_at:ee(i,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=Je();return t?t.request(je,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:ee(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||ee(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 X(e)}static buildAuthLoginUrl(e,t){return Y(e,t)}};function Ke(s){return new K(s)}var te=class{constructor(){this.tokens=null}getTokens(){return this.tokens}setTokens(e){this.tokens=e}clear(){this.tokens=null}},Ve="mero-tokens",ne=class{constructor(e=Ve){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 se=class{constructor(e={}){this.baseUrl=(e.cloudBaseUrl||"https://cloud.calimero.network").replace(/\/+$/,"")}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()}`)}};var Ce=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,112,4,34,4,32]);function b(s){let e=new Uint8Array(4);return new DataView(e.buffer).setUint32(0,s,!0),e}function R(s){return Array.from(s,e=>e.toString(16).padStart(2,"0")).join("")}function d(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 i=0;i<t;i+=1)r[i]=Number.parseInt(n.slice(i*2,i*2+2),16);return r}function A(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 k(s,e){let t=[A(s.length),s];for(let n of e)t.push(A(n.length),n);return new Uint8Array(await crypto.subtle.digest("SHA-256",m(...t)))}async function M(s){let e=d(s,"deviceSecret",32),t=m(Ce,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 T(s){let e=d(s,"deviceSecret",32),t=m(Ce,e),n=await crypto.subtle.importKey("pkcs8",t,{name:"Ed25519"},!0,["sign"]),i=(await crypto.subtle.exportKey("jwk",n)).x;return Uint8Array.from(atob(i.replace(/-/g,"+").replace(/_/g,"/")),a=>a.charCodeAt(0))}var Be=new TextEncoder().encode("calimero.warrant.v1"),Fe=new TextEncoder().encode("calimero.warrant.intent.v1");async function re(s,e){let t=new TextEncoder().encode(JSON.stringify(e));return k(Fe,[new TextEncoder().encode(s),t])}async function Re(s){let e=d(s.context,"context",32),t=d(s.authorAccount,"authorAccount",32),n=d(s.executor,"executor",32),r=await M(s.deviceSecret),i=await T(s.deviceSecret),a=await re(s.method,s.argsJson),c=A(s.nonce),g=A(s.notAfter),p=await k(Be,[e,t,i,n,a,c,g]),u=new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},r,p));return R(m(e,t,i,n,a,c,g,u))}var ze=new TextEncoder().encode("calimero.device.cert.v1"),we=new TextEncoder().encode("calimero.account.genesis.v1"),Qe=new TextEncoder().encode("calimero.device.id.v1"),ie=1;async function Ae(s,e){if(e.length!==16)throw new Error(`nonce must be 16 bytes, got ${e.length}`);let t=d(s,"account",32);return R(await k(Qe,[t,e]))}async function oe(s){return k(ze,[d(s.account,"account",32),d(s.device,"device",32),d(s.signPublicKey,"signPublicKey",32),d(s.kemPublicKey,"kemPublicKey",32),b(s.keyEpoch),b(s.deviceEpoch)])}function ke(s){return m(new Uint8Array([ie]),s.rootPublicKey,b(0),d(s.account,"account",32),d(s.device,"device",32),d(s.signPublicKey,"signPublicKey",32),d(s.kemPublicKey,"kemPublicKey",32),b(s.keyEpoch),b(s.deviceEpoch),s.signature)}async function ve(s){let e=await T(s.rootSecret),t=R(await k(we,[m(new Uint8Array([ie]),e)])),n=0,r=await oe({account:t,device:s.device,signPublicKey:s.signPublicKey,kemPublicKey:s.kemPublicKey,keyEpoch:n,deviceEpoch:s.deviceEpoch}),i=await M(s.rootSecret),a=new Uint8Array(await crypto.subtle.sign("Ed25519",i,r)),c=ke({rootPublicKey:e,account:t,device:s.device,signPublicKey:s.signPublicKey,kemPublicKey:s.kemPublicKey,keyEpoch:n,deviceEpoch:s.deviceEpoch,signature:a});return R(c)}async function xe(s){let e=await T(s);return R(await k(we,[m(new Uint8Array([ie]),e)]))}var pe=7,Xe=new TextEncoder().encode("calimero.namespace.v1"),Ye=0,Te={GroupCreated:0,GroupReparented:1,GroupDeleted:2,AdminChanged:3,PolicyUpdated:4,MemberJoined:5,KeyDelivery:6,MemberJoinedOpen:7,MemberJoinedAt:8,NamespaceCreated:9,MemberJoinedViaTeeAttestation:10};function ae(s,e){if(s.length!==32)throw new Error(`${e} must be 32 bytes, got ${s.length}`);return new Uint8Array(s)}function Pe(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 ce(s){let e=new TextEncoder().encode(s);return m(b(e.length),e)}function Ze(s){return"multiaddr"in s?m(new Uint8Array([0]),ce(s.multiaddr)):m(new Uint8Array([1]),ce(s.url))}function le(s){let e=s.invitation,t=e.admitters??[],n=s.admitter_hints??[];return m(ae(e.inviter_identity,"inviter_identity"),ae(e.group_id,"group_id"),A(e.expiration_timestamp),ae(e.secret_salt,"secret_salt"),new Uint8Array([e.invited_role]),b(t.length),...t.map((r,i)=>d(r,`admitters[${i}]`,32)),ce(s.inviter_signature),s.inviter_account?m(new Uint8Array([1]),d(s.inviter_account,"inviter_account",32)):new Uint8Array([0]),b(n.length),...n.map(Ze),Pe(s.application_id,"application_id"),Pe(s.app_key,"app_key"))}async function De(s){let e=s.parentOpHashes??[],t=d(s.credential,"credential",s.credential.length/2),n=m(new Uint8Array([s.at?Te.MemberJoinedAt:Te.MemberJoined]),d(s.member,"member",32),le(s.invitation),t),r=m(new Uint8Array([Ye]),n),i=await M(s.deviceSecret),a=await T(s.deviceSecret),c=m(new Uint8Array([pe]),d(s.namespaceId,"namespaceId",32),b(e.length),...e.map((p,u)=>d(p,`parentOpHashes[${u}]`,32)),a,A(s.nonce),r),g=new Uint8Array(await crypto.subtle.sign("Ed25519",i,m(Xe,c)));return R(m(c,g))}var Rn={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};function wn(s,e){let t=e>>>0;return(s&t)>>>0===t}function An(s,e){return(s|e)>>>0}function kn(s,e){return(s&~e)>>>0}var Se=[2428,2429,2528,2529],et="localhost",tt=2e3;function Ee(s){return`http://${et}:${s}`}function Ie(s,e){let t=s.endsWith("/")?s:`${s}/`;return new URL(e,t).toString()}async function Me(s,e={}){let{timeoutMs:t=tt,signal:n}=e;if(n?.aborted)return!1;let r=new AbortController,i=()=>r.abort(),a=n;a&&a.addEventListener("abort",i,{once:!0});let c=setTimeout(()=>r.abort(),t);try{let g=Ie(s,"admin-api/health"),p=await fetch(g,{method:"GET",signal:r.signal});if(!p.ok)return!1;try{let u=await p.json(),h=u?.data?.status!==void 0?u?.data?.status:u?.status;return h===void 0?!0:typeof h=="string"&&h.toLowerCase()==="alive"}catch{return!0}}catch{return!1}finally{clearTimeout(c),a&&a.removeEventListener("abort",i)}}async function nt(s={}){let{ports:e=Se,timeoutMs:t,signal:n}=s;return(await Promise.all(e.map(async i=>{let a=Ee(i);return await Me(a,{timeoutMs:t,signal:n})?a:null}))).filter(i=>i!==null)}export{x as AdminApiClient,v as AuthApiClient,D as AuthRevokedError,Rn as CAPABILITIES,se as CloudClient,Se as DEFAULT_LOCAL_NODE_PORTS,H as EphemeralClient,C as HTTPError,ne as LocalStorageTokenStore,te as MemoryTokenStore,K as MeroJs,N as RpcClient,W as RpcError,pe as SIGNED_NAMESPACE_OP_SCHEMA_VERSION,E as SseClient,G as WebHttpClient,I as WsClient,xe as accountForRoot,Y as buildAuthLoginUrl,B as combineSignals,Le as compareSemver,It as createAdminApiClient,ye as createAdminApiClientFromHttpClient,wt as createAuthApiClient,he as createAuthApiClientFromHttpClient,St as createBrowserAdminApiClient,Ct as createBrowserAuthApiClient,S as createBrowserHttpClient,z as createHttpClient,Ke as createMeroJs,Et as createNodeAdminApiClient,Rt as createNodeAuthApiClient,L as createNodeHttpClient,qe as createRetryableMethod,F as createTimeoutSignal,Q as createUniversalHttpClient,oe as deviceCertPayload,nt as discoverLocalNodes,le as encodeSignedInvitation,wn as hasCap,re as intentHash,J as jsonCodec,Ee as localNodeUrl,Ae as mintDeviceId,Ie as nodeEndpoint,X as parseAuthCallback,Me as probeNodeHealth,ve as signDeviceCert,De as signMemberJoinOp,Re as signWarrant,An as withCap,O as withRetry,kn as withoutCap};
|
|
3
3
|
//# sourceMappingURL=index.browser.mjs.map
|