@calimero-network/mero-js 29.11.0 → 29.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -101,10 +101,10 @@ Pinned measurements go through `policy.verifyQuote` (`createQuoteVerifier`).
101
101
  - **Account recovery** (core #4844): `createRecoveryCode`, `removeRecoveryCode` (passkey-approved; the code is shown once), then signed out `startAccountRecovery(code, passkey)` and, 72 hours later, `finishAccountRecovery(passkey, accountId?)`; a passkey the account still has cancels in between (`cancelAccountRecovery`; `me()` shows `recoveryCode` and `recoveryPending`).
102
102
  - **Package origins**: `packageOrigins.list`, `packageOrigins.add`, `packageOrigins.remove`. A package's managers register the web origins of a frontend they host themselves (approved with a passkey); `signUp` and `signIn` on such a page send its origin, sign for that origin's relying-party id, and open a session bound to the package (`me()` answers its `app` and `origin`). An unregistered origin is refused with `OriginNotRegistered`. `packageOrigins.add(pkg, origin, passkey, { served: true })` registers a custom domain: the cluster also serves the package's frontend there from its signed bundle (`https://host`, no port; the passkey's consent names `served: true`); `list` answers `served` on each origin, and the extra refusals are `NotServing` (the cluster serves no frontends), `ClusterNotUpgraded` (a node is on an older release), `QuotaExceeded` (4 served per package, 64 per cluster) and `OriginTaken` (held with the other `served`).
103
103
  - **Packages**: `installPackage`, `uploadPackage`, `packages`, `package`, `uninstallPackage`; `uploadBundle` (raw WASM, development clusters only).
104
- - **Apps**: `createApp`, `listApps`, `getApp`, `deleteApp`, `setAccess`, `setAppMetadata`, `appStorage`, `appAbi`, `upgradeApp`, `transferApp`.
104
+ - **Apps**: `createApp`, `listApps`, `getApp`, `deleteApp`, `setAccess`, `setAppMetadata`, `appStorage`, `appAbi`, `upgradeApp`, `transferApp`, `moveApp`.
105
105
  - **Calls**: `call`, `callConfirmed`, `view`, `events`. A call always carries an idempotency key, and is sent again with it while the node answers `503`, then to the next node.
106
106
  - **Blobs and presence**: `uploadBlob`, `downloadBlob`, `listBlobs`, `blobInfo`, `deleteBlob`; `publishPresence`, `presence`, `presenceStream`.
107
- - **Organizations**: `createOrg`, `getOrg`, `deleteOrg`, `setOrgMetadata`, `setMember`, `removeMember`, `setMemberMetadata`, `setCapabilities` (`ORG_CAPABILITIES`), `setTeamDefaultCapabilities`, teams, app teams (`listAppTeams`, `scopeApps`), `invite`, `redeemInvite`, `listInvites`, `revokeInvite`, recovery (`setRecoveryKey`, `startRecovery`, `cancelRecovery`, `finishRecovery`; `newRecoverySeed`, `recoveryPublicKey`). Setting or removing a member or team member, capabilities, invites (minting and revoking) and scoping apps are approved with the caller's passkey; redeeming an invite is not.
107
+ - **Organizations**: `createOrg`, `getOrg`, `orgMembersSecurity` (owners and admins: each member's passkey count to `3+`, recovery code set, last active day, live sessions), `deleteOrg`, `setOrgMetadata`, `setMember`, `removeMember`, `setMemberMetadata`, `setCapabilities` (`ORG_CAPABILITIES`), `setTeamDefaultCapabilities`, teams, app teams (`listAppTeams`, `scopeApps`), `invite`, `redeemInvite`, `listInvites`, `revokeInvite`, recovery (`setRecoveryKey`, `startRecovery`, `cancelRecovery`, `finishRecovery`; `newRecoverySeed`, `recoveryPublicKey`). Setting or removing a member or team member, capabilities, invites (minting and revoking) and scoping apps are approved with the caller's passkey; redeeming an invite is not.
108
108
  - **Owner decisions** (passkey approval, never from an app's frontend): `upgradeOrg`, `upgradeRun`, `retryUpgradeRun`, `approveRelease`, `approveOutbound`, `bindPublisher`, `upgradePublished`.
109
109
  - **Approvals from an app**: `appsReport`, `releaseRules`, `pendingApprovals`, then `requestConsent` / `openConsentPage` to send the user to the node's consent page, and `consentResult`. Show the answer's `code` to the user before sending them to `url` (`openConsentPage`'s `confirm` hook); they should see the same code on the page (`confirmationCode(requestId)` checks it). See [Ask your users to approve node images and app upgrades](https://calimero-network.github.io/mero-js/guides/user-approvals/).
110
110
  - **Operator** (ops token): `opsApps`, `opsOrgs`, `opsServedOrigins` (every custom domain the log holds, by package label), `setReleaseDeadline`, `liftReleaseDeadline`.
@@ -64,6 +64,22 @@ export interface PackageInfo {
64
64
  }>;
65
65
  }
66
66
  /** One app instance as `listApps` answers it. */
67
+ /** What {@link CalimeroClient.moveApp} answers. */
68
+ export interface MoveAppResult {
69
+ appId: string;
70
+ /** The organization it left; `null` for a personal app. */
71
+ from: string | null;
72
+ /** The organization it is in now. */
73
+ org: string;
74
+ /** Its access there: `{ kind: 'team', team }` on the target's app team, or as it was. */
75
+ access: Record<string, unknown>;
76
+ /** Whether the target's app team of its package was made for it. */
77
+ created: boolean;
78
+ /** The accounts that joined the target with it (`bringMembers`). */
79
+ added: string[];
80
+ /** The source's invites into the team it left that were revoked. */
81
+ revokedInvites: number;
82
+ }
67
83
  export interface AppInfo {
68
84
  appId: string;
69
85
  name: string;
@@ -386,6 +402,10 @@ export interface DeploymentOrgs {
386
402
  }>;
387
403
  /** RFC 3339: when its first instance from the deployment was created. */
388
404
  firstCreatedAt: string;
405
+ /** How many members it has (counts only, never who; core #4902). Absent from an older node. */
406
+ memberCount?: number;
407
+ /** How many of them signed in or used a session in the last 30 days (core #4902). Absent from an older node. */
408
+ activeMembers30d?: number;
389
409
  }>;
390
410
  /** Instances outside any organization, counted only. */
391
411
  outsideOrgs: number;
@@ -405,6 +425,27 @@ export interface FrontendManifest {
405
425
  }>;
406
426
  api: string[];
407
427
  }
428
+ /**
429
+ * One member's lockout risk, as {@link CalimeroClient.orgMembersSecurity}
430
+ * lists it for an organization's owner and admins (core #4902). Never a
431
+ * credential id, a passkey's label or times, a session or an activity entry.
432
+ */
433
+ export interface OrgMemberSecurity {
434
+ account: string;
435
+ /** The member's self-set name (`memberMetadata.name`); `null` when unset. */
436
+ name: string | null;
437
+ role: 'guest' | 'member' | 'admin' | 'owner';
438
+ /** The teams they are in. */
439
+ teams: string[];
440
+ /** How many passkeys they hold, capped: whether they have a backup, not how many devices. */
441
+ passkeys: 0 | 1 | 2 | '3+';
442
+ /** Whether a recovery code is set. */
443
+ recoveryCode: boolean;
444
+ /** The UTC day (`YYYY-MM-DD`) of their latest sign-in or session exchange; `null` when unknown. */
445
+ lastActiveDay: string | null;
446
+ /** How many live sessions they hold. */
447
+ sessions: number;
448
+ }
408
449
  /**
409
450
  * Read the `/.well-known/calimero.json` of the frontend at `origin` (by
410
451
  * default the page's own). Served in the clear by the frontend host, like the
@@ -1075,6 +1116,20 @@ export declare class CalimeroClient {
1075
1116
  * too, so an organization can hand on an app whose owner left (core #4893).
1076
1117
  */
1077
1118
  transferApp(app: string, to: string, passkey: PasskeyProvider): Promise<void>;
1119
+ /**
1120
+ * Move an app instance to another organization (`toOrg`), its data where it
1121
+ * is (core `POST /apps/{app}/move`), approved with `passkey`. Whoever
1122
+ * manages the app now (its owner while a member of its organization, an
1123
+ * admin there, or a personal app's owner) moves it, as an admin or the
1124
+ * owner of `toOrg`. Its files, runs and quotas go to the target; `org` or
1125
+ * app-team access becomes the target's app team of its package.
1126
+ * `bringMembers` adds the people of its organization who reach it to the
1127
+ * target (capped at `member`). A node from before the route answers `404`
1128
+ * ({@link NotFound}): the feature is not there yet.
1129
+ */
1130
+ moveApp(app: string, toOrg: string, options?: {
1131
+ bringMembers?: boolean;
1132
+ }, passkey?: PasskeyProvider): Promise<MoveAppResult>;
1078
1133
  /**
1079
1134
  * Move an app to another release of its package (`{ version }`), another
1080
1135
  * package, or a bundle hash, running its migration. Answers the upgrade's
@@ -1212,6 +1267,16 @@ export declare class CalimeroClient {
1212
1267
  }>;
1213
1268
  /** The organization, with the teams this caller reaches or manages. */
1214
1269
  getOrg(org: string): Promise<OrgInfo>;
1270
+ /**
1271
+ * Each member's lockout risk (`GET /orgs/{org}/members?detail=security`),
1272
+ * for the organization's owner and admins: name, role, teams, passkeys held
1273
+ * (to `'3+'`), recovery code set, last active UTC day and live sessions.
1274
+ * A member below admin is refused (`403 FORBIDDEN`), someone outside the
1275
+ * organization gets {@link NotFound}; the admin's own session on the
1276
+ * cluster's origin only, never an API key or a package-bound session. A
1277
+ * node before core #4902 has no such route (a bare `404`).
1278
+ */
1279
+ orgMembersSecurity(org: string): Promise<OrgMemberSecurity[]>;
1215
1280
  /**
1216
1281
  * Delete an organization with its teams, invites and apps (its owner only).
1217
1282
  * The node asks for the owner's passkey (`412 CONFIRM_REQUIRED`), which `passkey` gives.
@@ -1518,8 +1583,9 @@ export declare class CalimeroClient {
1518
1583
  withdrawApp(id: string, app: string, passkey: PasskeyProvider): Promise<void>;
1519
1584
  /**
1520
1585
  * The organizations with instances created from deployment `id`, for its
1521
- * managers: each one's id, name, instance count, apps and releases, and
1522
- * first instance. Never members, teams or app data.
1586
+ * managers: each one's id, name, instance count, apps and releases, first
1587
+ * instance, and (core #4902) how many members it has and how many were
1588
+ * active in 30 days. Never who the members are, teams or app data.
1523
1589
  */
1524
1590
  deploymentOrgs(id: string): Promise<DeploymentOrgs>;
1525
1591
  }
@@ -940,6 +940,22 @@ export class CalimeroClient {
940
940
  async transferApp(app, to, passkey) {
941
941
  await this.postConfirmed(`apps/${seg(app)}/transfer`, { to }, passkey);
942
942
  }
943
+ /**
944
+ * Move an app instance to another organization (`toOrg`), its data where it
945
+ * is (core `POST /apps/{app}/move`), approved with `passkey`. Whoever
946
+ * manages the app now (its owner while a member of its organization, an
947
+ * admin there, or a personal app's owner) moves it, as an admin or the
948
+ * owner of `toOrg`. Its files, runs and quotas go to the target; `org` or
949
+ * app-team access becomes the target's app team of its package.
950
+ * `bringMembers` adds the people of its organization who reach it to the
951
+ * target (capped at `member`). A node from before the route answers `404`
952
+ * ({@link NotFound}): the feature is not there yet.
953
+ */
954
+ moveApp(app, toOrg, options = {}, passkey) {
955
+ const path = `apps/${seg(app)}/move`;
956
+ const body = { toOrg, bringMembers: options.bringMembers ?? false };
957
+ return passkey ? this.postConfirmed(path, body, passkey) : this.post(path, body);
958
+ }
943
959
  /**
944
960
  * Move an app to another release of its package (`{ version }`), another
945
961
  * package, or a bundle hash, running its migration. Answers the upgrade's
@@ -1145,6 +1161,19 @@ export class CalimeroClient {
1145
1161
  getOrg(org) {
1146
1162
  return this.get(`orgs/${seg(org)}`);
1147
1163
  }
1164
+ /**
1165
+ * Each member's lockout risk (`GET /orgs/{org}/members?detail=security`),
1166
+ * for the organization's owner and admins: name, role, teams, passkeys held
1167
+ * (to `'3+'`), recovery code set, last active UTC day and live sessions.
1168
+ * A member below admin is refused (`403 FORBIDDEN`), someone outside the
1169
+ * organization gets {@link NotFound}; the admin's own session on the
1170
+ * cluster's origin only, never an API key or a package-bound session. A
1171
+ * node before core #4902 has no such route (a bare `404`).
1172
+ */
1173
+ async orgMembersSecurity(org) {
1174
+ const { members } = await this.get(`orgs/${seg(org)}/members?detail=security`);
1175
+ return members;
1176
+ }
1148
1177
  /**
1149
1178
  * Delete an organization with its teams, invites and apps (its owner only).
1150
1179
  * The node asks for the owner's passkey (`412 CONFIRM_REQUIRED`), which `passkey` gives.
@@ -1569,8 +1598,9 @@ export class CalimeroClient {
1569
1598
  }
1570
1599
  /**
1571
1600
  * The organizations with instances created from deployment `id`, for its
1572
- * managers: each one's id, name, instance count, apps and releases, and
1573
- * first instance. Never members, teams or app data.
1601
+ * managers: each one's id, name, instance count, apps and releases, first
1602
+ * instance, and (core #4902) how many members it has and how many were
1603
+ * active in 30 days. Never who the members are, teams or app data.
1574
1604
  */
1575
1605
  deploymentOrgs(id) {
1576
1606
  return this.get(`deployments/${seg(id)}/orgs`);
@@ -3,7 +3,7 @@ export { DEFAULT_DIRECTORY, DirectoryError } from './directory.js';
3
3
  export type { DirectoryFailure } from './directory.js';
4
4
  export { AppError, ArgsTooLarge, BadOrigin, CalimeroError, ClusterNotUpgraded, ConfirmCancelled, ConfirmPromptBlocked, ConfirmRequired, IdempotencyMismatch, LoginRequired, ConsentStale, NotFound, NotServing, OriginNotRegistered, OriginTaken, PasskeyUnknownHere, QuotaExceeded, RecoveryNotReady, ReleaseDeadlineError, SignUpRefused, TrapError, UnavailableError, WrongNode, WrongRecoveryCode, errorFrom, } from './errors.js';
5
5
  export type { Committed, SignUpRefusal } from './errors.js';
6
- export type { AppInfo, AppTeam, AppTeams, AppXcalls, BlobContent, BlobInfo, DeadLetter, Deployer, DeployerGrant, DeployersInfo, DeploymentInfo, DeploymentOffer, DeploymentOrgs, FrontendManifest, MeInfo, MeOrg, MePasskey, AccountSession, AccountActivity, PackageOrigin, PackageOriginAdded, PackageOriginRemoved, PackageOrigins, ServedOrigin, ServedOrigins, SignInOptions, AccountRecovery, SignUpOptions, SignUpPolicy, PublicDeployment, CallResult, CalimeroClientOptions, CalimeroConnectOptions, CloudEvent, CalimeroSession, PackageInfo, PackageInstalled, CloudRetryOptions, OrgInfo, OrgInvite, OrgMode, OrgRecovery, RecoveryTimes, OrgUpgradeTarget, PresenceEntry, ScopeApp, ScopeAppsOptions, ScopeAppsResult, ScopedAppTeam, TeamInfo, TeamMemberInfo, UpgradeRun, ViewResult, } from './client.js';
6
+ export type { AppInfo, AppTeam, AppTeams, AppXcalls, BlobContent, BlobInfo, DeadLetter, Deployer, DeployerGrant, DeployersInfo, DeploymentInfo, DeploymentOffer, DeploymentOrgs, OrgMemberSecurity, FrontendManifest, MeInfo, MeOrg, MePasskey, MoveAppResult, AccountSession, AccountActivity, PackageOrigin, PackageOriginAdded, PackageOriginRemoved, PackageOrigins, ServedOrigin, ServedOrigins, SignInOptions, AccountRecovery, SignUpOptions, SignUpPolicy, PublicDeployment, CallResult, CalimeroClientOptions, CalimeroConnectOptions, CloudEvent, CalimeroSession, PackageInfo, PackageInstalled, CloudRetryOptions, OrgInfo, OrgInvite, OrgMode, OrgRecovery, RecoveryTimes, OrgUpgradeTarget, PresenceEntry, ScopeApp, ScopeAppsOptions, ScopeAppsResult, ScopedAppTeam, TeamInfo, TeamMemberInfo, UpgradeRun, ViewResult, } from './client.js';
7
7
  export { claimedRelease, fetchAttestedKey, freshCollateral, MOCK_QUOTE_HEADER } from './attestation.js';
8
8
  export type { AttestationDoc, CloudPolicy, CloudReleasePolicy } from './attestation.js';
9
9
  export { browserPasskey, b64url, fromB64url } from './passkey.js';
@@ -1,9 +1,9 @@
1
- function R(r){return Array.from(r,e=>e.toString(16).padStart(2,"0")).join("")}function me(r,e,t){let n=r.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 i=new Uint8Array(t);for(let s=0;s<t;s+=1)i[s]=Number.parseInt(n.slice(s*2,s*2+2),16);return i}function h(...r){let e=new Uint8Array(r.reduce((n,i)=>n+i.length,0)),t=0;for(let n of r)e.set(n,t),t+=n.length;return e}var Lr="Noise_NK_25519_AESGCM_SHA256",Ye=32,Gr=16,Hr=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,110,4,34,4,32]),ze=class r{constructor(e){this.k=null;this.n=0;this.ck=e,this.h=e}static async initialize(){let e=new TextEncoder().encode(Lr),t=new Uint8Array(32);return t.set(e),new r(t)}async mixHash(e){this.h=await Fr(h(this.h,e))}async mixKey(e){let[t,n]=await Ct(this.ck,e);this.ck=t,this.k=await crypto.subtle.importKey("raw",n,"AES-GCM",!1,["encrypt","decrypt"]),this.n=0}async encryptAndHash(e){if(!this.k)throw new Error("Noise: no cipher key yet");let t=new Uint8Array(await crypto.subtle.encrypt({name:"AES-GCM",iv:St(this.n),additionalData:this.h},this.k,e));return this.n+=1,await this.mixHash(t),t}async decryptAndHash(e){if(!this.k)throw new Error("Noise: no cipher key yet");let t=new Uint8Array(await crypto.subtle.decrypt({name:"AES-GCM",iv:St(this.n),additionalData:this.h},this.k,e));return this.n+=1,await this.mixHash(e),t}split(){return Ct(this.ck,new Uint8Array)}};async function Ot(r,e,t){let n=await ze.initialize();await n.mixHash(e),await n.mixHash(r);let i=await q(t);return await n.mixHash(i.publicKey),await n.mixKey(await ee(i.privateKey,r)),{message1:h(i.publicKey,await n.encryptAndHash(new Uint8Array)),async finish(o){if(o.length<Ye+Gr)throw new Error("Noise: message 2 is too short");let a=o.slice(0,Ye);return await n.mixHash(a),await n.mixKey(await ee(i.privateKey,a)),{payload:await n.decryptAndHash(o.slice(Ye)),split:await n.split()}}}}async function q(r){if(!r){let n;try{n=await crypto.subtle.generateKey({name:"X25519"},!0,["deriveBits"])}catch(s){throw new Error(`Sealed transport needs WebCrypto with X25519, which this runtime lacks (${s?.name??"no crypto.subtle"}). Current browsers and Node have it; in React Native, install react-native-quick-crypto as the global crypto.`)}let i=new Uint8Array(await crypto.subtle.exportKey("raw",n.publicKey));return{privateKey:n.privateKey,publicKey:i}}let e=await crypto.subtle.importKey("pkcs8",h(Hr,r),{name:"X25519"},!0,["deriveBits"]),t=await crypto.subtle.exportKey("jwk",e);return{privateKey:e,publicKey:jr(t.x)}}async function ee(r,e){let t=await crypto.subtle.importKey("raw",e,{name:"X25519"},!1,[]);return new Uint8Array(await crypto.subtle.deriveBits({name:"X25519",public:t},r,256))}function St(r){let e=new Uint8Array(12);return new DataView(e.buffer).setBigUint64(4,BigInt(r),!1),e}async function Fr(r){return new Uint8Array(await crypto.subtle.digest("SHA-256",r))}async function Je(r,e){let t=await crypto.subtle.importKey("raw",r,{name:"HMAC",hash:"SHA-256"},!1,["sign"]);return new Uint8Array(await crypto.subtle.sign("HMAC",t,e))}async function Ct(r,e){let t=await Je(r,e),n=await Je(t,new Uint8Array([1])),i=await Je(t,h(n,new Uint8Array([2])));return[n,i]}function jr(r){let e=r.replace(/-/g,"+").replace(/_/g,"/"),t=atob(e+"=".repeat((4-e.length%4)%4));return Uint8Array.from(t,n=>n.charCodeAt(0))}var _t="/sealed/v2/handshake",Mt="/sealed/v2",re="application/vnd.calimero.sealed",Ze=2,qr=new TextEncoder().encode("calimero/sealed-http/v2"),te=16,Qr=1+te+8,Yr=0,Jr=1,zr=2,Zr=1+64*1024+16,Xr=1024,Wr=6e4,en="calimero.tee-attest.transport-key.v1",tn=[101,204,205,304],$t=new TextEncoder,ne=class extends Error{constructor(){super("The node no longer holds the attested transport key; attest again for the current one");this.name="StaleTransportKeyError"}},T=class extends Error{constructor(t,n,i,s){super(i);this.status=t;this.code=n;this.retryAfterMs=s;this.name="SealedTransportError"}};async function Xe(r,e){let t=await crypto.subtle.digest("SHA-256",h($t.encode(en),r,e));return new Uint8Array(t)}function We(r){let e=new URL(r.baseUrl),t=e.pathname.replace(/\/+$/,""),n=`${e.origin}${t}`,i=r.fetch??((g,p)=>fetch(g,p)),s=typeof r.transportPublicKey=="function"?r.transportPublicKey:void 0,o=s?Promise.resolve().then(s):Promise.resolve(r.transportPublicKey);o.catch(()=>{});let a,c=async()=>{try{return await Dt(i,n,await It(o))}catch(g){if(!(g instanceof ne)||!s)throw g;return o=Promise.resolve().then(s),Dt(i,n,await It(o))}},d=async()=>{let g=a??u(void 0),p=await g;if(Date.now()<p.renewAt)return[p,g];let m=u(g);return[await m,m]},u=g=>{if(a===g){let p=c();a=p,p.catch(()=>{a===p&&(a=void 0)})}return a};return async(g,p)=>{let m=new Request(g,p),f=new URL(m.url);if(f.origin!==e.origin||!f.pathname.startsWith(`${t}/`))throw new Error(`Refusing to send ${f.href} outside the sealed node at ${r.baseUrl}`);let b=[];m.headers.forEach((v,H)=>b.push([H,v]));let N={method:m.method,path:f.pathname.slice(t.length)+f.search,headers:b},E=new Uint8Array(await m.arrayBuffer()),k=p?.signal??(g instanceof Request?g.signal:void 0),_=async v=>{let{requestId:H,header:W,envelope:he}=await nn(v,N,E),F=await i(`${n}${Mt}`,{method:"POST",headers:{"content-type":re},body:he,signal:k});if(F.headers.get("content-type")!==re)throw await Kt(F);return on(F,v.responseKey,W,H)},[Fe,je]=await d();try{return await _(Fe)}catch(v){if(!(v instanceof T)||v.code!=="unknown_session")throw v;return _(await u(je))}}}async function It(r){let e=await r;if(e.length!==32)throw new Error("transportPublicKey must be 32 bytes");return e}async function Dt(r,e,t){try{return await Nt(r,e,t)}catch(n){if(!(n instanceof T)||n.code!=="busy")throw n;return await new Promise(i=>setTimeout(i,n.retryAfterMs??1e3)),Nt(r,e,t)}}async function Nt(r,e,t){let n=await Ot(t,qr),i=await r(`${e}${_t}`,{method:"POST",headers:{"content-type":re},body:h(new Uint8Array([Ze]),t,n.message1)});if(i.headers.get("content-type")!==re)throw await Kt(i);let s=await cn(i,Xr);return rn(n,s)}async function rn(r,e){if(e[0]!==Ze)throw new Error("The handshake reply is malformed");let t;try{t=await r.finish(e.slice(1))}catch{throw new Error("The handshake reply did not open: it did not come from the attested node")}let{payload:n,split:i}=t;if(n.length!==te+4)throw new Error("The handshake reply is malformed");let s=n.slice(0,te),o=new DataView(n.buffer,n.byteOffset).getUint32(te,!1),[a,c]=await Promise.all([crypto.subtle.importKey("raw",i[0],"AES-GCM",!1,["encrypt"]),crypto.subtle.importKey("raw",i[1],"AES-GCM",!1,["decrypt"])]);return i[0].fill(0),i[1].fill(0),{requestKey:a,responseKey:c,nextRequestId:1,renewAt:Date.now()+o*1e3-Wr,header(d){let u=new Uint8Array(Qr);return u[0]=Ze,u.set(s,1),new DataView(u.buffer).setBigUint64(1+te,BigInt(d),!1),u}}}async function nn(r,e,t){let n=r.nextRequestId;r.nextRequestId+=1;let i=r.header(n),s=await crypto.subtle.encrypt({name:"AES-GCM",iv:Bt(n,0),additionalData:i},r.requestKey,sn(e,t));return{requestId:n,header:i,envelope:h(i,new Uint8Array(s))}}function Bt(r,e){let t=new Uint8Array(12),n=new DataView(t.buffer);return n.setBigUint64(0,BigInt(r),!1),n.setUint32(8,e,!1),t}function sn(r,e){let t=$t.encode(JSON.stringify(r)),n=new Uint8Array(4);return new DataView(n.buffer).setUint32(0,t.length,!1),h(n,t,e)}async function on(r,e,t,n){if(!r.body)throw new Error("The sealed response has no body");let i=an(r.body.getReader()),s=0,o=async()=>{let u=await i.next();if(!u)return null;let g;try{g=new Uint8Array(await crypto.subtle.decrypt({name:"AES-GCM",iv:Bt(n,s),additionalData:t},e,u))}catch{throw new Error("A sealed response frame did not open: it was not sealed by the attested node")}return s+=1,{kind:g[0],data:g.slice(1)}},a=await o();if(!a||a.kind!==Yr)throw new Error("The sealed response is malformed");let c=JSON.parse(new TextDecoder().decode(a.data));if(tn.includes(c.status))return await i.cancel(),new Response(null,{status:c.status,headers:c.headers});let d=new ReadableStream({async pull(u){try{let g=await o();g?g.kind===Jr?u.enqueue(g.data):g.kind===zr?(u.close(),await i.cancel()):u.error(new Error("The sealed response is malformed")):u.error(new Error("The sealed response was cut short"))}catch(g){u.error(g)}},cancel(){return i.cancel()}});return new Response(d,{status:c.status,headers:c.headers})}function an(r){let e=new Uint8Array,t=async n=>{for(;e.length<n;){let{done:i,value:s}=await r.read();if(i)return!1;e=h(e,s)}return!0};return{async next(){if(!await t(4))return null;let n=new DataView(e.buffer,e.byteOffset).getUint32(0,!1);if(n>Zr)throw await r.cancel(),new Error("The sealed response is malformed: a frame is larger than the node sends");if(!await t(4+n))return null;let i=e.slice(4,4+n);return e=e.slice(4+n),i},cancel:()=>r.cancel()}}async function cn(r,e){if(!r.body)return new Uint8Array;let t=r.body.getReader(),n=new Uint8Array;for(;;){let{done:i,value:s}=await t.read();if(i)return n;if(n=h(n,s),n.length>e)throw await t.cancel(),new Error("The handshake reply is malformed: it is too long")}}async function Kt(r){let e,t=`Sealed request refused: HTTP ${r.status}`;try{let s=await r.json();e=s?.error?.code,s?.error?.message&&(t=`Sealed request refused: ${s.error.message}`)}catch{}if(e==="stale_transport_key")return new ne;let n=Number(r.headers.get("retry-after")),i=Number.isFinite(n)&&n>0?Math.min(n,5)*1e3:void 0;return new T(r.status,e,t,i)}var Vt=[{uri:"https://fulcio.sigstore.dev",validFor:{start:"2021-03-07T03:20:29Z",end:"2022-12-31T23:59:59.999Z"},certChain:["MIIB+DCCAX6gAwIBAgITNVkDZoCiofPDsy7dfm6geLbuhzAKBggqhkjOPQQDAzAqMRUwEwYDVQQKEwxzaWdzdG9yZS5kZXYxETAPBgNVBAMTCHNpZ3N0b3JlMB4XDTIxMDMwNzAzMjAyOVoXDTMxMDIyMzAzMjAyOVowKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTB2MBAGByqGSM49AgEGBSuBBAAiA2IABLSyA7Ii5k+pNO8ZEWY0ylemWDowOkNa3kL+GZE5Z5GWehL9/A9bRNA3RbrsZ5i0JcastaRL7Sp5fp/jD5dxqc/UdTVnlvS16an+2Yfswe/QuLolRUCrcOE2+2iA5+tzd6NmMGQwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEwHQYDVR0OBBYEFMjFHQBBmiQpMlEk6w2uSu1KBtPsMB8GA1UdIwQYMBaAFMjFHQBBmiQpMlEk6w2uSu1KBtPsMAoGCCqGSM49BAMDA2gAMGUCMH8liWJfMui6vXXBhjDgY4MwslmN/TJxVe/83WrFomwmNf056y1X48F9c4m3a3ozXAIxAKjRay5/aj/jsKKGIkmQatjI8uupHr/+CxFvaJWmpYqNkLDGRU+9orzh5hI2RrcuaQ=="]},{uri:"https://fulcio.sigstore.dev",validFor:{start:"2022-04-13T20:06:15Z"},certChain:["MIICGjCCAaGgAwIBAgIUALnViVfnU0brJasmRkHrn/UnfaQwCgYIKoZIzj0EAwMwKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTAeFw0yMjA0MTMyMDA2MTVaFw0zMTEwMDUxMzU2NThaMDcxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjEeMBwGA1UEAxMVc2lnc3RvcmUtaW50ZXJtZWRpYXRlMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE8RVS/ysH+NOvuDZyPIZtilgUF9NlarYpAd9HP1vBBH1U5CV77LSS7s0ZiH4nE7Hv7ptS6LvvR/STk798LVgMzLlJ4HeIfF3tHSaexLcYpSASr1kS0N/RgBJz/9jWCiXno3sweTAOBgNVHQ8BAf8EBAMCAQYwEwYDVR0lBAwwCgYIKwYBBQUHAwMwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQU39Ppz1YkEZb5qNjpKFWixi4YZD8wHwYDVR0jBBgwFoAUWMAeX5FFpWapesyQoZMi0CrFxfowCgYIKoZIzj0EAwMDZwAwZAIwPCsQK4DYiZYDPIaDi5HFKnfxXx6ASSVmERfsynYBiX2X6SJRnZU84/9DZdnFvvxmAjBOt6QpBlc4J/0DxvkTCqpclvziL6BCCPnjdlIB3Pu3BxsPmygUY7Ii2zbdCdliiow=","MIIB9zCCAXygAwIBAgIUALZNAPFdxHPwjeDloDwyYChAO/4wCgYIKoZIzj0EAwMwKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTAeFw0yMTEwMDcxMzU2NTlaFw0zMTEwMDUxMzU2NThaMCoxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjERMA8GA1UEAxMIc2lnc3RvcmUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAT7XeFT4rb3PQGwS4IajtLk3/OlnpgangaBclYpsYBr5i+4ynB07ceb3LP0OIOZdxexX69c5iVuyJRQ+Hz05yi+UF3uBWAlHpiS5sh0+H2GHE7SXrk1EC5m1Tr19L9gg92jYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRYwB5fkUWlZql6zJChkyLQKsXF+jAfBgNVHSMEGDAWgBRYwB5fkUWlZql6zJChkyLQKsXF+jAKBggqhkjOPQQDAwNpADBmAjEAj1nHeXZp+13NWBNa+EDsDP8G1WWg1tCMWP/WHPqpaVo0jhsweNFZgSs0eE7wYI4qAjEA2WB9ot98sIkoF3vZYdd3/VtWB5b9TNMea7Ix/stJ5TfcLLeABLE4BNJOsQ4vnBHJ"]}],Lt=[{baseUrl:"https://rekor.sigstore.dev",logId:"c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d",publicKey:"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE2G2Y+2tabdTV5BcGiBIx0a9fAFwrkBbmLSGtks4L3qX6yYY0zufBnhC8Ur/iy55GhWP/9A/bY2LhC30M9+RYtw==",validFor:{start:"2021-01-12T11:53:27Z"}}];var ln="1.2.840.10045.2.1",dn={"1.2.840.10045.3.1.7":"P-256","1.3.132.0.34":"P-384"},un={"P-256":32,"P-384":48},gn={"1.2.840.10045.4.3.2":"SHA-256","1.2.840.10045.4.3.3":"SHA-384"};function Gt(r,e,t){if(e+2>t)throw new Error("it is truncated");let n=r[e];if((n&31)===31)throw new Error("it uses a tag this parser does not read");let i=r[e+1],s=e+2;if(i&128){let a=i&127;if(a===0||a>4||s+a>t)throw new Error("it has a length this parser does not read");i=0;for(let c=0;c<a;c+=1)i=i*256+r[s+c];s+=a}let o=s+i;if(o>t)throw new Error("it is truncated");return{tag:n,bytes:r,offset:e,start:s,end:o}}function Y(r){let e=Gt(r,0,r.length);if(e.end!==r.length)throw new Error("it has trailing bytes");return e}function A(r){let e=[];for(let t=r.start;t<r.end;){let n=Gt(r.bytes,t,r.end);e.push(n),t=n.end}return e}function w(r,e,t){if(!r||r.tag!==e)throw new Error(`${t} is not where it should be`);return r}function S(r){return r.bytes.slice(r.start,r.end)}function we(r){return r.bytes.slice(r.offset,r.end)}function Q(r){let e=S(w(r,6,"An object identifier"));if(e.length===0||e[e.length-1]&128)throw new Error("it has a malformed object identifier");let t=[],n=0;for(let o of e)n=n*128+(o&127),o&128||(t.push(n),n=0);let i=t.shift();return[...i<80?[Math.floor(i/40),i%40]:[2,i-80],...t].join(".")}function pn(r){let e=new TextDecoder().decode(S(r)),t=r.tag===23?/^(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})Z$/.exec(e):null,n=r.tag===24?/^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})Z$/.exec(e):null,i=t??n;if(!i)throw new Error(`it holds the time ${JSON.stringify(e)}, which is not one a certificate may hold`);let s=Number(i[1]);t&&(s+=s<50?2e3:1900);let[o,a,c,d,u]=i.slice(2).map(Number);return Date.UTC(s,o-1,a,c,d,u)}function et(r){try{let[e,t,n,...i]=A(w(Y(r),48,"The certificate"));if(i.length>0)throw new Error("it has fields after its signature");let s=A(w(e,48,"The signed part")),o=s[0]?.tag===160?1:0,[a,c,d,u,g,p,...m]=s.slice(o);w(a,2,"The serial number");let f=Q(A(w(t,48,"The signature algorithm"))[0]);if(Q(A(w(c,48,"The signature algorithm"))[0])!==f)throw new Error("it names two different signature algorithms");let N=gn[f];if(!N)throw new Error(`it is signed with ${f}, not ECDSA with SHA-256 or SHA-384`);let[E,k]=A(w(u,48,"The validity")).map(pn);if(k===void 0)throw new Error("its validity is incomplete");let[_,Fe]=A(w(p,48,"The public key"));w(Fe,3,"The public key");let[je,v]=A(w(_,48,"The key algorithm"));if(Q(je)!==ln)throw new Error("its key is not an elliptic-curve key");let H=dn[Q(v)];if(!H)throw new Error("its key is on a curve other than P-256 or P-384");let W=new Map,he=m.find(qe=>qe.tag===163);if(he){let[qe]=A(he);for(let Vr of A(w(qe,48,"The extensions"))){let j=A(w(Vr,48,"An extension"));if(j.length===3)w(j[1],1,"An extension's critical flag");else if(j.length!==2)throw new Error("it has a malformed extension");let Qe=Q(j[0]);if(W.has(Qe))throw new Error(`it has extension ${Qe} twice`);W.set(Qe,S(w(j[j.length-1],4,"An extension value")))}}let F=S(w(n,3,"The signature"));if(F[0]!==0)throw new Error("its signature is not a whole number of bytes");return{der:r,tbs:we(e),signatureHash:N,signature:F.slice(1),issuer:we(w(d,48,"The issuer")),subject:we(w(g,48,"The subject")),notBefore:E,notAfter:k,spki:we(p),curve:H,extensions:W}}catch(e){throw new Error(`The certificate is malformed: ${e.message}`)}}function Ht(r){return A(w(Y(r),48,"The list")).map(Q)}function fn(r,e){let t=un[e],n=A(w(Y(r),48,"The signature"));if(n.length!==2)throw new Error("The signature is not an ECDSA signature");let i=new Uint8Array(t*2);return n.forEach((s,o)=>{let a=S(w(s,2,"The signature"));if(a.length===0||a[0]&128)throw new Error("The signature is not an ECDSA signature");for(;a.length>1&&a[0]===0;)a=a.subarray(1);if(a.length>t)throw new Error("The signature is not an ECDSA signature");i.set(a,o*t+t-a.length)}),i}async function Ae(r,e,t,n,i){let s;try{s=fn(n,e)}catch{return!1}let o=await crypto.subtle.importKey("spki",r,{name:"ECDSA",namedCurve:e},!1,["verify"]);return crypto.subtle.verify({name:"ECDSA",hash:t},o,s,i)}function x(r,e){let t=r.replace(/\s+/g,"");if(!/^[A-Za-z0-9+/]*={0,2}$/.test(t)||t.length%4!==0)throw new Error(`${e} is not base64`);let n=atob(t),i=new Uint8Array(n.length);for(let s=0;s<n.length;s+=1)i[s]=n.charCodeAt(s);return i}function tt(r,e){let t=[...r.matchAll(/-----BEGIN CERTIFICATE-----([^-]*)-----END CERTIFICATE-----/g)];if(t.length!==1||r.replace(t[0][0],"").trim()!=="")throw new Error(`${e} is not exactly one PEM certificate`);return x(t[0][1],e)}var yn="2.5.29.17",hn="2.5.29.37",mn="1.3.6.1.5.5.7.3.3",wn="1.3.6.1.4.1.57264.1.8",An="1.3.6.1.4.1.57264.1.1",bn=134,En=12,Rn=48,Pn=new TextEncoder,J=r=>new TextDecoder().decode(r);async function be(r,e,t,n){let{base64Signature:i,cert:s,rekorBundle:o}=Un(e),a=o.Payload;if(n!==void 0&&n.trim()!==i.trim())throw new Error("The detached signature is not the one in the bundle");let c=x(i,"The bundle signature"),d=tt(J(x(s,"The bundle certificate")),"The bundle certificate"),u=et(d),g=Lt.find(k=>k.logId===a.logID.toLowerCase());if(!g)throw new Error(`The bundle names Rekor log ${a.logID}, which the Sigstore trust root does not know`);let p=Pn.encode(`{"body":${JSON.stringify(a.body)},"integratedTime":${a.integratedTime},"logID":${JSON.stringify(a.logID)},"logIndex":${a.logIndex}}`);if(!await Ae(x(g.publicKey,"The Rekor key"),"P-256","SHA-256",x(o.SignedEntryTimestamp,"The signed entry timestamp"),p))throw new Error("Rekor's signed entry timestamp does not verify: the log entry, its time or its index was altered");let f=a.integratedTime*1e3;if(!qt(f,g.validFor))throw new Error(`Rekor log ${g.baseUrl} was not in use at ${ie(f)}, when the entry says it was logged`);let b=Tn(a.body),N=R(new Uint8Array(await crypto.subtle.digest("SHA-256",r)));if(b.hash!==N)throw new Error("The file's SHA-256 is not the one Rekor logged: the file is not the one signed");if(!rt(x(b.signature,"The logged signature"),c))throw new Error("The bundle's signature is not the one Rekor logged");let E=tt(J(x(b.publicKey,"The logged certificate")),"The logged certificate");if(!rt(E,d))throw new Error("The bundle's certificate is not the one Rekor logged");if(u.curve!=="P-256"||!await Ae(u.spki,"P-256","SHA-256",c,r))throw new Error("The signature over the file does not verify with the bundle's certificate");return await vn(u,f),kn(u,t),{integratedTime:a.integratedTime}}async function vn(r,e){if(!jt(r,e))throw new Error(`The signing certificate was valid ${ie(r.notBefore)} to ${ie(r.notAfter)}, not at ${ie(e)} when Rekor logged it`);let t=[];for(let n of Vt){let i=n.certChain.map(o=>et(x(o,"A Fulcio certificate")));if(!await Ft(r,i[0]))continue;let s=await xn(i,n.validFor,e);if(!s)return;t.push(`${n.uri} (valid from ${n.validFor.start}): ${s}`)}throw new Error(t.length>0?`The signing certificate's CA is not trusted at ${ie(e)}: ${t.join("; ")}`:"The signing certificate was not issued by a Fulcio CA in the Sigstore trust root")}async function xn(r,e,t){if(!qt(t,e))return"the trust root says it was not issuing certificates then";for(let[n,i]of r.entries()){if(!jt(i,t))return`its certificate ${n} was not valid then`;let s=r[n+1]??i;if(!await Ft(i,s))return`its certificate ${n} is not signed by the next`}}async function Ft(r,e){return rt(r.issuer,e.subject)?Ae(e.spki,e.curve,r.signatureHash,r.signature,r.tbs):!1}function kn(r,e){let t=r.extensions.get(yn);if(!t)throw new Error("The signing certificate names no identity");let n=A(w(Y(t),Rn,"The subject alternative name")),i=n.filter(d=>d.tag===bn).map(d=>J(S(d)));if(i.length!==1||n.length!==1||i[0]!==e.identity)throw new Error(`The release was signed by ${JSON.stringify(i.length===1?i[0]:i)}, not by ${e.identity}`);let s=r.extensions.get(wn),o=r.extensions.get(An),a=s?J(S(w(Y(s),En,"The OIDC issuer"))):o?J(o):void 0;if(a!==e.issuer)throw new Error(`The signing certificate's OIDC issuer is ${a===void 0?"missing":JSON.stringify(a)}, not ${e.issuer}`);let c=r.extensions.get(hn);if(!c||!Ht(c).includes(mn))throw new Error("The signing certificate is not for code signing")}function Un(r){let e=r;if(typeof e=="string")try{e=JSON.parse(e)}catch{throw new Error("The bundle is not JSON")}let t=e,n=t?.rekorBundle?.Payload;if(!(typeof t?.base64Signature=="string"&&typeof t.cert=="string"&&typeof t.rekorBundle?.SignedEntryTimestamp=="string"&&typeof n?.body=="string"&&typeof n.logID=="string"&&/^[0-9a-fA-F]{64}$/.test(n.logID)&&Number.isSafeInteger(n.integratedTime)&&n.integratedTime>=0&&Number.isSafeInteger(n.logIndex)&&n.logIndex>=0))throw new Error("The bundle is not a cosign bundle with a Rekor entry");return t}function Tn(r){let e;try{e=JSON.parse(J(x(r,"The logged entry")))}catch{throw new Error("The logged entry is not JSON")}let t=e?.spec?.data?.hash,n=e?.spec?.signature;if(e?.kind!=="hashedrekord"||t?.algorithm!=="sha256"||typeof t.value!="string"||typeof n?.content!="string"||typeof n.publicKey?.content!="string")throw new Error("The logged entry is not a SHA-256 hashedrekord");return{hash:t.value.toLowerCase(),signature:n.content,publicKey:n.publicKey.content}}function jt(r,e){return r.notBefore<=e&&e<=r.notAfter}function qt(r,e){return Date.parse(e.start)<=r&&(e.end===void 0||r<=Date.parse(e.end))}function ie(r){return new Date(r).toISOString()}function rt(r,e){return r.length===e.length&&r.every((t,n)=>t===e[n])}var Sn=/^[0-9a-f]{96}$/,Cn=["mrtd","rtmr0","rtmr1","rtmr2","rtmr3"];function $(r){let e=z(r.allowedMrtd??[],"allowedMrtd"),t=(r.allowedMeasurements??[]).map((a,c)=>{let d=`allowedMeasurements[${c}]`;return Cn.map(u=>z([a?.[u]??""],`${d}.${u}`)[0]).join()}),n=[z(r.allowedRtmr0??[],"allowedRtmr0"),z(r.allowedRtmr1??[],"allowedRtmr1"),z(r.allowedRtmr2??[],"allowedRtmr2"),z(r.allowedRtmr3??[],"allowedRtmr3")];if(r.allowedMeasurements!==void 0&&t.length===0)throw new Error("allowedMeasurements is empty, so no quote would ever be accepted");if(t.length===0){if(e.length===0)throw new Error("No image is trusted: give allowedMeasurements, or allowedMrtd with allowedRtmr1-3");if(n.slice(1).some(a=>a.length===0))throw new Error("allowedMrtd alone does not name an image: the MRTD measures the TD firmware, which images share, and the image is in RTMR1-3. Give allowedMeasurements, or allowedRtmr1-3 too")}let i=r.allowedTcbStatuses??["UpToDate"],s=r.now??Date.now;return Object.assign(async({quoteB64:a,nonce:c,reportDataSuffix:d,collateral:u})=>{let g=In(a),p=u??await r.fetchCollateral?.(g);if(!p)throw new Error("The node sent no collateral for its quote, and no fetchCollateral was given to get it");let m;try{m=r.dcapVerify(g,p,Math.floor(s()/1e3))}catch(E){throw new Error(`The quote did not verify: ${E?.message??String(E)}`)}if(m.status==="Revoked"||!i.includes(m.status))throw new Error(`The platform's TCB status is ${m.status}, which is not accepted`);let f=On(m.report);if(f.tdAttributes?.length!==8||(f.tdAttributes[0]&1)!==0)throw new Error("The quote is from a debug TD, or its TD attributes cannot be read");let b=[f.mrTd,f.rtMr0,f.rtMr1,f.rtMr2,f.rtMr3].map(E=>R(E));if(t.length>0&&!t.includes(b.join()))throw new Error(`The measurements (MRTD ${b[0]}, RTMR0-3 ${b.slice(1).join(", ")}) are not an image this verifier trusts`);if(e.length>0&&!e.includes(b[0]))throw new Error(`MRTD ${b[0]} is not an image this verifier trusts`);if([f.rtMr0,f.rtMr1,f.rtMr2,f.rtMr3].forEach((E,k)=>{let _=n[k];if(_.length>0&&!_.includes(R(E)))throw new Error(`RTMR${k} ${R(E)} is not one this verifier trusts`)}),R(f.reportData)!==`${c}${d}`.toLowerCase())throw new Error("The quote does not commit to this nonce and binding");return!0},{includeCollateral:!0})}function z(r,e){return r.map(t=>{let n=t.trim().toLowerCase();if(!Sn.test(n))throw new Error(`${e} holds ${JSON.stringify(t)}, which is not a 48-byte hex measurement`);return n})}function On(r){let e=r.data;if(r.type==="td10"&&e)return e;if(r.type==="td15"&&e?.base)return e.base;throw new Error(`The quote is a ${r.type} quote, not a TDX one`)}function In(r){let e=atob(r),t=new Uint8Array(e.length);for(let n=0;n<e.length;n+=1)t[n]=e.charCodeAt(n);return t}var Dn=["UpToDate","SWHardeningNeeded","ConfigurationNeeded","ConfigurationAndSWHardeningNeeded","OutOfDate","OutOfDateConfigurationNeeded"],M="locked-read-only";function nt(r,{profile:e,allowDebugProfile:t=!1}){if(r.length===0)throw new Error("No release given, so no image would be trusted");let n,i=r.map((s,o)=>{let a=s?.tag??`releases[${o}]`;if(s?.role!==void 0&&s.role!=="node")throw new Error(`${a} lists the measurements of a ${s.role}, not of a node image`);let c=s?.profiles?.[e];if(!c){let u=Object.keys(s?.profiles??{}).join(", ")||"none";throw new Error(`${a} has no profile ${JSON.stringify(e)} (it has: ${u})`)}if(e!==M&&!t)throw new Error(`${JSON.stringify(e)} is not a production profile: its image is readable by whoever operates the node. Trust ${JSON.stringify(M)}, or pass allowDebugProfile to test`);let d=(c.allowed_tcb_statuses??["uptodate"]).map(u=>Nn(u,a));return n=n===void 0?d:n.filter(u=>d.includes(u)),{mrtd:c.mrtd,rtmr0:c.rtmr0,rtmr1:c.rtmr1,rtmr2:c.rtmr2,rtmr3:c.rtmr3}});if(!n||n.length===0)throw new Error("The releases given accept no TCB status in common");return{allowedMeasurements:i,allowedTcbStatuses:n}}function Nn(r,e){let t=Dn.find(n=>n.toLowerCase()===String(r).toLowerCase());if(!t)throw new Error(`${e} accepts TCB status ${JSON.stringify(r)}, which this verifier does not know`);return t}var it=Object.freeze({identity:"https://github.com/calimero-network/mero-tee/.github/workflows/release-node-image-gcp.yaml@refs/heads/master",issuer:"https://token.actions.githubusercontent.com"}),_n=["mrtd","rtmr0","rtmr1","rtmr2","rtmr3"],Ee="https://cloud.calimero.network",st=`${Ee}/api/tee/pcs`;async function Yt(r,e,t={}){let n=typeof r=="string"?new TextEncoder().encode(r):r;await be(n,e,{identity:t.identity??it.identity,issuer:t.issuer??it.issuer},t.signature);let i;try{i=JSON.parse(new TextDecoder().decode(n))}catch{throw new Error("The signed release is not JSON")}if(i?.role!=="node")throw new Error(`The signed release is a ${JSON.stringify(i?.role)} release, not a node one`);let s=Object.values(i.profiles??{}),o=a=>_n.every(c=>/^[0-9a-f]{96}$/i.test(String(a?.[c])));if(typeof i.tag!="string"||s.length===0||!s.every(o))throw new Error("The signed file is not a release's published-mrtds.json: it lists no measured profiles");if(t.expectedVersion!==void 0&&i.tag!==t.expectedVersion)throw new Error(`The signed release is ${i.tag}, not ${t.expectedVersion}`);return i}async function ot(r,e={}){let t=await(e.fetch??fetch)(r,{headers:{accept:"application/json"}});if(!t.ok)throw new Error(`Fetching the node release from ${r} failed: HTTP ${t.status}`);let n;try{n=(await t.json())?.data}catch{throw new Error(`${r} did not answer with JSON`)}if(typeof n?.version!="string"||typeof n.publishedMrtds!="string"||typeof n.bundle!="string")throw new Error(`${r} did not answer with a signed node release`);return{version:n.version,publishedMrtds:n.publishedMrtds,bundle:n.bundle}}var Jt="https://github.com/calimero-network/mero-tee/releases/download";async function at(r,e={}){let t=`mero-tee-v${C(r,"version")}`,n=`${(e.base??Jt).replace(/\/+$/,"")}/${t}/published-mrtds.json`,i=async a=>{let c=await(e.fetch??fetch)(a);if(!c.ok)throw new Error(`Fetching ${a} failed: HTTP ${c.status}`);return c.text()},[s,o]=await Promise.all([i(n),i(`${n}.bundle.json`)]);return{version:r,publishedMrtds:s,bundle:o}}function ct(r,e){return`${r.replace(/\/+$/,"")}/api/tee/node-releases/${C(e,"version")}`}async function Re(r){let e=C(r.minReleaseVersion,"minReleaseVersion"),t=C(r.release?.version,"The release version"),n=await Yt(r.release.publishedMrtds,r.release.bundle,{expectedVersion:t,identity:r.identity,issuer:r.issuer});if(se(t,e)<0)throw new Error(`Release ${t} is older than the minimum trusted, ${e}`);return nt([n],{profile:r.profile,allowDebugProfile:r.allowDebugProfile})}function Mn(r){return C(r.minReleaseVersion,"minReleaseVersion"),Object.assign(async t=>{let n=await Re({release:await r.release(),profile:r.profile,allowDebugProfile:r.allowDebugProfile,minReleaseVersion:r.minReleaseVersion,identity:r.identity,issuer:r.issuer});return $({dcapVerify:r.dcapVerify,fetchCollateral:r.fetchCollateral,now:r.now,...n})(t)},{includeCollateral:!0})}var zt=/^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/;function C(r,e){let t=typeof r=="string"?zt.exec(r):null,n=t?.[4];if(!t||n!==void 0&&n.split(".").some(i=>i===""))throw new Error(`${e} is ${JSON.stringify(r)}, not a release version like 2.3.87`);return r}function se(r,e){let[t,n]=Qt(r),[i,s]=Qt(e);for(let c=0;c<3;c+=1)if(t[c]!==i[c])return t[c]<i[c]?-1:1;if(n===void 0||s===void 0)return n===s?0:n===void 0?1:-1;let o=n.split("."),a=s.split(".");for(let c=0;c<Math.max(o.length,a.length);c+=1){let[d,u]=[o[c],a[c]];if(d===void 0||u===void 0)return d===void 0?-1:1;let[g,p]=[/^\d+$/.test(d),/^\d+$/.test(u)],m=g&&p?Math.sign(Number(d)-Number(u)):g!==p?g?-1:1:d<u?-1:d>u?1:0;if(m!==0)return m}return 0}function Qt(r){let e=zt.exec(r);return[[Number(e[1]),Number(e[2]),Number(e[3])],e[4]]}var Xt="MOCK_TDX_QUOTE_V1";function $n(r){let e=atob(r),t=new Uint8Array(e.length);for(let n=0;n<e.length;n++)t[n]=e.charCodeAt(n);return t}function lt(r,e){if(r.length!==e.length)return!1;let t=0;for(let n=0;n<r.length;n++)t|=r[n]^e[n];return t===0}var Zt;async function dt(r){Zt??(Zt=import("@phala/dcap-qvl"));let e=await Zt,t=typeof e[r]=="function"?e[r]:e.default?.[r];if(typeof t!="function")throw new TypeError(`@phala/dcap-qvl loaded without ${r}`);return t}function Wt(r,e){let t=C(e,"minReleaseVersion"),n=String(r.release?.version??"").trim().replace(/^mero-tee-v/,"").replace(/^v/,""),i=C(n,"The release the node names");if(se(i,t)<0)throw new Error(`mero-tee release ${i} is older than the minimum ${t}`);return i}async function Bn(r,e,t){let n=e.releaseSource;return typeof n=="function"?n(r):n==="github"?at(r,{fetch:t}):ot(ct(n??Ee,r),{fetch:t})}function Kn(r){let e=r.collateralSource??st;return e==="intel"?async t=>(await dt("getCollateralFromPcs"))(t):async t=>(await dt("getCollateral"))(e,t)}function er(r,e){let t=e.maxCollateralAgeDays;return t===void 0?r:async n=>{let i=await r(n),s;try{s=Date.parse(JSON.parse(i.tcb_info).issueDate??"")}catch{s=Number.NaN}if(!Number.isFinite(s))throw new Error("The quote's collateral names no TCB info issue date");let o=((e.now??Date.now)()-s)/864e5;if(o>t)throw new Error(`The quote's collateral was issued ${Math.floor(o)} days ago, more than the ${t} this client accepts`);return i}}async function Vn(r,e,t,n){let i=Wt(r,t.minReleaseVersion),s=await Re({release:await Bn(i,t,n),profile:t.profile??M,allowDebugProfile:t.allowDebugProfile,minReleaseVersion:t.minReleaseVersion,identity:t.identity,issuer:t.issuer}),o=er(t.fetchCollateral??Kn(t),t);return $({dcapVerify:t.dcapVerify??await dt("verify"),fetchCollateral:o,now:t.now,...s})(e)}async function ut(r,e,t=(n,i)=>fetch(n,i)){let n=R(crypto.getRandomValues(new Uint8Array(32))),i=new URL(`${r.replace(/\/+$/,"")}/attestation`);i.searchParams.set("nonce",n),e.appHash&&i.searchParams.set("appHash",e.appHash);let s=await t(i.toString());if(!s.ok)throw new Error(`The node refused to attest: HTTP ${s.status}`);let o=await s.json(),a=me(o.transportKey,"transportKey",32),c=e.appHash?me(e.appHash,"appHash",32):new Uint8Array(32),d=await Xe(c,a),u=$n(o.quote),g=new TextEncoder().encode(Xt);if(lt(u.slice(0,g.length),g)){if(!e.allowMock)throw new Error("mock quote refused: this client only trusts real TEEs");let f=u.slice(g.length,g.length+64);if(!lt(f.slice(0,32),me(n,"nonce",32))||!lt(f.slice(32),d))throw new Error("the quote does not bind this transport key, app and nonce");return a}let p={quoteB64:o.quote,nonce:n,reportDataSuffix:R(d)},m;if(e.verifyQuote)m=await e.verifyQuote(p);else if(e.release)m=await Vn(o,p,e.release,t);else throw new Error("real quote refused: this client trusts no TD image (set policy.release)");if(!m)throw new Error("The attestation did not verify, so its transport key is not trusted");return a}var gt="https://manager.cloud.calimero.network/api/v2/directory";var U=class extends Error{constructor(t,n,i,s,o){super(`directory for cluster ${t}: ${i}`);this.cluster=t;this.reason=n;this.status=s;this.cause=o;this.name="DirectoryError"}};function Ln(r,e){return`${r.replace(/\/+$/,"")}/${encodeURIComponent(e)}`}async function pt(r,e,t){let n;try{n=await t(Ln(r,e),{method:"GET",headers:{accept:"application/json"}})}catch(u){throw new U(e,"unreachable",`could not be reached: ${String(u)}`,void 0,u)}if(n.status===404)throw new U(e,"not-found","unknown cluster",404);if(!n.ok)throw new U(e,"unreachable",`answered ${n.status}`,n.status);let i;try{i=await n.json()}catch(u){throw new U(e,"bad-response","answered something other than JSON",n.status,u)}let s=i;if(!s||typeof s!="object"||!Array.isArray(s.nodes))throw new U(e,"bad-response","answered no node list",n.status);let o=[],a=new Set;for(let u of s.nodes){let g=Gn(u);g&&!a.has(g.url)&&(a.add(g.url),o.push(g))}if(o.length===0)throw new U(e,"empty","lists no usable node",n.status);let c=s.refreshAfterSeconds,d=typeof c=="number"&&Number.isFinite(c)&&c>=1?c:60;return{nodes:o,refreshAfterSeconds:d}}function Gn(r){if(!r||typeof r!="object")return;let{url:e,zone:t,weight:n}=r;if(typeof e!="string"||typeof n!="number"||!Number.isInteger(n)||n<1)return;let i;try{i=new URL(e)}catch{return}if(!(i.protocol!=="https:"&&i.protocol!=="http:"))return{url:e.replace(/\/+$/,""),zone:typeof t=="string"?t:void 0,weight:n}}function ft(r,e,t){let n=e===void 0?[]:r.filter(s=>s.zone===e),i=e===void 0?r:r.filter(s=>s.zone!==e);return[...tr(n,t),...tr(i,t)]}function tr(r,e){let t=[...r],n=[];for(;t.length>0;){let i=e()*t.reduce((o,a)=>o+a.weight,0),s=0;for(;s<t.length-1&&i>=t[s].weight;)i-=t[s++].weight;n.push(t.splice(s,1)[0].url)}return n}var y=class extends Error{constructor(t,n,i,s={}){super(`${t} ${n}: ${i}`);this.status=t;this.code=n;this.details=s;this.name="CalimeroError"}},B=class extends y{constructor(e,t={}){super(401,"UNAUTHENTICATED",e,t),this.name="LoginRequired"}},Pe=class extends y{constructor(e,t={}){super(401,"PASSKEY_UNKNOWN_HERE",e||"this passkey belongs to another Calimero cluster or was removed from this one",t),this.name="PasskeyUnknownHere"}},K=class extends y{constructor(e,t={}){super(421,"WRONG_NODE",e,t),this.name="WrongNode"}},ve=class extends y{constructor(e,t={}){super(404,"NOT_FOUND",e,t),this.name="NotFound"}},Z=class extends y{constructor(e,t={}){super(412,"CONFIRM_REQUIRED",e,t),this.name="ConfirmRequired"}},oe=class extends Error{constructor(t){super("the passkey confirmation was cancelled");this.cause=t;this.name="ConfirmCancelled"}},ae=class extends Error{constructor(t){super("the passkey prompt was blocked by the browser or a password manager");this.cause=t;this.name="ConfirmPromptBlocked"}},xe=class extends y{constructor(e,t={}){super(413,"ARGS_TOO_LARGE",e,t),this.name="ArgsTooLarge"}},ke=class extends y{constructor(e,t={}){super(409,"IDEMPOTENCY_MISMATCH",e,t),this.name="IdempotencyMismatch"}},Ue=class extends y{constructor(e,t={}){super(409,"RELEASE_DEADLINE",e,t),this.name="ReleaseDeadlineError",this.release=typeof t.release=="string"?t.release:"",this.after=typeof t.after=="string"?t.after:""}},Te=class extends y{constructor(e,t={}){super(409,"CONSENT_STALE",e,t),this.name="ConsentStale"}},V=class extends y{constructor(e,t={}){let n=typeof t.origin=="string"?t.origin:"",i=typeof t.package=="string"?t.package:"",s=n?`this site (${n})`:"this site";super(403,"ORIGIN_NOT_REGISTERED",`${s} is not registered for ${i||"any package"}${e?` (${e})`:""}`,t),this.name="OriginNotRegistered",this.origin=n,this.package=i,this.nodeMessage=e}},Se=class extends y{constructor(e,t,n={}){super(400,e,t,n),this.name="BadOrigin"}},Ce=class extends y{constructor(e,t={}){super(409,"ORIGIN_TAKEN",e,t),this.name="OriginTaken"}},Oe=class extends y{constructor(e,t={}){super(400,"NOT_SERVING",e,t),this.name="NotServing"}},Ie=class extends y{constructor(e,t={}){super(409,"CLUSTER_NOT_UPGRADED",e,t),this.name="ClusterNotUpgraded"}},De=class extends y{constructor(e,t={}){super(409,"RECOVERY_NOT_READY",e,t),this.name="RecoveryNotReady",this.readyAt=typeof t.readyAt=="number"?t.readyAt:void 0}},ce=class extends y{constructor(e,t={}){super(401,"UNAUTHENTICATED",e||"unknown or used recovery code",t),this.name="WrongRecoveryCode"}},Ne=class extends y{constructor(e,t={}){super(403,"SIGN_UP_REFUSED",e,t),this.name="SignUpRefused",this.reason=Hn(e)}};function Hn(r){return/invite only/.test(r)?"invite-only":/pre-authorized|sign-up invite/.test(r)?"closed":/unknown invite/.test(r)?"unknown-invite":/invite has expired/.test(r)?"expired-invite":/organization is gone/.test(r)?"org-gone":"other"}var _e=class extends y{constructor(e,t={}){super(429,"QUOTA_EXCEEDED",e,t),this.name="QuotaExceeded"}},Me=class extends y{constructor(e,t={}){super(422,"APP_ERROR",e,t),this.name="AppError";let{appCode:n,fields:i}=Fn(t);this.appCode=n,this.fields=i}},$e=class extends y{constructor(e,t={}){super(422,"TRAP",e,t),this.name="TrapError",this.kind=typeof t.kind=="string"?t.kind:""}},L=class extends y{constructor(e,t,n={},i,s){super(503,e,t,n),this.name="UnavailableError",this.reason=e.toLowerCase(),this.committed=e==="TIMEOUT"||e==="MIGRATING"?!1:"unknown",this.retryAfter=i,this.cause=s}};function Be(r){return r&&typeof r=="object"&&!Array.isArray(r)?r:{}}function Fn(r){let e=typeof r.code=="string"?r:Be(r.error);return{appCode:typeof e.code=="string"?e.code:"",fields:{...Be(e.fields)}}}function jn(r,e){for(let t of[r.retryAfter,e==null?void 0:Number(e)])if(typeof t=="number"&&Number.isFinite(t)&&t>=0)return t}function Ke(r,e,t){let n=Be(e),i=typeof n.error=="string"?n.error:"ERROR",s=typeof n.message=="string"?n.message:"",o=Be(n.details);if(r===503)return new L(i,s,o,jn(o,t));switch(`${r} ${i}`){case"401 UNAUTHENTICATED":return new B(s,o);case"401 PASSKEY_UNKNOWN_HERE":return new Pe(s,o);case"421 WRONG_NODE":return new K(s,o);case"404 NOT_FOUND":return new ve(s,o);case"409 IDEMPOTENCY_MISMATCH":return new ke(s,o);case"409 RELEASE_DEADLINE":return new Ue(s,o);case"409 CONSENT_STALE":return new Te(s,o);case"403 ORIGIN_NOT_REGISTERED":return new V(s,o);case"400 BAD_ORIGIN":case"400 BAD_RP_ID":return new Se(i,s,o);case"409 ORIGIN_TAKEN":return new Ce(s,o);case"400 NOT_SERVING":return new Oe(s,o);case"409 CLUSTER_NOT_UPGRADED":return new Ie(s,o);case"429 QUOTA_EXCEEDED":return new _e(s,o);case"409 RECOVERY_NOT_READY":return new De(s,o);case"403 SIGN_UP_REFUSED":return new Ne(s,o);case"412 CONFIRM_REQUIRED":return new Z(s,o);case"413 ARGS_TOO_LARGE":return new xe(s,o);case"422 APP_ERROR":return new Me(s,o);case"422 TRAP":return new $e(s,o);default:return new y(r,i,s,o)}}function P(r){let e="";for(let t of r)e+=String.fromCharCode(t);return btoa(e).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function O(r){let e=r.replace(/-/g,"+").replace(/_/g,"/")+"===".slice((r.length+3)%4),t=atob(e),n=new Uint8Array(t.length);for(let i=0;i<t.length;i++)n[i]=t.charCodeAt(i);return n}var le=r=>r.buffer.slice(r.byteOffset,r.byteOffset+r.byteLength);function yt(r){let e=new Error(r);return e.name="NotAllowedError",e}async function rr(r,e,t,n){let i=navigator.credentials,o=globalThis.CredentialsContainer?.prototype?.[r]??i[r];try{return await o.call(i,t?{...e,signal:t}:e)}catch(a){throw t?.aborted||a?.name==="AbortError"?Object.assign(yt(`${n} was cancelled`),{cause:a}):a}}function qn(r){let e=r.filter(t=>t.alg===-7);return e.length?e:r}function Qn(){return{async create(r,e){let t=r,n=await rr("create",{publicKey:{challenge:le(O(t.challenge)),rp:t.rp,user:{...t.user,id:le(O(t.user.id))},pubKeyCredParams:qn(t.pubKeyCredParams),excludeCredentials:(t.excludeCredentials??[]).map(s=>({type:s.type,id:le(O(s.id))})),authenticatorSelection:t.authenticatorSelection,attestation:"none",timeout:t.timeout}},e?.signal,"passkey creation");if(!n)throw yt("passkey creation was cancelled");let i=n.response;return{attestationObject:P(new Uint8Array(i.attestationObject)),clientDataJson:P(new Uint8Array(i.clientDataJSON))}},async get(r,e,t,n){let i=await rr("get",{publicKey:{challenge:le(r),rpId:e,userVerification:n?.userVerification??"preferred",allowCredentials:(t??[]).map(o=>({type:"public-key",id:le(O(o))}))}},n?.signal,"passkey sign-in");if(!i)throw yt("passkey sign-in was cancelled");let s=i.response;return{credentialId:P(new Uint8Array(i.rawId)),authenticatorData:P(new Uint8Array(s.authenticatorData)),clientDataJson:P(new Uint8Array(s.clientDataJSON)),signature:P(new Uint8Array(s.signature))}}}}var nr="calimero.org-recovery.v1\0",mt=64,ht=Uint8Array.from([48,46,2,1,0,48,5,6,3,43,101,112,4,34,4,32]);function Yn(){return crypto.getRandomValues(new Uint8Array(32))}function Jn(r){sr(r);let e=Array.from(r,n=>n.toString(16).padStart(2,"0")).join(""),t=[];for(let n=0;n<e.length;n+=8)t.push(e.slice(n,n+8));return t.join("-")}function zn(r){let e=r.replace(/[-\s]/g,"");if(!/^[0-9a-fA-F]{64}$/.test(e))throw new Error("a recovery seed is 64 hex digits");return Uint8Array.from({length:32},(t,n)=>parseInt(e.slice(2*n,2*n+2),16))}function ir(r,e,t){return new TextEncoder().encode(`${nr}${r}\0${e}\0${t}`)}async function Zn(r){let e=await or(r,!0),t=await crypto.subtle.exportKey("jwk",e);if(!t.x)throw new Error("this runtime cannot export an Ed25519 public key");return t.x}async function wt(r,e,t,n){let i=new TextEncoder().encode(n).length;if(i===0||i>mt)throw new Error(`a recovery nonce is 1 to ${mt} bytes`);let s=await or(r,!1),o=await crypto.subtle.sign("Ed25519",s,ar(ir(e,t,n)));return P(new Uint8Array(o))}function sr(r){if(r.length!==32)throw new Error("a recovery seed is 32 bytes")}function or(r,e){sr(r);let t=new Uint8Array(ht.length+32);return t.set(ht),t.set(r,ht.length),crypto.subtle.importKey("pkcs8",ar(t),{name:"Ed25519"},e,["sign"])}var ar=r=>r.buffer.slice(r.byteOffset,r.byteOffset+r.byteLength);var At=100;function ue(r={}){let e=new URLSearchParams;if(r.after!==void 0&&e.set("after",r.after),r.limit!==void 0){if(!Number.isInteger(r.limit)||r.limit<1||r.limit>At)throw new RangeError(`limit is 1 to ${At}`);e.set("limit",String(r.limit))}let t=e.toString();return t?`?${t}`:""}function de(r,e){try{return se(r,e)}catch{return r<e?-1:r>e?1:0}}function cr(r,e,t=Date.now()/1e3){if(r===null||r.length===0)return null;let n=r.reduce((s,o)=>de(s,o)>=0?s:o),i=null;for(let s of e)s.afterSecs<=t&&de(n,s.version)<0&&(i===null||de(s.version,i.version)>0)&&(i=s);return i}function lr(r,e,t,n){return`calimero-publisher-binding/v1
2
- ${r}
3
- ${e}
1
+ function R(t){return Array.from(t,e=>e.toString(16).padStart(2,"0")).join("")}function me(t,e,r){let n=t.trim();if(!/^[0-9a-fA-F]*$/.test(n)||n.length!==r*2)throw new Error(`${e} must be ${r*2} hex characters, got ${n.length}`);let i=new Uint8Array(r);for(let s=0;s<r;s+=1)i[s]=Number.parseInt(n.slice(s*2,s*2+2),16);return i}function h(...t){let e=new Uint8Array(t.reduce((n,i)=>n+i.length,0)),r=0;for(let n of t)e.set(n,r),r+=n.length;return e}var Lt="Noise_NK_25519_AESGCM_SHA256",Ye=32,Gt=16,Ht=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,110,4,34,4,32]),ze=class t{constructor(e){this.k=null;this.n=0;this.ck=e,this.h=e}static async initialize(){let e=new TextEncoder().encode(Lt),r=new Uint8Array(32);return r.set(e),new t(r)}async mixHash(e){this.h=await Ft(h(this.h,e))}async mixKey(e){let[r,n]=await Cr(this.ck,e);this.ck=r,this.k=await crypto.subtle.importKey("raw",n,"AES-GCM",!1,["encrypt","decrypt"]),this.n=0}async encryptAndHash(e){if(!this.k)throw new Error("Noise: no cipher key yet");let r=new Uint8Array(await crypto.subtle.encrypt({name:"AES-GCM",iv:Tr(this.n),additionalData:this.h},this.k,e));return this.n+=1,await this.mixHash(r),r}async decryptAndHash(e){if(!this.k)throw new Error("Noise: no cipher key yet");let r=new Uint8Array(await crypto.subtle.decrypt({name:"AES-GCM",iv:Tr(this.n),additionalData:this.h},this.k,e));return this.n+=1,await this.mixHash(e),r}split(){return Cr(this.ck,new Uint8Array)}};async function Or(t,e,r){let n=await ze.initialize();await n.mixHash(e),await n.mixHash(t);let i=await q(r);return await n.mixHash(i.publicKey),await n.mixKey(await ee(i.privateKey,t)),{message1:h(i.publicKey,await n.encryptAndHash(new Uint8Array)),async finish(o){if(o.length<Ye+Gt)throw new Error("Noise: message 2 is too short");let a=o.slice(0,Ye);return await n.mixHash(a),await n.mixKey(await ee(i.privateKey,a)),{payload:await n.decryptAndHash(o.slice(Ye)),split:await n.split()}}}}async function q(t){if(!t){let n;try{n=await crypto.subtle.generateKey({name:"X25519"},!0,["deriveBits"])}catch(s){throw new Error(`Sealed transport needs WebCrypto with X25519, which this runtime lacks (${s?.name??"no crypto.subtle"}). Current browsers and Node have it; in React Native, install react-native-quick-crypto as the global crypto.`)}let i=new Uint8Array(await crypto.subtle.exportKey("raw",n.publicKey));return{privateKey:n.privateKey,publicKey:i}}let e=await crypto.subtle.importKey("pkcs8",h(Ht,t),{name:"X25519"},!0,["deriveBits"]),r=await crypto.subtle.exportKey("jwk",e);return{privateKey:e,publicKey:jt(r.x)}}async function ee(t,e){let r=await crypto.subtle.importKey("raw",e,{name:"X25519"},!1,[]);return new Uint8Array(await crypto.subtle.deriveBits({name:"X25519",public:r},t,256))}function Tr(t){let e=new Uint8Array(12);return new DataView(e.buffer).setBigUint64(4,BigInt(t),!1),e}async function Ft(t){return new Uint8Array(await crypto.subtle.digest("SHA-256",t))}async function Je(t,e){let r=await crypto.subtle.importKey("raw",t,{name:"HMAC",hash:"SHA-256"},!1,["sign"]);return new Uint8Array(await crypto.subtle.sign("HMAC",r,e))}async function Cr(t,e){let r=await Je(t,e),n=await Je(r,new Uint8Array([1])),i=await Je(r,h(n,new Uint8Array([2])));return[n,i]}function jt(t){let e=t.replace(/-/g,"+").replace(/_/g,"/"),r=atob(e+"=".repeat((4-e.length%4)%4));return Uint8Array.from(r,n=>n.charCodeAt(0))}var Mr="/sealed/v2/handshake",_r="/sealed/v2",te="application/vnd.calimero.sealed",Ze=2,qt=new TextEncoder().encode("calimero/sealed-http/v2"),re=16,Qt=1+re+8,Yt=0,Jt=1,zt=2,Zt=1+64*1024+16,Xt=1024,Wt=6e4,en="calimero.tee-attest.transport-key.v1",rn=[101,204,205,304],$r=new TextEncoder,ne=class extends Error{constructor(){super("The node no longer holds the attested transport key; attest again for the current one");this.name="StaleTransportKeyError"}},S=class extends Error{constructor(r,n,i,s){super(i);this.status=r;this.code=n;this.retryAfterMs=s;this.name="SealedTransportError"}};async function Xe(t,e){let r=await crypto.subtle.digest("SHA-256",h($r.encode(en),t,e));return new Uint8Array(r)}function We(t){let e=new URL(t.baseUrl),r=e.pathname.replace(/\/+$/,""),n=`${e.origin}${r}`,i=t.fetch??((g,p)=>fetch(g,p)),s=typeof t.transportPublicKey=="function"?t.transportPublicKey:void 0,o=s?Promise.resolve().then(s):Promise.resolve(t.transportPublicKey);o.catch(()=>{});let a,c=async()=>{try{return await Dr(i,n,await Ir(o))}catch(g){if(!(g instanceof ne)||!s)throw g;return o=Promise.resolve().then(s),Dr(i,n,await Ir(o))}},d=async()=>{let g=a??u(void 0),p=await g;if(Date.now()<p.renewAt)return[p,g];let m=u(g);return[await m,m]},u=g=>{if(a===g){let p=c();a=p,p.catch(()=>{a===p&&(a=void 0)})}return a};return async(g,p)=>{let m=new Request(g,p),f=new URL(m.url);if(f.origin!==e.origin||!f.pathname.startsWith(`${r}/`))throw new Error(`Refusing to send ${f.href} outside the sealed node at ${t.baseUrl}`);let b=[];m.headers.forEach((v,H)=>b.push([H,v]));let N={method:m.method,path:f.pathname.slice(r.length)+f.search,headers:b},E=new Uint8Array(await m.arrayBuffer()),k=p?.signal??(g instanceof Request?g.signal:void 0),M=async v=>{let{requestId:H,header:W,envelope:he}=await nn(v,N,E),F=await i(`${n}${_r}`,{method:"POST",headers:{"content-type":te},body:he,signal:k});if(F.headers.get("content-type")!==te)throw await Kr(F);return on(F,v.responseKey,W,H)},[Fe,je]=await d();try{return await M(Fe)}catch(v){if(!(v instanceof S)||v.code!=="unknown_session")throw v;return M(await u(je))}}}async function Ir(t){let e=await t;if(e.length!==32)throw new Error("transportPublicKey must be 32 bytes");return e}async function Dr(t,e,r){try{return await Nr(t,e,r)}catch(n){if(!(n instanceof S)||n.code!=="busy")throw n;return await new Promise(i=>setTimeout(i,n.retryAfterMs??1e3)),Nr(t,e,r)}}async function Nr(t,e,r){let n=await Or(r,qt),i=await t(`${e}${Mr}`,{method:"POST",headers:{"content-type":te},body:h(new Uint8Array([Ze]),r,n.message1)});if(i.headers.get("content-type")!==te)throw await Kr(i);let s=await cn(i,Xt);return tn(n,s)}async function tn(t,e){if(e[0]!==Ze)throw new Error("The handshake reply is malformed");let r;try{r=await t.finish(e.slice(1))}catch{throw new Error("The handshake reply did not open: it did not come from the attested node")}let{payload:n,split:i}=r;if(n.length!==re+4)throw new Error("The handshake reply is malformed");let s=n.slice(0,re),o=new DataView(n.buffer,n.byteOffset).getUint32(re,!1),[a,c]=await Promise.all([crypto.subtle.importKey("raw",i[0],"AES-GCM",!1,["encrypt"]),crypto.subtle.importKey("raw",i[1],"AES-GCM",!1,["decrypt"])]);return i[0].fill(0),i[1].fill(0),{requestKey:a,responseKey:c,nextRequestId:1,renewAt:Date.now()+o*1e3-Wt,header(d){let u=new Uint8Array(Qt);return u[0]=Ze,u.set(s,1),new DataView(u.buffer).setBigUint64(1+re,BigInt(d),!1),u}}}async function nn(t,e,r){let n=t.nextRequestId;t.nextRequestId+=1;let i=t.header(n),s=await crypto.subtle.encrypt({name:"AES-GCM",iv:Br(n,0),additionalData:i},t.requestKey,sn(e,r));return{requestId:n,header:i,envelope:h(i,new Uint8Array(s))}}function Br(t,e){let r=new Uint8Array(12),n=new DataView(r.buffer);return n.setBigUint64(0,BigInt(t),!1),n.setUint32(8,e,!1),r}function sn(t,e){let r=$r.encode(JSON.stringify(t)),n=new Uint8Array(4);return new DataView(n.buffer).setUint32(0,r.length,!1),h(n,r,e)}async function on(t,e,r,n){if(!t.body)throw new Error("The sealed response has no body");let i=an(t.body.getReader()),s=0,o=async()=>{let u=await i.next();if(!u)return null;let g;try{g=new Uint8Array(await crypto.subtle.decrypt({name:"AES-GCM",iv:Br(n,s),additionalData:r},e,u))}catch{throw new Error("A sealed response frame did not open: it was not sealed by the attested node")}return s+=1,{kind:g[0],data:g.slice(1)}},a=await o();if(!a||a.kind!==Yt)throw new Error("The sealed response is malformed");let c=JSON.parse(new TextDecoder().decode(a.data));if(rn.includes(c.status))return await i.cancel(),new Response(null,{status:c.status,headers:c.headers});let d=new ReadableStream({async pull(u){try{let g=await o();g?g.kind===Jt?u.enqueue(g.data):g.kind===zt?(u.close(),await i.cancel()):u.error(new Error("The sealed response is malformed")):u.error(new Error("The sealed response was cut short"))}catch(g){u.error(g)}},cancel(){return i.cancel()}});return new Response(d,{status:c.status,headers:c.headers})}function an(t){let e=new Uint8Array,r=async n=>{for(;e.length<n;){let{done:i,value:s}=await t.read();if(i)return!1;e=h(e,s)}return!0};return{async next(){if(!await r(4))return null;let n=new DataView(e.buffer,e.byteOffset).getUint32(0,!1);if(n>Zt)throw await t.cancel(),new Error("The sealed response is malformed: a frame is larger than the node sends");if(!await r(4+n))return null;let i=e.slice(4,4+n);return e=e.slice(4+n),i},cancel:()=>t.cancel()}}async function cn(t,e){if(!t.body)return new Uint8Array;let r=t.body.getReader(),n=new Uint8Array;for(;;){let{done:i,value:s}=await r.read();if(i)return n;if(n=h(n,s),n.length>e)throw await r.cancel(),new Error("The handshake reply is malformed: it is too long")}}async function Kr(t){let e,r=`Sealed request refused: HTTP ${t.status}`;try{let s=await t.json();e=s?.error?.code,s?.error?.message&&(r=`Sealed request refused: ${s.error.message}`)}catch{}if(e==="stale_transport_key")return new ne;let n=Number(t.headers.get("retry-after")),i=Number.isFinite(n)&&n>0?Math.min(n,5)*1e3:void 0;return new S(t.status,e,r,i)}var Vr=[{uri:"https://fulcio.sigstore.dev",validFor:{start:"2021-03-07T03:20:29Z",end:"2022-12-31T23:59:59.999Z"},certChain:["MIIB+DCCAX6gAwIBAgITNVkDZoCiofPDsy7dfm6geLbuhzAKBggqhkjOPQQDAzAqMRUwEwYDVQQKEwxzaWdzdG9yZS5kZXYxETAPBgNVBAMTCHNpZ3N0b3JlMB4XDTIxMDMwNzAzMjAyOVoXDTMxMDIyMzAzMjAyOVowKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTB2MBAGByqGSM49AgEGBSuBBAAiA2IABLSyA7Ii5k+pNO8ZEWY0ylemWDowOkNa3kL+GZE5Z5GWehL9/A9bRNA3RbrsZ5i0JcastaRL7Sp5fp/jD5dxqc/UdTVnlvS16an+2Yfswe/QuLolRUCrcOE2+2iA5+tzd6NmMGQwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEwHQYDVR0OBBYEFMjFHQBBmiQpMlEk6w2uSu1KBtPsMB8GA1UdIwQYMBaAFMjFHQBBmiQpMlEk6w2uSu1KBtPsMAoGCCqGSM49BAMDA2gAMGUCMH8liWJfMui6vXXBhjDgY4MwslmN/TJxVe/83WrFomwmNf056y1X48F9c4m3a3ozXAIxAKjRay5/aj/jsKKGIkmQatjI8uupHr/+CxFvaJWmpYqNkLDGRU+9orzh5hI2RrcuaQ=="]},{uri:"https://fulcio.sigstore.dev",validFor:{start:"2022-04-13T20:06:15Z"},certChain:["MIICGjCCAaGgAwIBAgIUALnViVfnU0brJasmRkHrn/UnfaQwCgYIKoZIzj0EAwMwKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTAeFw0yMjA0MTMyMDA2MTVaFw0zMTEwMDUxMzU2NThaMDcxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjEeMBwGA1UEAxMVc2lnc3RvcmUtaW50ZXJtZWRpYXRlMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE8RVS/ysH+NOvuDZyPIZtilgUF9NlarYpAd9HP1vBBH1U5CV77LSS7s0ZiH4nE7Hv7ptS6LvvR/STk798LVgMzLlJ4HeIfF3tHSaexLcYpSASr1kS0N/RgBJz/9jWCiXno3sweTAOBgNVHQ8BAf8EBAMCAQYwEwYDVR0lBAwwCgYIKwYBBQUHAwMwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQU39Ppz1YkEZb5qNjpKFWixi4YZD8wHwYDVR0jBBgwFoAUWMAeX5FFpWapesyQoZMi0CrFxfowCgYIKoZIzj0EAwMDZwAwZAIwPCsQK4DYiZYDPIaDi5HFKnfxXx6ASSVmERfsynYBiX2X6SJRnZU84/9DZdnFvvxmAjBOt6QpBlc4J/0DxvkTCqpclvziL6BCCPnjdlIB3Pu3BxsPmygUY7Ii2zbdCdliiow=","MIIB9zCCAXygAwIBAgIUALZNAPFdxHPwjeDloDwyYChAO/4wCgYIKoZIzj0EAwMwKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTAeFw0yMTEwMDcxMzU2NTlaFw0zMTEwMDUxMzU2NThaMCoxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjERMA8GA1UEAxMIc2lnc3RvcmUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAT7XeFT4rb3PQGwS4IajtLk3/OlnpgangaBclYpsYBr5i+4ynB07ceb3LP0OIOZdxexX69c5iVuyJRQ+Hz05yi+UF3uBWAlHpiS5sh0+H2GHE7SXrk1EC5m1Tr19L9gg92jYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRYwB5fkUWlZql6zJChkyLQKsXF+jAfBgNVHSMEGDAWgBRYwB5fkUWlZql6zJChkyLQKsXF+jAKBggqhkjOPQQDAwNpADBmAjEAj1nHeXZp+13NWBNa+EDsDP8G1WWg1tCMWP/WHPqpaVo0jhsweNFZgSs0eE7wYI4qAjEA2WB9ot98sIkoF3vZYdd3/VtWB5b9TNMea7Ix/stJ5TfcLLeABLE4BNJOsQ4vnBHJ"]}],Lr=[{baseUrl:"https://rekor.sigstore.dev",logId:"c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d",publicKey:"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE2G2Y+2tabdTV5BcGiBIx0a9fAFwrkBbmLSGtks4L3qX6yYY0zufBnhC8Ur/iy55GhWP/9A/bY2LhC30M9+RYtw==",validFor:{start:"2021-01-12T11:53:27Z"}}];var ln="1.2.840.10045.2.1",dn={"1.2.840.10045.3.1.7":"P-256","1.3.132.0.34":"P-384"},un={"P-256":32,"P-384":48},gn={"1.2.840.10045.4.3.2":"SHA-256","1.2.840.10045.4.3.3":"SHA-384"};function Gr(t,e,r){if(e+2>r)throw new Error("it is truncated");let n=t[e];if((n&31)===31)throw new Error("it uses a tag this parser does not read");let i=t[e+1],s=e+2;if(i&128){let a=i&127;if(a===0||a>4||s+a>r)throw new Error("it has a length this parser does not read");i=0;for(let c=0;c<a;c+=1)i=i*256+t[s+c];s+=a}let o=s+i;if(o>r)throw new Error("it is truncated");return{tag:n,bytes:t,offset:e,start:s,end:o}}function Y(t){let e=Gr(t,0,t.length);if(e.end!==t.length)throw new Error("it has trailing bytes");return e}function A(t){let e=[];for(let r=t.start;r<t.end;){let n=Gr(t.bytes,r,t.end);e.push(n),r=n.end}return e}function w(t,e,r){if(!t||t.tag!==e)throw new Error(`${r} is not where it should be`);return t}function T(t){return t.bytes.slice(t.start,t.end)}function we(t){return t.bytes.slice(t.offset,t.end)}function Q(t){let e=T(w(t,6,"An object identifier"));if(e.length===0||e[e.length-1]&128)throw new Error("it has a malformed object identifier");let r=[],n=0;for(let o of e)n=n*128+(o&127),o&128||(r.push(n),n=0);let i=r.shift();return[...i<80?[Math.floor(i/40),i%40]:[2,i-80],...r].join(".")}function pn(t){let e=new TextDecoder().decode(T(t)),r=t.tag===23?/^(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})Z$/.exec(e):null,n=t.tag===24?/^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})Z$/.exec(e):null,i=r??n;if(!i)throw new Error(`it holds the time ${JSON.stringify(e)}, which is not one a certificate may hold`);let s=Number(i[1]);r&&(s+=s<50?2e3:1900);let[o,a,c,d,u]=i.slice(2).map(Number);return Date.UTC(s,o-1,a,c,d,u)}function er(t){try{let[e,r,n,...i]=A(w(Y(t),48,"The certificate"));if(i.length>0)throw new Error("it has fields after its signature");let s=A(w(e,48,"The signed part")),o=s[0]?.tag===160?1:0,[a,c,d,u,g,p,...m]=s.slice(o);w(a,2,"The serial number");let f=Q(A(w(r,48,"The signature algorithm"))[0]);if(Q(A(w(c,48,"The signature algorithm"))[0])!==f)throw new Error("it names two different signature algorithms");let N=gn[f];if(!N)throw new Error(`it is signed with ${f}, not ECDSA with SHA-256 or SHA-384`);let[E,k]=A(w(u,48,"The validity")).map(pn);if(k===void 0)throw new Error("its validity is incomplete");let[M,Fe]=A(w(p,48,"The public key"));w(Fe,3,"The public key");let[je,v]=A(w(M,48,"The key algorithm"));if(Q(je)!==ln)throw new Error("its key is not an elliptic-curve key");let H=dn[Q(v)];if(!H)throw new Error("its key is on a curve other than P-256 or P-384");let W=new Map,he=m.find(qe=>qe.tag===163);if(he){let[qe]=A(he);for(let Vt of A(w(qe,48,"The extensions"))){let j=A(w(Vt,48,"An extension"));if(j.length===3)w(j[1],1,"An extension's critical flag");else if(j.length!==2)throw new Error("it has a malformed extension");let Qe=Q(j[0]);if(W.has(Qe))throw new Error(`it has extension ${Qe} twice`);W.set(Qe,T(w(j[j.length-1],4,"An extension value")))}}let F=T(w(n,3,"The signature"));if(F[0]!==0)throw new Error("its signature is not a whole number of bytes");return{der:t,tbs:we(e),signatureHash:N,signature:F.slice(1),issuer:we(w(d,48,"The issuer")),subject:we(w(g,48,"The subject")),notBefore:E,notAfter:k,spki:we(p),curve:H,extensions:W}}catch(e){throw new Error(`The certificate is malformed: ${e.message}`)}}function Hr(t){return A(w(Y(t),48,"The list")).map(Q)}function fn(t,e){let r=un[e],n=A(w(Y(t),48,"The signature"));if(n.length!==2)throw new Error("The signature is not an ECDSA signature");let i=new Uint8Array(r*2);return n.forEach((s,o)=>{let a=T(w(s,2,"The signature"));if(a.length===0||a[0]&128)throw new Error("The signature is not an ECDSA signature");for(;a.length>1&&a[0]===0;)a=a.subarray(1);if(a.length>r)throw new Error("The signature is not an ECDSA signature");i.set(a,o*r+r-a.length)}),i}async function Ae(t,e,r,n,i){let s;try{s=fn(n,e)}catch{return!1}let o=await crypto.subtle.importKey("spki",t,{name:"ECDSA",namedCurve:e},!1,["verify"]);return crypto.subtle.verify({name:"ECDSA",hash:r},o,s,i)}function x(t,e){let r=t.replace(/\s+/g,"");if(!/^[A-Za-z0-9+/]*={0,2}$/.test(r)||r.length%4!==0)throw new Error(`${e} is not base64`);let n=atob(r),i=new Uint8Array(n.length);for(let s=0;s<n.length;s+=1)i[s]=n.charCodeAt(s);return i}function rr(t,e){let r=[...t.matchAll(/-----BEGIN CERTIFICATE-----([^-]*)-----END CERTIFICATE-----/g)];if(r.length!==1||t.replace(r[0][0],"").trim()!=="")throw new Error(`${e} is not exactly one PEM certificate`);return x(r[0][1],e)}var yn="2.5.29.17",hn="2.5.29.37",mn="1.3.6.1.5.5.7.3.3",wn="1.3.6.1.4.1.57264.1.8",An="1.3.6.1.4.1.57264.1.1",bn=134,En=12,Rn=48,Pn=new TextEncoder,J=t=>new TextDecoder().decode(t);async function be(t,e,r,n){let{base64Signature:i,cert:s,rekorBundle:o}=Un(e),a=o.Payload;if(n!==void 0&&n.trim()!==i.trim())throw new Error("The detached signature is not the one in the bundle");let c=x(i,"The bundle signature"),d=rr(J(x(s,"The bundle certificate")),"The bundle certificate"),u=er(d),g=Lr.find(k=>k.logId===a.logID.toLowerCase());if(!g)throw new Error(`The bundle names Rekor log ${a.logID}, which the Sigstore trust root does not know`);let p=Pn.encode(`{"body":${JSON.stringify(a.body)},"integratedTime":${a.integratedTime},"logID":${JSON.stringify(a.logID)},"logIndex":${a.logIndex}}`);if(!await Ae(x(g.publicKey,"The Rekor key"),"P-256","SHA-256",x(o.SignedEntryTimestamp,"The signed entry timestamp"),p))throw new Error("Rekor's signed entry timestamp does not verify: the log entry, its time or its index was altered");let f=a.integratedTime*1e3;if(!qr(f,g.validFor))throw new Error(`Rekor log ${g.baseUrl} was not in use at ${ie(f)}, when the entry says it was logged`);let b=Sn(a.body),N=R(new Uint8Array(await crypto.subtle.digest("SHA-256",t)));if(b.hash!==N)throw new Error("The file's SHA-256 is not the one Rekor logged: the file is not the one signed");if(!tr(x(b.signature,"The logged signature"),c))throw new Error("The bundle's signature is not the one Rekor logged");let E=rr(J(x(b.publicKey,"The logged certificate")),"The logged certificate");if(!tr(E,d))throw new Error("The bundle's certificate is not the one Rekor logged");if(u.curve!=="P-256"||!await Ae(u.spki,"P-256","SHA-256",c,t))throw new Error("The signature over the file does not verify with the bundle's certificate");return await vn(u,f),kn(u,r),{integratedTime:a.integratedTime}}async function vn(t,e){if(!jr(t,e))throw new Error(`The signing certificate was valid ${ie(t.notBefore)} to ${ie(t.notAfter)}, not at ${ie(e)} when Rekor logged it`);let r=[];for(let n of Vr){let i=n.certChain.map(o=>er(x(o,"A Fulcio certificate")));if(!await Fr(t,i[0]))continue;let s=await xn(i,n.validFor,e);if(!s)return;r.push(`${n.uri} (valid from ${n.validFor.start}): ${s}`)}throw new Error(r.length>0?`The signing certificate's CA is not trusted at ${ie(e)}: ${r.join("; ")}`:"The signing certificate was not issued by a Fulcio CA in the Sigstore trust root")}async function xn(t,e,r){if(!qr(r,e))return"the trust root says it was not issuing certificates then";for(let[n,i]of t.entries()){if(!jr(i,r))return`its certificate ${n} was not valid then`;let s=t[n+1]??i;if(!await Fr(i,s))return`its certificate ${n} is not signed by the next`}}async function Fr(t,e){return tr(t.issuer,e.subject)?Ae(e.spki,e.curve,t.signatureHash,t.signature,t.tbs):!1}function kn(t,e){let r=t.extensions.get(yn);if(!r)throw new Error("The signing certificate names no identity");let n=A(w(Y(r),Rn,"The subject alternative name")),i=n.filter(d=>d.tag===bn).map(d=>J(T(d)));if(i.length!==1||n.length!==1||i[0]!==e.identity)throw new Error(`The release was signed by ${JSON.stringify(i.length===1?i[0]:i)}, not by ${e.identity}`);let s=t.extensions.get(wn),o=t.extensions.get(An),a=s?J(T(w(Y(s),En,"The OIDC issuer"))):o?J(o):void 0;if(a!==e.issuer)throw new Error(`The signing certificate's OIDC issuer is ${a===void 0?"missing":JSON.stringify(a)}, not ${e.issuer}`);let c=t.extensions.get(hn);if(!c||!Hr(c).includes(mn))throw new Error("The signing certificate is not for code signing")}function Un(t){let e=t;if(typeof e=="string")try{e=JSON.parse(e)}catch{throw new Error("The bundle is not JSON")}let r=e,n=r?.rekorBundle?.Payload;if(!(typeof r?.base64Signature=="string"&&typeof r.cert=="string"&&typeof r.rekorBundle?.SignedEntryTimestamp=="string"&&typeof n?.body=="string"&&typeof n.logID=="string"&&/^[0-9a-fA-F]{64}$/.test(n.logID)&&Number.isSafeInteger(n.integratedTime)&&n.integratedTime>=0&&Number.isSafeInteger(n.logIndex)&&n.logIndex>=0))throw new Error("The bundle is not a cosign bundle with a Rekor entry");return r}function Sn(t){let e;try{e=JSON.parse(J(x(t,"The logged entry")))}catch{throw new Error("The logged entry is not JSON")}let r=e?.spec?.data?.hash,n=e?.spec?.signature;if(e?.kind!=="hashedrekord"||r?.algorithm!=="sha256"||typeof r.value!="string"||typeof n?.content!="string"||typeof n.publicKey?.content!="string")throw new Error("The logged entry is not a SHA-256 hashedrekord");return{hash:r.value.toLowerCase(),signature:n.content,publicKey:n.publicKey.content}}function jr(t,e){return t.notBefore<=e&&e<=t.notAfter}function qr(t,e){return Date.parse(e.start)<=t&&(e.end===void 0||t<=Date.parse(e.end))}function ie(t){return new Date(t).toISOString()}function tr(t,e){return t.length===e.length&&t.every((r,n)=>r===e[n])}var Tn=/^[0-9a-f]{96}$/,Cn=["mrtd","rtmr0","rtmr1","rtmr2","rtmr3"];function $(t){let e=z(t.allowedMrtd??[],"allowedMrtd"),r=(t.allowedMeasurements??[]).map((a,c)=>{let d=`allowedMeasurements[${c}]`;return Cn.map(u=>z([a?.[u]??""],`${d}.${u}`)[0]).join()}),n=[z(t.allowedRtmr0??[],"allowedRtmr0"),z(t.allowedRtmr1??[],"allowedRtmr1"),z(t.allowedRtmr2??[],"allowedRtmr2"),z(t.allowedRtmr3??[],"allowedRtmr3")];if(t.allowedMeasurements!==void 0&&r.length===0)throw new Error("allowedMeasurements is empty, so no quote would ever be accepted");if(r.length===0){if(e.length===0)throw new Error("No image is trusted: give allowedMeasurements, or allowedMrtd with allowedRtmr1-3");if(n.slice(1).some(a=>a.length===0))throw new Error("allowedMrtd alone does not name an image: the MRTD measures the TD firmware, which images share, and the image is in RTMR1-3. Give allowedMeasurements, or allowedRtmr1-3 too")}let i=t.allowedTcbStatuses??["UpToDate"],s=t.now??Date.now;return Object.assign(async({quoteB64:a,nonce:c,reportDataSuffix:d,collateral:u})=>{let g=In(a),p=u??await t.fetchCollateral?.(g);if(!p)throw new Error("The node sent no collateral for its quote, and no fetchCollateral was given to get it");let m;try{m=t.dcapVerify(g,p,Math.floor(s()/1e3))}catch(E){throw new Error(`The quote did not verify: ${E?.message??String(E)}`)}if(m.status==="Revoked"||!i.includes(m.status))throw new Error(`The platform's TCB status is ${m.status}, which is not accepted`);let f=On(m.report);if(f.tdAttributes?.length!==8||(f.tdAttributes[0]&1)!==0)throw new Error("The quote is from a debug TD, or its TD attributes cannot be read");let b=[f.mrTd,f.rtMr0,f.rtMr1,f.rtMr2,f.rtMr3].map(E=>R(E));if(r.length>0&&!r.includes(b.join()))throw new Error(`The measurements (MRTD ${b[0]}, RTMR0-3 ${b.slice(1).join(", ")}) are not an image this verifier trusts`);if(e.length>0&&!e.includes(b[0]))throw new Error(`MRTD ${b[0]} is not an image this verifier trusts`);if([f.rtMr0,f.rtMr1,f.rtMr2,f.rtMr3].forEach((E,k)=>{let M=n[k];if(M.length>0&&!M.includes(R(E)))throw new Error(`RTMR${k} ${R(E)} is not one this verifier trusts`)}),R(f.reportData)!==`${c}${d}`.toLowerCase())throw new Error("The quote does not commit to this nonce and binding");return!0},{includeCollateral:!0})}function z(t,e){return t.map(r=>{let n=r.trim().toLowerCase();if(!Tn.test(n))throw new Error(`${e} holds ${JSON.stringify(r)}, which is not a 48-byte hex measurement`);return n})}function On(t){let e=t.data;if(t.type==="td10"&&e)return e;if(t.type==="td15"&&e?.base)return e.base;throw new Error(`The quote is a ${t.type} quote, not a TDX one`)}function In(t){let e=atob(t),r=new Uint8Array(e.length);for(let n=0;n<e.length;n+=1)r[n]=e.charCodeAt(n);return r}var Dn=["UpToDate","SWHardeningNeeded","ConfigurationNeeded","ConfigurationAndSWHardeningNeeded","OutOfDate","OutOfDateConfigurationNeeded"],_="locked-read-only";function nr(t,{profile:e,allowDebugProfile:r=!1}){if(t.length===0)throw new Error("No release given, so no image would be trusted");let n,i=t.map((s,o)=>{let a=s?.tag??`releases[${o}]`;if(s?.role!==void 0&&s.role!=="node")throw new Error(`${a} lists the measurements of a ${s.role}, not of a node image`);let c=s?.profiles?.[e];if(!c){let u=Object.keys(s?.profiles??{}).join(", ")||"none";throw new Error(`${a} has no profile ${JSON.stringify(e)} (it has: ${u})`)}if(e!==_&&!r)throw new Error(`${JSON.stringify(e)} is not a production profile: its image is readable by whoever operates the node. Trust ${JSON.stringify(_)}, or pass allowDebugProfile to test`);let d=(c.allowed_tcb_statuses??["uptodate"]).map(u=>Nn(u,a));return n=n===void 0?d:n.filter(u=>d.includes(u)),{mrtd:c.mrtd,rtmr0:c.rtmr0,rtmr1:c.rtmr1,rtmr2:c.rtmr2,rtmr3:c.rtmr3}});if(!n||n.length===0)throw new Error("The releases given accept no TCB status in common");return{allowedMeasurements:i,allowedTcbStatuses:n}}function Nn(t,e){let r=Dn.find(n=>n.toLowerCase()===String(t).toLowerCase());if(!r)throw new Error(`${e} accepts TCB status ${JSON.stringify(t)}, which this verifier does not know`);return r}var ir=Object.freeze({identity:"https://github.com/calimero-network/mero-tee/.github/workflows/release-node-image-gcp.yaml@refs/heads/master",issuer:"https://token.actions.githubusercontent.com"}),Mn=["mrtd","rtmr0","rtmr1","rtmr2","rtmr3"],Ee="https://cloud.calimero.network",sr=`${Ee}/api/tee/pcs`;async function Yr(t,e,r={}){let n=typeof t=="string"?new TextEncoder().encode(t):t;await be(n,e,{identity:r.identity??ir.identity,issuer:r.issuer??ir.issuer},r.signature);let i;try{i=JSON.parse(new TextDecoder().decode(n))}catch{throw new Error("The signed release is not JSON")}if(i?.role!=="node")throw new Error(`The signed release is a ${JSON.stringify(i?.role)} release, not a node one`);let s=Object.values(i.profiles??{}),o=a=>Mn.every(c=>/^[0-9a-f]{96}$/i.test(String(a?.[c])));if(typeof i.tag!="string"||s.length===0||!s.every(o))throw new Error("The signed file is not a release's published-mrtds.json: it lists no measured profiles");if(r.expectedVersion!==void 0&&i.tag!==r.expectedVersion)throw new Error(`The signed release is ${i.tag}, not ${r.expectedVersion}`);return i}async function or(t,e={}){let r=await(e.fetch??fetch)(t,{headers:{accept:"application/json"}});if(!r.ok)throw new Error(`Fetching the node release from ${t} failed: HTTP ${r.status}`);let n;try{n=(await r.json())?.data}catch{throw new Error(`${t} did not answer with JSON`)}if(typeof n?.version!="string"||typeof n.publishedMrtds!="string"||typeof n.bundle!="string")throw new Error(`${t} did not answer with a signed node release`);return{version:n.version,publishedMrtds:n.publishedMrtds,bundle:n.bundle}}var Jr="https://github.com/calimero-network/mero-tee/releases/download";async function ar(t,e={}){let r=`mero-tee-v${C(t,"version")}`,n=`${(e.base??Jr).replace(/\/+$/,"")}/${r}/published-mrtds.json`,i=async a=>{let c=await(e.fetch??fetch)(a);if(!c.ok)throw new Error(`Fetching ${a} failed: HTTP ${c.status}`);return c.text()},[s,o]=await Promise.all([i(n),i(`${n}.bundle.json`)]);return{version:t,publishedMrtds:s,bundle:o}}function cr(t,e){return`${t.replace(/\/+$/,"")}/api/tee/node-releases/${C(e,"version")}`}async function Re(t){let e=C(t.minReleaseVersion,"minReleaseVersion"),r=C(t.release?.version,"The release version"),n=await Yr(t.release.publishedMrtds,t.release.bundle,{expectedVersion:r,identity:t.identity,issuer:t.issuer});if(se(r,e)<0)throw new Error(`Release ${r} is older than the minimum trusted, ${e}`);return nr([n],{profile:t.profile,allowDebugProfile:t.allowDebugProfile})}function _n(t){return C(t.minReleaseVersion,"minReleaseVersion"),Object.assign(async r=>{let n=await Re({release:await t.release(),profile:t.profile,allowDebugProfile:t.allowDebugProfile,minReleaseVersion:t.minReleaseVersion,identity:t.identity,issuer:t.issuer});return $({dcapVerify:t.dcapVerify,fetchCollateral:t.fetchCollateral,now:t.now,...n})(r)},{includeCollateral:!0})}var zr=/^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/;function C(t,e){let r=typeof t=="string"?zr.exec(t):null,n=r?.[4];if(!r||n!==void 0&&n.split(".").some(i=>i===""))throw new Error(`${e} is ${JSON.stringify(t)}, not a release version like 2.3.87`);return t}function se(t,e){let[r,n]=Qr(t),[i,s]=Qr(e);for(let c=0;c<3;c+=1)if(r[c]!==i[c])return r[c]<i[c]?-1:1;if(n===void 0||s===void 0)return n===s?0:n===void 0?1:-1;let o=n.split("."),a=s.split(".");for(let c=0;c<Math.max(o.length,a.length);c+=1){let[d,u]=[o[c],a[c]];if(d===void 0||u===void 0)return d===void 0?-1:1;let[g,p]=[/^\d+$/.test(d),/^\d+$/.test(u)],m=g&&p?Math.sign(Number(d)-Number(u)):g!==p?g?-1:1:d<u?-1:d>u?1:0;if(m!==0)return m}return 0}function Qr(t){let e=zr.exec(t);return[[Number(e[1]),Number(e[2]),Number(e[3])],e[4]]}var Xr="MOCK_TDX_QUOTE_V1";function $n(t){let e=atob(t),r=new Uint8Array(e.length);for(let n=0;n<e.length;n++)r[n]=e.charCodeAt(n);return r}function lr(t,e){if(t.length!==e.length)return!1;let r=0;for(let n=0;n<t.length;n++)r|=t[n]^e[n];return r===0}var Zr;async function dr(t){Zr??(Zr=import("@phala/dcap-qvl"));let e=await Zr,r=typeof e[t]=="function"?e[t]:e.default?.[t];if(typeof r!="function")throw new TypeError(`@phala/dcap-qvl loaded without ${t}`);return r}function Wr(t,e){let r=C(e,"minReleaseVersion"),n=String(t.release?.version??"").trim().replace(/^mero-tee-v/,"").replace(/^v/,""),i=C(n,"The release the node names");if(se(i,r)<0)throw new Error(`mero-tee release ${i} is older than the minimum ${r}`);return i}async function Bn(t,e,r){let n=e.releaseSource;return typeof n=="function"?n(t):n==="github"?ar(t,{fetch:r}):or(cr(n??Ee,t),{fetch:r})}function Kn(t){let e=t.collateralSource??sr;return e==="intel"?async r=>(await dr("getCollateralFromPcs"))(r):async r=>(await dr("getCollateral"))(e,r)}function et(t,e){let r=e.maxCollateralAgeDays;return r===void 0?t:async n=>{let i=await t(n),s;try{s=Date.parse(JSON.parse(i.tcb_info).issueDate??"")}catch{s=Number.NaN}if(!Number.isFinite(s))throw new Error("The quote's collateral names no TCB info issue date");let o=((e.now??Date.now)()-s)/864e5;if(o>r)throw new Error(`The quote's collateral was issued ${Math.floor(o)} days ago, more than the ${r} this client accepts`);return i}}async function Vn(t,e,r,n){let i=Wr(t,r.minReleaseVersion),s=await Re({release:await Bn(i,r,n),profile:r.profile??_,allowDebugProfile:r.allowDebugProfile,minReleaseVersion:r.minReleaseVersion,identity:r.identity,issuer:r.issuer}),o=et(r.fetchCollateral??Kn(r),r);return $({dcapVerify:r.dcapVerify??await dr("verify"),fetchCollateral:o,now:r.now,...s})(e)}async function ur(t,e,r=(n,i)=>fetch(n,i)){let n=R(crypto.getRandomValues(new Uint8Array(32))),i=new URL(`${t.replace(/\/+$/,"")}/attestation`);i.searchParams.set("nonce",n),e.appHash&&i.searchParams.set("appHash",e.appHash);let s=await r(i.toString());if(!s.ok)throw new Error(`The node refused to attest: HTTP ${s.status}`);let o=await s.json(),a=me(o.transportKey,"transportKey",32),c=e.appHash?me(e.appHash,"appHash",32):new Uint8Array(32),d=await Xe(c,a),u=$n(o.quote),g=new TextEncoder().encode(Xr);if(lr(u.slice(0,g.length),g)){if(!e.allowMock)throw new Error("mock quote refused: this client only trusts real TEEs");let f=u.slice(g.length,g.length+64);if(!lr(f.slice(0,32),me(n,"nonce",32))||!lr(f.slice(32),d))throw new Error("the quote does not bind this transport key, app and nonce");return a}let p={quoteB64:o.quote,nonce:n,reportDataSuffix:R(d)},m;if(e.verifyQuote)m=await e.verifyQuote(p);else if(e.release)m=await Vn(o,p,e.release,r);else throw new Error("real quote refused: this client trusts no TD image (set policy.release)");if(!m)throw new Error("The attestation did not verify, so its transport key is not trusted");return a}var gr="https://manager.cloud.calimero.network/api/v2/directory";var U=class extends Error{constructor(r,n,i,s,o){super(`directory for cluster ${r}: ${i}`);this.cluster=r;this.reason=n;this.status=s;this.cause=o;this.name="DirectoryError"}};function Ln(t,e){return`${t.replace(/\/+$/,"")}/${encodeURIComponent(e)}`}async function pr(t,e,r){let n;try{n=await r(Ln(t,e),{method:"GET",headers:{accept:"application/json"}})}catch(u){throw new U(e,"unreachable",`could not be reached: ${String(u)}`,void 0,u)}if(n.status===404)throw new U(e,"not-found","unknown cluster",404);if(!n.ok)throw new U(e,"unreachable",`answered ${n.status}`,n.status);let i;try{i=await n.json()}catch(u){throw new U(e,"bad-response","answered something other than JSON",n.status,u)}let s=i;if(!s||typeof s!="object"||!Array.isArray(s.nodes))throw new U(e,"bad-response","answered no node list",n.status);let o=[],a=new Set;for(let u of s.nodes){let g=Gn(u);g&&!a.has(g.url)&&(a.add(g.url),o.push(g))}if(o.length===0)throw new U(e,"empty","lists no usable node",n.status);let c=s.refreshAfterSeconds,d=typeof c=="number"&&Number.isFinite(c)&&c>=1?c:60;return{nodes:o,refreshAfterSeconds:d}}function Gn(t){if(!t||typeof t!="object")return;let{url:e,zone:r,weight:n}=t;if(typeof e!="string"||typeof n!="number"||!Number.isInteger(n)||n<1)return;let i;try{i=new URL(e)}catch{return}if(!(i.protocol!=="https:"&&i.protocol!=="http:"))return{url:e.replace(/\/+$/,""),zone:typeof r=="string"?r:void 0,weight:n}}function fr(t,e,r){let n=e===void 0?[]:t.filter(s=>s.zone===e),i=e===void 0?t:t.filter(s=>s.zone!==e);return[...rt(n,r),...rt(i,r)]}function rt(t,e){let r=[...t],n=[];for(;r.length>0;){let i=e()*r.reduce((o,a)=>o+a.weight,0),s=0;for(;s<r.length-1&&i>=r[s].weight;)i-=r[s++].weight;n.push(r.splice(s,1)[0].url)}return n}var y=class extends Error{constructor(r,n,i,s={}){super(`${r} ${n}: ${i}`);this.status=r;this.code=n;this.details=s;this.name="CalimeroError"}},B=class extends y{constructor(e,r={}){super(401,"UNAUTHENTICATED",e,r),this.name="LoginRequired"}},Pe=class extends y{constructor(e,r={}){super(401,"PASSKEY_UNKNOWN_HERE",e||"this passkey belongs to another Calimero cluster or was removed from this one",r),this.name="PasskeyUnknownHere"}},K=class extends y{constructor(e,r={}){super(421,"WRONG_NODE",e,r),this.name="WrongNode"}},ve=class extends y{constructor(e,r={}){super(404,"NOT_FOUND",e,r),this.name="NotFound"}},Z=class extends y{constructor(e,r={}){super(412,"CONFIRM_REQUIRED",e,r),this.name="ConfirmRequired"}},oe=class extends Error{constructor(r){super("the passkey confirmation was cancelled");this.cause=r;this.name="ConfirmCancelled"}},ae=class extends Error{constructor(r){super("the passkey prompt was blocked by the browser or a password manager");this.cause=r;this.name="ConfirmPromptBlocked"}},xe=class extends y{constructor(e,r={}){super(413,"ARGS_TOO_LARGE",e,r),this.name="ArgsTooLarge"}},ke=class extends y{constructor(e,r={}){super(409,"IDEMPOTENCY_MISMATCH",e,r),this.name="IdempotencyMismatch"}},Ue=class extends y{constructor(e,r={}){super(409,"RELEASE_DEADLINE",e,r),this.name="ReleaseDeadlineError",this.release=typeof r.release=="string"?r.release:"",this.after=typeof r.after=="string"?r.after:""}},Se=class extends y{constructor(e,r={}){super(409,"CONSENT_STALE",e,r),this.name="ConsentStale"}},V=class extends y{constructor(e,r={}){let n=typeof r.origin=="string"?r.origin:"",i=typeof r.package=="string"?r.package:"",s=n?`this site (${n})`:"this site";super(403,"ORIGIN_NOT_REGISTERED",`${s} is not registered for ${i||"any package"}${e?` (${e})`:""}`,r),this.name="OriginNotRegistered",this.origin=n,this.package=i,this.nodeMessage=e}},Te=class extends y{constructor(e,r,n={}){super(400,e,r,n),this.name="BadOrigin"}},Ce=class extends y{constructor(e,r={}){super(409,"ORIGIN_TAKEN",e,r),this.name="OriginTaken"}},Oe=class extends y{constructor(e,r={}){super(400,"NOT_SERVING",e,r),this.name="NotServing"}},Ie=class extends y{constructor(e,r={}){super(409,"CLUSTER_NOT_UPGRADED",e,r),this.name="ClusterNotUpgraded"}},De=class extends y{constructor(e,r={}){super(409,"RECOVERY_NOT_READY",e,r),this.name="RecoveryNotReady",this.readyAt=typeof r.readyAt=="number"?r.readyAt:void 0}},ce=class extends y{constructor(e,r={}){super(401,"UNAUTHENTICATED",e||"unknown or used recovery code",r),this.name="WrongRecoveryCode"}},Ne=class extends y{constructor(e,r={}){super(403,"SIGN_UP_REFUSED",e,r),this.name="SignUpRefused",this.reason=Hn(e)}};function Hn(t){return/invite only/.test(t)?"invite-only":/pre-authorized|sign-up invite/.test(t)?"closed":/unknown invite/.test(t)?"unknown-invite":/invite has expired/.test(t)?"expired-invite":/organization is gone/.test(t)?"org-gone":"other"}var Me=class extends y{constructor(e,r={}){super(429,"QUOTA_EXCEEDED",e,r),this.name="QuotaExceeded"}},_e=class extends y{constructor(e,r={}){super(422,"APP_ERROR",e,r),this.name="AppError";let{appCode:n,fields:i}=Fn(r);this.appCode=n,this.fields=i}},$e=class extends y{constructor(e,r={}){super(422,"TRAP",e,r),this.name="TrapError",this.kind=typeof r.kind=="string"?r.kind:""}},L=class extends y{constructor(e,r,n={},i,s){super(503,e,r,n),this.name="UnavailableError",this.reason=e.toLowerCase(),this.committed=e==="TIMEOUT"||e==="MIGRATING"?!1:"unknown",this.retryAfter=i,this.cause=s}};function Be(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:{}}function Fn(t){let e=typeof t.code=="string"?t:Be(t.error);return{appCode:typeof e.code=="string"?e.code:"",fields:{...Be(e.fields)}}}function jn(t,e){for(let r of[t.retryAfter,e==null?void 0:Number(e)])if(typeof r=="number"&&Number.isFinite(r)&&r>=0)return r}function Ke(t,e,r){let n=Be(e),i=typeof n.error=="string"?n.error:"ERROR",s=typeof n.message=="string"?n.message:"",o=Be(n.details);if(t===503)return new L(i,s,o,jn(o,r));switch(`${t} ${i}`){case"401 UNAUTHENTICATED":return new B(s,o);case"401 PASSKEY_UNKNOWN_HERE":return new Pe(s,o);case"421 WRONG_NODE":return new K(s,o);case"404 NOT_FOUND":return new ve(s,o);case"409 IDEMPOTENCY_MISMATCH":return new ke(s,o);case"409 RELEASE_DEADLINE":return new Ue(s,o);case"409 CONSENT_STALE":return new Se(s,o);case"403 ORIGIN_NOT_REGISTERED":return new V(s,o);case"400 BAD_ORIGIN":case"400 BAD_RP_ID":return new Te(i,s,o);case"409 ORIGIN_TAKEN":return new Ce(s,o);case"400 NOT_SERVING":return new Oe(s,o);case"409 CLUSTER_NOT_UPGRADED":return new Ie(s,o);case"429 QUOTA_EXCEEDED":return new Me(s,o);case"409 RECOVERY_NOT_READY":return new De(s,o);case"403 SIGN_UP_REFUSED":return new Ne(s,o);case"412 CONFIRM_REQUIRED":return new Z(s,o);case"413 ARGS_TOO_LARGE":return new xe(s,o);case"422 APP_ERROR":return new _e(s,o);case"422 TRAP":return new $e(s,o);default:return new y(t,i,s,o)}}function P(t){let e="";for(let r of t)e+=String.fromCharCode(r);return btoa(e).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function O(t){let e=t.replace(/-/g,"+").replace(/_/g,"/")+"===".slice((t.length+3)%4),r=atob(e),n=new Uint8Array(r.length);for(let i=0;i<r.length;i++)n[i]=r.charCodeAt(i);return n}var le=t=>t.buffer.slice(t.byteOffset,t.byteOffset+t.byteLength);function yr(t){let e=new Error(t);return e.name="NotAllowedError",e}async function tt(t,e,r,n){let i=navigator.credentials,o=globalThis.CredentialsContainer?.prototype?.[t]??i[t];try{return await o.call(i,r?{...e,signal:r}:e)}catch(a){throw r?.aborted||a?.name==="AbortError"?Object.assign(yr(`${n} was cancelled`),{cause:a}):a}}function qn(t){let e=t.filter(r=>r.alg===-7);return e.length?e:t}function Qn(){return{async create(t,e){let r=t,n=await tt("create",{publicKey:{challenge:le(O(r.challenge)),rp:r.rp,user:{...r.user,id:le(O(r.user.id))},pubKeyCredParams:qn(r.pubKeyCredParams),excludeCredentials:(r.excludeCredentials??[]).map(s=>({type:s.type,id:le(O(s.id))})),authenticatorSelection:r.authenticatorSelection,attestation:"none",timeout:r.timeout}},e?.signal,"passkey creation");if(!n)throw yr("passkey creation was cancelled");let i=n.response;return{attestationObject:P(new Uint8Array(i.attestationObject)),clientDataJson:P(new Uint8Array(i.clientDataJSON))}},async get(t,e,r,n){let i=await tt("get",{publicKey:{challenge:le(t),rpId:e,userVerification:n?.userVerification??"preferred",allowCredentials:(r??[]).map(o=>({type:"public-key",id:le(O(o))}))}},n?.signal,"passkey sign-in");if(!i)throw yr("passkey sign-in was cancelled");let s=i.response;return{credentialId:P(new Uint8Array(i.rawId)),authenticatorData:P(new Uint8Array(s.authenticatorData)),clientDataJson:P(new Uint8Array(s.clientDataJSON)),signature:P(new Uint8Array(s.signature))}}}}var nt="calimero.org-recovery.v1\0",mr=64,hr=Uint8Array.from([48,46,2,1,0,48,5,6,3,43,101,112,4,34,4,32]);function Yn(){return crypto.getRandomValues(new Uint8Array(32))}function Jn(t){st(t);let e=Array.from(t,n=>n.toString(16).padStart(2,"0")).join(""),r=[];for(let n=0;n<e.length;n+=8)r.push(e.slice(n,n+8));return r.join("-")}function zn(t){let e=t.replace(/[-\s]/g,"");if(!/^[0-9a-fA-F]{64}$/.test(e))throw new Error("a recovery seed is 64 hex digits");return Uint8Array.from({length:32},(r,n)=>parseInt(e.slice(2*n,2*n+2),16))}function it(t,e,r){return new TextEncoder().encode(`${nt}${t}\0${e}\0${r}`)}async function Zn(t){let e=await ot(t,!0),r=await crypto.subtle.exportKey("jwk",e);if(!r.x)throw new Error("this runtime cannot export an Ed25519 public key");return r.x}async function wr(t,e,r,n){let i=new TextEncoder().encode(n).length;if(i===0||i>mr)throw new Error(`a recovery nonce is 1 to ${mr} bytes`);let s=await ot(t,!1),o=await crypto.subtle.sign("Ed25519",s,at(it(e,r,n)));return P(new Uint8Array(o))}function st(t){if(t.length!==32)throw new Error("a recovery seed is 32 bytes")}function ot(t,e){st(t);let r=new Uint8Array(hr.length+32);return r.set(hr),r.set(t,hr.length),crypto.subtle.importKey("pkcs8",at(r),{name:"Ed25519"},e,["sign"])}var at=t=>t.buffer.slice(t.byteOffset,t.byteOffset+t.byteLength);var Ar=100;function ue(t={}){let e=new URLSearchParams;if(t.after!==void 0&&e.set("after",t.after),t.limit!==void 0){if(!Number.isInteger(t.limit)||t.limit<1||t.limit>Ar)throw new RangeError(`limit is 1 to ${Ar}`);e.set("limit",String(t.limit))}let r=e.toString();return r?`?${r}`:""}function de(t,e){try{return se(t,e)}catch{return t<e?-1:t>e?1:0}}function ct(t,e,r=Date.now()/1e3){if(t===null||t.length===0)return null;let n=t.reduce((s,o)=>de(s,o)>=0?s:o),i=null;for(let s of e)s.afterSecs<=r&&de(n,s.version)<0&&(i===null||de(s.version,i.version)>0)&&(i=s);return i}function lt(t,e,r,n){return`calimero-publisher-binding/v1
4
2
  ${t}
5
- ${n}`}function Xn(r,e,t,n){return new TextEncoder().encode(lr(r,e,t,n))}var Wn="0123456789ABCDEFGHJKMNPQRSTVWXYZ";async function bt(r){let e=new Uint8Array(await crypto.subtle.digest("SHA-256",new TextEncoder().encode(r))),t=(e[0]<<24|e[1]<<16|e[2]<<8|e[3])>>>0,n="";for(let i=0;i<6;i++)i===3&&(n+="-"),n+=Wn[t>>>27-5*i&31];return n}function ei(r){let e=typeof r=="string"?new URL(r):r,t=e.searchParams.get("request_id"),n=e.searchParams.get("result");return!t||n!=="approved"&&n!=="declined"?null:{requestId:t,result:n}}var dr="https://mero-tee.vercel.app";function ur(r){return`https://github.com/calimero-network/mero-tee/releases/tag/mero-tee-v${encodeURIComponent(r)}`}function gr(r){return`${dr}/mero-tee?release_tag=${encodeURIComponent(`mero-tee-v${r}`)}`}function Et(r,e,t=Date.now()/1e3){let n=c=>e.deadlines.find(d=>d.version===c)??null,i=r.governance.releases==="owner",s=r.governance.appUpgrades==="owner",o=r.clusterReleases.filter(c=>!c.approved).sort((c,d)=>de(d.release,c.release)).map(c=>({version:c.release,nodes:c.nodes,actionable:i,releaseNotesUrl:ur(c.release),verifyUrl:gr(c.release),deadline:n(c.release)})),a=[];for(let c of r.apps){let d=c.availableVersions??[];c.package===null||d.length===0||a.push({app:c.app,name:c.name??null,package:c.package.package,from:c.package.version,to:d[d.length-1],available:d,actionable:s})}return{scope:r.scope,governance:r.governance,approvedReleases:r.approvedReleases,releases:o,upgrades:a,stalledBy:cr(r.approvedReleases,e.deadlines,t),actionable:o.some(c=>c.actionable)||a.some(c=>c.actionable)}}function pr(r,e,t,n={}){return{kind:"release",scope:r.kind==="org"?{org:r.org}:"account",subject:n.withdraw?{version:e,withdraw:!0}:{version:e},returnTo:t}}function ti(r,e,t){return pr(r,e,t,{withdraw:!0})}function ri(r,e,t){return{kind:"upgrade",subject:{app:r,toVersion:e},returnTo:t}}function mr(r){return"account"in r?`account:${r.account}`:`org:${r.org}`}async function ni(r,e=fetch){let t=r??globalThis.location?.origin;if(!t)throw new Error("no page origin to read the frontend manifest from; pass `origin`");let n=await e(new URL("/.well-known/calimero.json",t).toString());if(!n.ok)throw await Rt(n);let i=await n.json();return{...i,deployments:i.deployments??[]}}function ii(r){let e=r??globalThis.location?.href;if(!e)return null;try{return new URL(e).searchParams.get("deployment")||null}catch{return null}}function si(r,e){return r==="required"||r==="preferred"||r==="discouraged"?r:e}function oi(r){let e=r,t=e?.name,n=typeof e?.message=="string"?e.message:"";return t==="InvalidStateError"||/not focused|already pending/i.test(n)?new ae(r):t==="NotAllowedError"||t==="AbortError"?new oe(r):r}function l(r){return encodeURIComponent(r)}function ai(r){return r instanceof T&&r.status===413?Ke(413,{error:"TOO_LARGE",message:r.message.replace(/^Sealed request refused: /,"")}):r}async function Rt(r){let e=await r.text().catch(()=>""),t={};try{t=e?JSON.parse(e):{}}catch{t={message:e}}return Ke(r.status,t,r.headers.get("retry-after"))}async function*ci(r){let e=r.getReader(),t=new TextDecoder,n="";for(;;){let{value:i,done:s}=await e.read();if(s)return;n+=t.decode(i,{stream:!0});let o;for(;(o=n.indexOf(`
3
+ ${e}
4
+ ${r}
5
+ ${n}`}function Xn(t,e,r,n){return new TextEncoder().encode(lt(t,e,r,n))}var Wn="0123456789ABCDEFGHJKMNPQRSTVWXYZ";async function br(t){let e=new Uint8Array(await crypto.subtle.digest("SHA-256",new TextEncoder().encode(t))),r=(e[0]<<24|e[1]<<16|e[2]<<8|e[3])>>>0,n="";for(let i=0;i<6;i++)i===3&&(n+="-"),n+=Wn[r>>>27-5*i&31];return n}function ei(t){let e=typeof t=="string"?new URL(t):t,r=e.searchParams.get("request_id"),n=e.searchParams.get("result");return!r||n!=="approved"&&n!=="declined"?null:{requestId:r,result:n}}var dt="https://mero-tee.vercel.app";function ut(t){return`https://github.com/calimero-network/mero-tee/releases/tag/mero-tee-v${encodeURIComponent(t)}`}function gt(t){return`${dt}/mero-tee?release_tag=${encodeURIComponent(`mero-tee-v${t}`)}`}function Er(t,e,r=Date.now()/1e3){let n=c=>e.deadlines.find(d=>d.version===c)??null,i=t.governance.releases==="owner",s=t.governance.appUpgrades==="owner",o=t.clusterReleases.filter(c=>!c.approved).sort((c,d)=>de(d.release,c.release)).map(c=>({version:c.release,nodes:c.nodes,actionable:i,releaseNotesUrl:ut(c.release),verifyUrl:gt(c.release),deadline:n(c.release)})),a=[];for(let c of t.apps){let d=c.availableVersions??[];c.package===null||d.length===0||a.push({app:c.app,name:c.name??null,package:c.package.package,from:c.package.version,to:d[d.length-1],available:d,actionable:s})}return{scope:t.scope,governance:t.governance,approvedReleases:t.approvedReleases,releases:o,upgrades:a,stalledBy:ct(t.approvedReleases,e.deadlines,r),actionable:o.some(c=>c.actionable)||a.some(c=>c.actionable)}}function pt(t,e,r,n={}){return{kind:"release",scope:t.kind==="org"?{org:t.org}:"account",subject:n.withdraw?{version:e,withdraw:!0}:{version:e},returnTo:r}}function ri(t,e,r){return pt(t,e,r,{withdraw:!0})}function ti(t,e,r){return{kind:"upgrade",subject:{app:t,toVersion:e},returnTo:r}}function mt(t){return"account"in t?`account:${t.account}`:`org:${t.org}`}async function ni(t,e=fetch){let r=t??globalThis.location?.origin;if(!r)throw new Error("no page origin to read the frontend manifest from; pass `origin`");let n=await e(new URL("/.well-known/calimero.json",r).toString());if(!n.ok)throw await Rr(n);let i=await n.json();return{...i,deployments:i.deployments??[]}}function ii(t){let e=t??globalThis.location?.href;if(!e)return null;try{return new URL(e).searchParams.get("deployment")||null}catch{return null}}function si(t,e){return t==="required"||t==="preferred"||t==="discouraged"?t:e}function oi(t){let e=t,r=e?.name,n=typeof e?.message=="string"?e.message:"";return r==="InvalidStateError"||/not focused|already pending/i.test(n)?new ae(t):r==="NotAllowedError"||r==="AbortError"?new oe(t):t}function l(t){return encodeURIComponent(t)}function ai(t){return t instanceof S&&t.status===413?Ke(413,{error:"TOO_LARGE",message:t.message.replace(/^Sealed request refused: /,"")}):t}async function Rr(t){let e=await t.text().catch(()=>""),r={};try{r=e?JSON.parse(e):{}}catch{r={message:e}}return Ke(t.status,r,t.headers.get("retry-after"))}async function*ci(t){let e=t.getReader(),r=new TextDecoder,n="";for(;;){let{value:i,done:s}=await e.read();if(s)return;n+=r.decode(i,{stream:!0});let o;for(;(o=n.indexOf(`
6
6
 
7
7
  `))>=0;){let a=n.slice(0,o);n=n.slice(o+2);let c="",d="",u="";for(let p of a.split(`
8
- `))p.startsWith("id:")?c=p.slice(3).trim():p.startsWith("event:")?d=p.slice(6).trim():p.startsWith("data:")&&(u+=p.slice(5).trim());if(!d&&!u)continue;let g=u;try{g=JSON.parse(u)}catch{}yield{id:c,kind:d,data:g}}}}function fr(r){return Array.from(r,e=>e.toString(16).padStart(2,"0")).join("")}function yr(){return`node:c-${P(crypto.getRandomValues(new Uint8Array(16)))}`}var li={retries:6,baseDelayMs:200,maxDelayMs:2e3};function di(r,e){return Math.min(e.baseDelayMs*2**r,e.maxDelayMs)}function hr(r){return r==="auth/refresh"||r.startsWith("auth/passkey/")||ui.has(r)}var ui=new Set(["auth/recovery/begin","auth/recovery/start","auth/recovery/finish"]),Pt=class r{constructor(e){this.at=0;this.channels=new Map;this.networkFailures=new WeakSet;this.packageOrigins={list:async e=>{let{origins:t}=await this.get(`package-origins/${l(e)}`);return t??[]},add:(e,t,n,i={})=>this.confirmed("POST",`package-origins/${l(e)}`,{origin:t,...i.rpId===void 0?{}:{rpId:i.rpId},...i.served?{served:!0}:{}},n),remove:(e,t,n)=>this.confirmed("DELETE",`package-origins/${l(e)}`,{origin:t},n)};let t=s=>s.replace(/\/+$/,"");this.nodeUrls=[...new Set([e.baseUrl,...e.nodes??[]].map(t))],this.policy=e.policy,this.retry={...li,...e.retry};let n=e.fetch??((s,o)=>fetch(s,o)),i=async(s,o)=>{try{return await n(s,o)}catch(a){throw a instanceof TypeError&&this.networkFailures.add(a),a}};this.raw=i}static async connect(e){let t=e.directory??gt,n=e.random??Math.random,i=e.fetch??((d,u)=>fetch(d,u)),s=await pt(t,e.cluster,i),[o,...a]=ft(s.nodes,e.zone,n),c=new r({baseUrl:o,nodes:a,policy:e.policy,fetch:e.fetch,retry:e.retry});return c.source={directory:t,cluster:e.cluster,zone:e.zone,random:n,due:Date.now()+s.refreshAfterSeconds*1e3},c}get nodeUrl(){return this.nodeUrls[this.at]}get nodes(){return[...this.nodeUrls]}channel(e){let t=this.channels.get(e);return t||(t=We({baseUrl:e,transportPublicKey:()=>ut(e,this.policy,this.raw),fetch:this.raw}),this.channels.set(e,t)),t}moveOn(e){return this.nodeUrls.length<2?!1:(this.nodeUrl===e&&(this.at=(this.at+1)%this.nodeUrls.length),!0)}failOver(e,t){if(this.nodeUrl!==e&&!t.has(this.nodeUrl))return!0;let n=this.nodeUrls.length;for(let i=1;i<n;i++){let s=(this.at+i)%n;if(!t.has(this.nodeUrls[s]))return this.at=s,this.reread(),!0}return!1}reread(){let e=this.source;!e||e.reading||(e.reading=pt(e.directory,e.cluster,this.raw).then(t=>{let n=this.nodeUrl,i=ft(t.nodes,e.zone,e.random);this.nodeUrls=[n,...i.filter(s=>s!==n)],this.at=0,e.due=Date.now()+t.refreshAfterSeconds*1e3}).catch(()=>{}).finally(()=>{e.reading=void 0}))}useApiKey(e){this.auth=e,this.current=void 0}useSession(e){this.auth=e.sessionToken,this.current=e}get session(){return this.current}async request(e,t,n,i,s="application/wasm",o){let a={};this.auth&&(a.authorization=`Bearer ${this.auth}`);let c;i?(a["content-type"]=s,c=i):n!==void 0&&(a["content-type"]="application/json",c=JSON.stringify(n)),this.source&&Date.now()>=this.source.due&&this.reread();let d=this.nodeUrl;try{return await this.channel(d)(`${d}/${t}`,{method:e,headers:a,body:c,signal:o})}catch(u){throw ai(u)}}async send(e,t,n,i,s,o){let a=!1,c=!1;for(;;){let[d,u]=[this.auth,this.nodeUrl],g=await this.request(e,t,n,i,s,o);if(g.ok)return g;let p=await Rt(g);if(p instanceof K&&!c){if(c=!0,this.moveOn(u)&&!hr(t))continue}else if(p instanceof B&&!a&&this.mayRefresh(d,t)){a=!0,await this.renew(d);continue}throw p}}mayRefresh(e,t){return e!==void 0&&this.current!==void 0&&!hr(t)}async renew(e){this.auth===e&&await this.refresh()}async json(e,t,n,i,s){let a=await(await this.send(e,t,n,i,s)).text();return a?JSON.parse(a):{}}async retried(e,t,n,i=!1){let s=i?0:this.retry.retries,o=new Set;for(;;){let a,c=this.nodeUrl;for(let d=0;;d++){c=this.nodeUrl,o.add(c);try{return await this.json(e,t,n)}catch(g){if(g instanceof L)a=g;else if(g instanceof TypeError&&this.networkFailures.has(g))a=new L("NETWORK",`the node could not be reached: ${g.message}`,{},void 0,g);else throw g}if(d>=s)break;let u=di(d,this.retry);await new Promise(g=>setTimeout(g,Math.max(u,(a.retryAfter??0)*1e3)))}if(i||!this.failOver(c,o))throw a}}post(e,t={}){return this.json("POST",e,t)}get(e){return this.json("GET",e)}put(e,t={}){return this.json("PUT",e,t)}delete(e,t){return this.json("DELETE",e,t)}async signUp(e,t,n={}){let i=this.pageOrigin(n),s=n.invite?{invite:n.invite}:{},o=await this.begin("auth/passkey/register/begin",i===void 0?{name:t,...s}:{name:t,origin:i,...s},i),a=n.signal,c=await(a?e.create(o.options,{signal:a}):e.create(o.options)),d=await this.confirmed("POST","auth/passkey/register/finish",{challengeId:o.challengeId,registration:c,...s},e,void 0,"preferred",a);return this.useSession(d),d}signUpPolicy(){return this.get("sign-up")}async signIn(e,t={}){let n=this.pageOrigin(t),i=await this.begin("auth/passkey/login/begin",n===void 0?void 0:{origin:n},n),s=i.options.rpId??i.options.rp?.id??"",o=O(i.options.challenge),a=await(t.signal?e.get(o,s,void 0,{signal:t.signal}):e.get(o,s)),c=await this.post("auth/passkey/login/finish",{challengeId:i.challengeId,assertion:a});return this.useSession(c),c}pageOrigin(e){if(e.origin!==void 0)return e.origin??void 0;let t=globalThis.location?.origin;return!t||t==="null"||new Set(this.nodeUrls.map(i=>{try{return new URL(i).origin}catch{return i}})).has(t)?void 0:t}async begin(e,t,n){try{return await this.post(e,t)}catch(i){throw i instanceof V&&!i.origin&&n!==void 0?new V(i.nodeMessage,{...i.details,origin:n}):i}}refresh(){if(!this.refreshing){let e=this.exchangeRefresh();this.refreshing=e;let t=()=>{this.refreshing===e&&(this.refreshing=void 0)};e.then(t,t)}return this.refreshing}async exchangeRefresh(){let e=this.current;if(!e)throw new Error("no session to refresh");let t;for(let n=1;t===void 0;n++)try{t=await this.post("auth/refresh",{refreshToken:e.refreshToken})}catch(i){if(!(i instanceof K)||n>=this.nodeUrls.length)throw i}return this.current===e&&this.useSession(t),t}async signOut(){await this.signingOut("auth/logout")}async signOutEverywhere(){await this.signingOut("auth/logout-all")}async listSessions(){let{sessions:e}=await this.get("auth/sessions");return e}async revokeSession(e){await this.delete(`auth/sessions/${l(e)}`)}async listActivity(e){let t=e===void 0?"":`?after=${encodeURIComponent(String(e))}`,{activity:n}=await this.get(`auth/activity${t}`);return n}async signingOut(e){try{await this.post(e)}finally{this.auth=void 0,this.current=void 0}}me(){return this.get("auth/me")}async addPasskey(e,t){let n=await this.post("auth/passkeys/add/begin"),i=await e.create(n.options),{credentialId:s}=await this.postConfirmed("auth/passkeys/add/finish",{challengeId:n.challengeId,registration:i},t);return s}async removePasskey(e,t){await this.deleteConfirmed(`auth/passkeys/${l(e)}`,t)}async labelPasskey(e,t){await this.post(`auth/passkeys/${l(e)}`,{label:t})}async createRecoveryCode(e){let{code:t}=await this.postConfirmed("auth/recovery",{},e);return t}async removeRecoveryCode(e){await this.deleteConfirmed("auth/recovery",e)}async startAccountRecovery(e,t){try{let n=await this.post("auth/recovery/begin",{code:e}),i=await t.create(n.options);return await this.post("auth/recovery/start",{challengeId:n.challengeId,code:e,registration:i})}catch(n){throw n instanceof B?new ce(n.message.replace(/^401 UNAUTHENTICATED: /,""),n.details):n}}async cancelAccountRecovery(e){await this.postConfirmed("auth/recovery/cancel",{},e)}async finishAccountRecovery(e,t){let n=await this.postConfirmed("auth/recovery/finish",t?{accountId:t}:{},e);return this.useSession(n),n}usage(){return this.get("auth/usage")}async attestation(){let e=fr(crypto.getRandomValues(new Uint8Array(32))),t=await this.raw(`${this.nodeUrl}/attestation?nonce=${e}`);if(!t.ok)throw await Rt(t);return await t.json()}async listApiKeys(){let{keys:e}=await this.get("auth/apikeys");return e}async revokeApiKey(e,t){await this.deleteConfirmed(`auth/apikeys/${l(e)}`,t)}createApiKey(e,t){return this.postConfirmed("auth/apikeys",{...e},t)}async uploadBundle(e){let{hash:t}=await this.json("POST","bundles",void 0,e);return t}uploadBlob(e,t,n={}){let i=(typeof n=="string"?n:n.contentType)??"application/octet-stream";return this.json("POST",`apps/${l(e)}/blobs`,void 0,t,i)}async downloadBlob(e,t){return(await this.blobContent(e,t)).data}async downloadBlobGranted(e,t,n){return(await this.blobContent(e,t,{grant:n})).data}async blobContent(e,t,n={}){let i=n.grant===void 0?"":`?grant=${encodeURIComponent(n.grant)}`,s=await this.send("GET",`apps/${l(e)}/blobs/${l(t)}${i}`);return{data:new Uint8Array(await s.arrayBuffer()),contentType:s.headers.get("content-type")??"application/octet-stream"}}async listBlobs(e){let{blobs:t}=await this.get(`apps/${l(e)}/blobs`);return t}blobInfo(e,t){return this.get(`apps/${l(e)}/blobs/${l(t)}/info`)}async deleteBlob(e,t){await this.delete(`apps/${l(e)}/blobs/${l(t)}`)}uploadPackage(e){return this.json("POST","packages",void 0,e,"application/octet-stream")}installPackage(e,t){return this.post("packages/install",{package:e,version:t})}async packages(){let{packages:e}=await this.get("packages");return e}package(e){return this.get(`packages/${l(e)}`)}uninstallPackage(e,t){return this.delete(t===void 0?`packages/${l(e)}`:`packages/${l(e)}/${l(t)}`)}async listApps(e={}){let t=new URLSearchParams;e.package&&t.set("package",e.package),e.bundle&&t.set("bundle",e.bundle);let n=t.toString(),{apps:i}=await this.get(n?`apps?${n}`:"apps");return i}getApp(e){return this.get(`apps/${l(e)}`)}async deleteApp(e){await this.delete(`apps/${l(e)}`)}async setAccess(e,t){await this.post(`apps/${l(e)}/access`,{access:t})}async setAppMetadata(e,t){await this.post(`apps/${l(e)}/metadata`,{metadata:t})}appXcalls(e){return this.get(`apps/${l(e)}/xcalls`)}appStorage(e){return this.get(`apps/${l(e)}/storage`)}appAbi(e){return this.get(`apps/${l(e)}/abi`)}async transferApp(e,t,n){await this.postConfirmed(`apps/${l(e)}/transfer`,{to:t},n)}upgradeApp(e,t,n){let i=`apps/${l(e)}/upgrade`;return n?this.postConfirmed(i,t,n):this.post(i,t)}postConfirmed(e,t,n){return this.confirmed("POST",e,t,n)}deleteConfirmed(e,t,n={}){return this.confirmed("DELETE",e,n,t)}async confirmed(e,t,n,i,s=c=>this.json(e,t,c),o="required",a){try{return await s(n)}catch(c){if(!(c instanceof Z)||!i)throw c;let d=c.details,u;try{u=await i.get(O(d.challenge),d.rpId,d.allowCredentials,{userVerification:si(d.userVerification,o),...a?{signal:a}:{}})}catch(g){throw oi(g)}return s({...n,confirm:{challengeId:d.challengeId,assertion:u}})}}async createApp(e,t,n={}){let i=typeof t=="string"?{bundle:t}:t,{appId:s}=await this.post("apps",{name:e,...i,...n});return s}call(e,t,n={},i){let s=i??yr();return this.retried("POST",`apps/${l(e)}/intents`,{method:t,args:n,idempotencyKey:s})}async callConfirmed(e,t,n,i,s){let o=`apps/${l(e)}/intents`,a=s??yr();return this.confirmed("POST",o,{method:t,args:n,idempotencyKey:a},i,c=>this.retried("POST",o,c,c.confirm!==void 0))}view(e,t,n={},i={}){return this.retried("POST",`apps/${l(e)}/views`,{method:t,args:n,consistency:i.stale?"stale":"strong",minIndex:i.minIndex??0})}events(e,t=0,n){return this.stream(`apps/${l(e)}/events?from=${t}`,n)}async*stream(e,t){let n=await this.send("GET",e,void 0,void 0,void 0,t);if(!n.body)throw new y(n.status,"EVENTS","the event stream has no body");yield*ci(n.body)}async publishPresence(e,t,n){await this.post(`apps/${l(e)}/presence`,{seq:t,state:n===null?null:fr(n)})}async presence(e){let{present:t}=await this.get(`apps/${l(e)}/presence`);return t}presenceStream(e,t){return this.stream(`apps/${l(e)}/presence/stream`,t)}async setAlias(e,t){await this.put(`auth/aliases/${l(e)}`,{app:t})}async aliases(){let{aliases:e}=await this.get("auth/aliases");return e}async alias(e){let{appId:t}=await this.get(`auth/aliases/${l(e)}`);return t}async deleteAlias(e){await this.delete(`auth/aliases/${l(e)}`)}async createOrg(e,t={}){let n={name:e};t.recoveryKey!==void 0&&(n.recoveryKey=t.recoveryKey);let{orgId:i}=await this.post("orgs",n);return i}async setRecoveryKey(e,t,n){await this.postConfirmed(`orgs/${l(e)}/recovery`,{publicKey:t},n)}async startRecovery(e,t){let n=(await this.me()).accountId,i=P(crypto.getRandomValues(new Uint8Array(16))),s=await wt(t,e,n,i);return this.post(`orgs/${l(e)}/recovery/start`,{nonce:i,signature:s})}async cancelRecovery(e,t){await this.postConfirmed(`orgs/${l(e)}/recovery/cancel`,{},t)}finishRecovery(e,t){return this.postConfirmed(`orgs/${l(e)}/recovery/finish`,{},t)}getOrg(e){return this.get(`orgs/${l(e)}`)}async deleteOrg(e,t){await this.deleteConfirmed(`orgs/${l(e)}`,t)}async setOrgMetadata(e,t){await this.post(`orgs/${l(e)}/metadata`,{metadata:t})}async setMemberMetadata(e,t,n){await this.post(`orgs/${l(e)}/members/${l(t)}/metadata`,{metadata:n})}upgradeOrg(e,t,n){return this.postConfirmed(`orgs/${l(e)}/upgrade`,{...t},n)}upgradeRun(e,t){return this.get(`orgs/${l(e)}/upgrades/${l(t)}`)}retryUpgradeRun(e,t,n){return this.postConfirmed(`orgs/${l(e)}/upgrades/${l(t)}/retry`,{},n)}async approveRelease(e,t,n,i=!0){let s=e===null?"auth/releases":`orgs/${l(e)}/releases`;return this.postConfirmed(s,{version:t,approved:i},n)}async approveOutbound(e,t,n,i={}){let s=e===null?"auth/outbound":`orgs/${l(e)}/outbound`;return this.postConfirmed(s,{package:t,prefixes:i.prefixes??"manifest",replace:i.replace??!1},n)}appsReport(e,t={}){let n=e===null?"auth/apps":`orgs/${l(e)}/apps`;return this.get(`${n}${ue(t)}`)}async appsReportAll(e){let t=await this.appsReport(e),n=[...t.apps],i=t.next;for(;i!==null;){let s=await this.appsReport(e,{after:i});n.push(...s.apps),i=s.next}return{...t,apps:n,next:null}}releaseRules(){return this.get("releases")}async pendingApprovals(e=null){let[t,n]=await Promise.all([this.appsReportAll(e),this.releaseRules()]);return Et(t,n)}requestConsent(e){return this.post("consent/requests",e)}async openConsentPage(e,t={}){let n=typeof t=="function"?{navigate:t}:t,i=n.navigate??(o=>{let a=globalThis.window;if(!a)throw new Error("no window to open the consent page in; pass `navigate`");a.location.assign(o)}),s=await this.requestConsent(e);if(s.code!==void 0){let o=await bt(s.requestId);if(s.code!==o)throw new y(200,"CONSENT_CODE_MISMATCH","the consent page code does not match the request",{requestId:s.requestId,code:s.code,expected:o})}return n.confirm&&!await n.confirm(s)||i(s.url),s}consentResult(e){return this.get(`consent/${l(e)}/result`)}async waitForConsent(e,t={}){let n=t.intervalMs??2e3;for(;;){let i=await this.consentResult(e);if(i.status!=="pending"||t.signal?.aborted||t.expiresAt!==void 0&&Date.now()/1e3>=t.expiresAt)return i;await new Promise(s=>setTimeout(s,n))}}publisherBinding(e){return this.get(`publishers/${l(e)}`)}bindPublisher(e,t,n){return this.postConfirmed(`orgs/${l(e)}/publishers`,{...t},n)}upgradePublished(e,t,n,i){return this.postConfirmed(`orgs/${l(e)}/packages/${l(t)}/upgrade`,{...n},i)}opsApps(e={}){return this.get(`ops/apps${ue(e)}`)}opsOrgs(e={}){return this.get(`ops/orgs${ue(e)}`)}opsServedOrigins(){return this.get("ops/served-origins")}async setReleaseDeadline(e,t){let n=typeof t=="string"?t:t.toISOString();await this.post(`ops/releases/${l(e)}/deadline`,{after:n})}async liftReleaseDeadline(e){await this.delete(`ops/releases/${l(e)}/deadline`)}async setMember(e,t,n,i){await this.postConfirmed(`orgs/${l(e)}/members`,{account:t,role:n},i)}removeMember(e,t,n){return this.deleteConfirmed(`orgs/${l(e)}/members/${l(t)}`,n)}async setCapabilities(e,t,n,i={}){await this.postConfirmed(`orgs/${l(e)}/capabilities`,{capabilities:t,...i},n)}async setTeamDefaultCapabilities(e,t,n,i){await this.postConfirmed(`orgs/${l(e)}/capabilities`,{team:t,capabilities:n},i)}async createTeam(e,t,n,i){let{teamId:s}=await this.post(`orgs/${l(e)}/teams`,{name:t,join:n,parent:i});return s}getTeam(e,t){return this.get(`orgs/${l(e)}/teams/${l(t)}`)}async updateTeam(e,t,n){await this.post(`orgs/${l(e)}/teams/${l(t)}`,n)}async deleteTeam(e,t,n){let i=`orgs/${l(e)}/teams/${l(t)}`;await(n?this.deleteConfirmed(i,n):this.delete(i))}async setTeamMember(e,t,n,i,s={}){await this.postConfirmed(`orgs/${l(e)}/teams/${l(t)}/members`,{account:n,...s},i)}async removeTeamMember(e,t,n,i){await this.deleteConfirmed(`orgs/${l(e)}/teams/${l(t)}/members/${l(n)}`,i)}async invite(e,t,n,i=[],s={}){let{token:o}=await this.postConfirmed(`orgs/${l(e)}/invites`,{role:t,teams:i,...s},n);return o}redeemInvite(e){return this.post(`invites/${l(e)}/redeem`)}async listInvites(e){let{invites:t}=await this.get(`orgs/${l(e)}/invites`);return t}async revokeInvite(e,t,n){await this.deleteConfirmed(`orgs/${l(e)}/invites/${l(t)}`,n)}listAppTeams(e){return this.get(`orgs/${l(e)}/app-teams`)}scopeApps(e,t,n={}){let i={};return n.apps!==void 0&&(i.apps=n.apps),n.shared!==void 0&&(i.shared=n.shared),this.postConfirmed(`orgs/${l(e)}/app-teams`,i,t)}grantDeployer(e,t,n={}){let i=n.until instanceof Date?n.until.toISOString():n.until;return this.postConfirmed("deployers",{deployer:e,...i===void 0?{}:{until:i}},t)}deployers(){return this.get("deployers")}async revokeDeployer(e,t){let n=typeof e=="string"?e:mr(e);await this.deleteConfirmed(`deployers/${l(n)}`,t)}async createDeployment(e,t,n){let{id:i}=await this.postConfirmed("deployments",{name:e,owner:t},n);return i}async deployments(){let{deployments:e}=await this.get("deployments");return e}deployment(e){return this.get(`deployments/${l(e)}`)}async deleteDeployment(e,t){await this.deleteConfirmed(`deployments/${l(e)}`,t)}offerApp(e,t,n){return this.postConfirmed(`deployments/${l(e)}/apps`,{...t},n)}async withdrawApp(e,t,n){await this.deleteConfirmed(`deployments/${l(e)}/apps/${l(t)}`,n)}deploymentOrgs(e){return this.get(`deployments/${l(e)}/orgs`)}};var vt={CREATE_APP:1,INVITE_MEMBERS:2,JOIN_OPEN_TEAMS:4,MANAGE_MEMBERS:8,MANAGE_APPLICATION:16,CREATE_TEAM:32,DELETE_TEAM:64,MANAGE_VISIBILITY:128,MANAGE_METADATA:256,APPROVE_RELEASES:1024},gi=vt.JOIN_OPEN_TEAMS;function pi(...r){return r.reduce((e,t)=>e|vt[t],0)}function Ve(r,e){return(r<<e|r>>>32-e)>>>0}function I(r,e,t,n,i){r[e]=r[e]+r[t]>>>0,r[i]=Ve(r[i]^r[e],16),r[n]=r[n]+r[i]>>>0,r[t]=Ve(r[t]^r[n],12),r[e]=r[e]+r[t]>>>0,r[i]=Ve(r[i]^r[e],8),r[n]=r[n]+r[i]>>>0,r[t]=Ve(r[t]^r[n],7)}function wr(r,e){return(r[e]|r[e+1]<<8|r[e+2]<<16|r[e+3]<<24)>>>0}function Er(r,e,t){let n=new Uint32Array(16);n[0]=1634760805,n[1]=857760878,n[2]=2036477234,n[3]=1797285236;for(let o=0;o<8;o+=1)n[4+o]=wr(r,o*4);n[12]=e>>>0;for(let o=0;o<3;o+=1)n[13+o]=wr(t,o*4);let i=n.slice();for(let o=0;o<10;o+=1)I(i,0,4,8,12),I(i,1,5,9,13),I(i,2,6,10,14),I(i,3,7,11,15),I(i,0,5,10,15),I(i,1,6,11,12),I(i,2,7,8,13),I(i,3,4,9,14);let s=new Uint8Array(64);for(let o=0;o<16;o+=1){let a=i[o]+n[o]>>>0;s[o*4]=a&255,s[o*4+1]=a>>>8&255,s[o*4+2]=a>>>16&255,s[o*4+3]=a>>>24&255}return s}function fi(r,e,t,n){let i=new Uint8Array(n.length);for(let s=0,o=e;s<n.length;s+=64,o+=1){let a=Er(r,o,t),c=Math.min(s+64,n.length);for(let d=s;d<c;d+=1)i[d]=n[d]^a[d-s]}return i}function xt(r){let e=0n;for(let t=r.length-1;t>=0;t-=1)e=e<<8n|BigInt(r[t]);return e}var yi=(1n<<130n)-5n;function hi(r,e){let t=xt(r.subarray(0,16))&0x0ffffffc0ffffffc0ffffffc0fffffffn,n=xt(r.subarray(16,32)),i=0n;for(let a=0;a<e.length;a+=16){let c=e.subarray(a,Math.min(a+16,e.length)),d=xt(c)+(1n<<BigInt(8*c.length));i=(i+d)*t%yi}let s=i+n&(1n<<128n)-1n,o=new Uint8Array(16);for(let a=0;a<16;a+=1)o[a]=Number(s&0xffn),s>>=8n;return o}function Ar(r){return new Uint8Array((16-r%16)%16)}function br(r){let e=new Uint8Array(8);return new DataView(e.buffer).setBigUint64(0,BigInt(r),!0),e}function mi(r,e){let t=[r,Ar(r.length),e,Ar(e.length),br(r.length),br(e.length)],n=new Uint8Array(t.reduce((s,o)=>s+o.length,0)),i=0;for(let s of t)n.set(s,i),i+=s.length;return n}function wi(r,e){if(r.length!==32)throw new Error("ChaCha20-Poly1305 needs a 32-byte key");if(e.length!==12)throw new Error("ChaCha20-Poly1305 needs a 12-byte nonce")}function Rr(r,e,t,n=new Uint8Array(0)){wi(r,e);let i=Er(r,0,e).subarray(0,32),s=fi(r,1,e,t),o=hi(i,mi(n,s)),a=new Uint8Array(s.length+16);return a.set(s),a.set(o,s.length),a}var vr=32,Ai=1,bi=3,Ei=2,Ri=32,Pi=32,vi=12,X=r=>new TextEncoder().encode(r),pe=r=>new Uint8Array([r>>8&255,r&255]),Pr=h(X("KEM"),pe(vr)),ge=h(X("HPKE"),pe(vr),pe(Ai),pe(bi));async function xr(r,e){let t=r.length===0?new Uint8Array(32):r,n=await crypto.subtle.importKey("raw",t,{name:"HMAC",hash:"SHA-256"},!1,["sign"]);return new Uint8Array(await crypto.subtle.sign("HMAC",n,e))}async function xi(r,e,t){let n=new Uint8Array(t),i=new Uint8Array(0);for(let s=1,o=0;o<t;s+=1)i=await xr(r,h(i,e,new Uint8Array([s]))),n.set(i.subarray(0,Math.min(i.length,t-o)),o),o+=i.length;return n}function Le(r,e,t,n){return xr(e,h(X("HPKE-v1"),r,X(t),n))}function kt(r,e,t,n,i){return xi(e,h(pe(i),X("HPKE-v1"),r,X(t),n),i)}async function ki(r,e){let t=await Le(Pr,new Uint8Array(0),"eae_prk",r);return kt(Pr,t,"shared_secret",e,Ri)}async function Ui(r,e){let t=new Uint8Array(0),n=await Le(ge,t,"psk_id_hash",t),i=await Le(ge,t,"info_hash",e),s=h(new Uint8Array([Ei]),n,i),o=await Le(ge,r,"secret",t);return{key:await kt(ge,o,"key",s,Pi),nonce:await kt(ge,o,"base_nonce",s,vi)}}async function kr(r,e,t,n,i=new Uint8Array(0),s){if(r.length!==32)throw new Error("The recipient key is not 32 bytes of X25519");let o=await q(s),a=await q(e),c=h(await ee(o.privateKey,r),await ee(a.privateKey,r)),d=await ki(c,h(o.publicKey,r,a.publicKey)),{key:u,nonce:g}=await Ui(d,t);return{enc:o.publicKey,ciphertext:Rr(u,g,n,i)}}var Sr="mero-agent-gate/attest/v3",Cr="mero-agent-gate/provision/v2",Ti=/^[a-z0-9][a-z0-9-]{0,62}$/,Si=/^[A-Za-z0-9][A-Za-z0-9_.-]{0,63}$/,Ur=64,Tr=64*1024,D=class extends Error{constructor(t,n,i){super(t);this.status=n;this.code=i;this.name="AgentGateError"}};function Or(r){if(!Ti.test(r))throw new Error(`Agent id ${JSON.stringify(r)} must match [a-z0-9][a-z0-9-]{0,62}`)}function fe(r){return new TextEncoder().encode(r)}function Ir(r){let e=fe(r);return h(new Uint8Array([e.length]),e)}function G(r){let e="";for(let t of r)e+=String.fromCharCode(t);return btoa(e)}function Ge(r,e,t){let n;try{n=Uint8Array.from(atob(r.trim()),i=>i.charCodeAt(0))}catch{throw new Error(`${e} is not base64`)}if(t!==void 0&&n.length!==t)throw new Error(`${e} is not ${t} bytes`);return n}async function Dr(r,e,t,n){let i=new Uint8Array(32),s=h(fe(Sr),r,Ir(e),t??i,n??i);return new Uint8Array(await crypto.subtle.digest("SHA-256",s))}function Nr(r,e){return h(fe(Cr),r,Ir(e))}async function Ci(){let r=crypto.getRandomValues(new Uint8Array(32));return{secret:r,publicKey:await He(r)}}async function He(r){if(r.length!==32)throw new Error("An owner key is 32 bytes");return G((await q(r)).publicKey)}function _r(r,e){return`${r.replace(/\/+$/,"")}${e}`}async function Mr(r,e,t){let n=await r(e,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(t)}),i=await n.text(),s;try{s=i?JSON.parse(i):void 0}catch{}if(!n.ok){let o=s;throw new D(`The gate answered ${n.status}${o?.error?` ${o.error}`:""}: ${o?.details??i.slice(0,200)}`,n.status,o?.error)}return s}async function Ut(r){let e=r.agentId??"";e&&Or(e);let t=crypto.getRandomValues(new Uint8Array(32)),n=await Mr(r.fetch??fetch,_r(r.gateUrl,"/attest"),{nonceB64:G(t),...e?{agentId:e}:{}});if((n?.agentId??"")!==e)throw new Error(`Asked about agent ${JSON.stringify(e)}, the gate answered for ${JSON.stringify(n?.agentId)}`);let i=Ge(n.provisioningPublicKeyB64??"","provisioningPublicKeyB64",32),s=n.signingPublicKeyB64?Ge(n.signingPublicKeyB64,"signingPublicKeyB64",32):void 0,o=n.ownerPublicKeyB64?Ge(n.ownerPublicKeyB64,"ownerPublicKeyB64",32):void 0;if(!s!=!o)throw new Error("A claimed agent has both a signing key and an owner; the gate named one");let a=await Dr(i,e,s,o);return await r.verifier({quoteB64:n.quoteB64,nonce:R(t),reportDataSuffix:R(a)}),{agentId:e,provisioningPublicKey:G(i),...s?{signingPublicKey:G(s)}:{},...o?{ownerPublicKey:G(o)}:{}}}async function $r(r,e){let t=await He(e);if(r.ownerPublicKey&&r.ownerPublicKey!==t)throw new D(`This agent is claimed by another key (${r.ownerPublicKey}); it is not yours. Send it nothing and do not authorize its signing key`,void 0,"not_yours");return t}function Oi(r){let e=Object.keys(r);if(e.length===0)throw new Error("There are no secrets to provision");if(e.length>Ur)throw new Error(`At most ${Ur} secrets at once`);for(let t of e){if(!Si.test(t))throw new Error(`Secret name ${JSON.stringify(t)} must match [A-Za-z0-9][A-Za-z0-9_.-]{0,63}`);if(typeof r[t]!="string")throw new Error(`Secret ${t} is not a string`);if(fe(r[t]).length>Tr)throw new Error(`Secret ${t} is over ${Tr} bytes`)}}async function Br(r,e,t,n,i,s){if(!n.agentId)throw new Error("This quote names no agent; attest with the agent id");let o=await $r(n,i),a=Ge(n.provisioningPublicKey,"provisioningPublicKey",32),c=await kr(a,i,Nr(a,n.agentId),fe(JSON.stringify(s)));return Mr(r,_r(e,t),{agentId:n.agentId,provisioningPublicKeyB64:n.provisioningPublicKey,senderPublicKeyB64:o,encappedKeyB64:G(c.enc),ciphertextB64:G(c.ciphertext)})}async function Ii(r){Oi(r.secrets);let e=r.fetch??fetch,t=await Br(e,r.gateUrl,"/provision",r.agent,r.ownerSecret,{secrets:r.secrets}),n=await Ut({gateUrl:r.gateUrl,agentId:r.agent.agentId,verifier:r.verifier,fetch:e}),i=await He(r.ownerSecret);if(n.ownerPublicKey!==i||!n.signingPublicKey)throw new D("The gate accepted the secrets, but its quote does not name your key as owner");if(r.agent.signingPublicKey&&r.agent.signingPublicKey!==n.signingPublicKey)throw new D("The agent's signing key changed while provisioning");return{agentId:n.agentId,provisioningPublicKey:n.provisioningPublicKey,signingPublicKey:n.signingPublicKey,ownerPublicKey:i,written:t?.written??[],claimed:t?.claimed===!0}}async function Di(r){if(!r.agent.ownerPublicKey)throw new Error("This agent is not claimed; there is nothing to release");let e=r.fetch??fetch;if(await Br(e,r.gateUrl,"/release",r.agent,r.ownerSecret,{release:!0}),(await Ut({gateUrl:r.gateUrl,agentId:r.agent.agentId,verifier:r.verifier,fetch:e})).ownerPublicKey)throw new D("The gate says it released the agent, but its quote still names an owner")}var Tt=Object.freeze({identity:"https://github.com/calimero-network/mero-tee/.github/workflows/release-kms.yaml@refs/heads/master",issuer:"https://token.actions.githubusercontent.com"}),Ni=["allowed_tcb_statuses","allowed_mrtd","allowed_rtmr0","allowed_rtmr1","allowed_rtmr2","allowed_rtmr3"];async function _i(r,e,t={}){let n=typeof r=="string"?new TextEncoder().encode(r):r;await be(n,e,{identity:t.identity??Tt.identity,issuer:t.issuer??Tt.issuer});let i;try{i=JSON.parse(new TextDecoder().decode(n))}catch{throw new Error("The signed agent policy is not JSON")}let s=t.role??"agent";if(i?.role!==s)throw new Error(`The signed file is a ${JSON.stringify(i?.role)} policy, not an ${s} one`);let o=t.profile??M;if(i.profile!==o)throw new Error(`The signed agent policy is for the ${JSON.stringify(i.profile)} profile, not ${o}`);if(t.expectedVersion!==void 0&&i.version!==t.expectedVersion)throw new Error(`The signed agent policy is release ${JSON.stringify(i.version)}, not ${t.expectedVersion}`);return Kr(i),i}function Kr(r){for(let e of Ni)if(!Array.isArray(r?.[e])||r[e].length===0)throw new Error(`The agent policy's ${e} is empty, so no agent would be accepted`)}var Mi=["UpToDate","SWHardeningNeeded","ConfigurationNeeded","ConfigurationAndSWHardeningNeeded","OutOfDate","OutOfDateConfigurationNeeded"];function $i(r){let e=Mi.find(t=>t.toLowerCase()===r.trim().toLowerCase());if(!e)throw new Error(`The agent policy allows an unknown TCB status ${JSON.stringify(r)}`);return e}var ye=r=>r.trim().replace(/^0x/i,"");function Bi(r,e){return Kr(r),$({dcapVerify:e.dcapVerify,fetchCollateral:e.fetchCollateral,now:e.now,allowedTcbStatuses:r.allowed_tcb_statuses.map($i),allowedMrtd:r.allowed_mrtd.map(ye),allowedRtmr0:r.allowed_rtmr0.map(ye),allowedRtmr1:r.allowed_rtmr1.map(ye),allowedRtmr2:r.allowed_rtmr2.map(ye),allowedRtmr3:r.allowed_rtmr3.map(ye)})}export{Sr as AGENT_ATTEST_DOMAIN,Cr as AGENT_PROVISION_INFO_DOMAIN,D as AgentGateError,Me as AppError,xe as ArgsTooLarge,Se as BadOrigin,Pt as CalimeroClient,y as CalimeroError,Ie as ClusterNotUpgraded,oe as ConfirmCancelled,ae as ConfirmPromptBlocked,Z as ConfirmRequired,Te as ConsentStale,st as DEFAULT_COLLATERAL_MIRROR,gt as DEFAULT_DIRECTORY,gi as DEFAULT_ORG_CAPABILITIES,Ee as DEFAULT_RELEASE_MIRROR,U as DirectoryError,Jt as GITHUB_RELEASES,_t as HANDSHAKE_PATH,ke as IdempotencyMismatch,Tt as KMS_RELEASE_SIGNER,B as LoginRequired,mt as MAX_RECOVERY_NONCE_BYTES,At as MAX_REPORT_PAGE,Xt as MOCK_QUOTE_HEADER,it as NODE_RELEASE_SIGNER,ve as NotFound,Oe as NotServing,vt as ORG_CAPABILITIES,V as OriginNotRegistered,Ce as OriginTaken,M as PRODUCTION_PROFILE,Pe as PasskeyUnknownHere,_e as QuotaExceeded,nr as RECOVERY_DOMAIN,dr as RELEASE_VERIFIER,De as RecoveryNotReady,Ue as ReleaseDeadlineError,re as SEALED_CONTENT_TYPE,Mt as SEALED_PATH,T as SealedTransportError,Ne as SignUpRefused,ne as StaleTransportKeyError,$e as TrapError,L as UnavailableError,K as WrongNode,ce as WrongRecoveryCode,Dr as agentKeyBinding,Bi as agentQuoteVerifier,Ut as attestAgent,P as b64url,Qn as browserPasskey,$r as checkOwner,Wt as claimedRelease,ct as cloudNodeReleaseUrl,de as compareVersions,bt as confirmationCode,ei as consentReturn,$ as createQuoteVerifier,We as createSealedFetch,Mn as createSignedReleaseVerifier,mr as deployerKey,Ke as errorFrom,ut as fetchAttestedKey,at as fetchGithubNodeRelease,ot as fetchNodeRelease,er as freshCollateral,O as fromB64url,ni as frontendManifest,Ci as generateOwnerKey,Yn as newRecoverySeed,pi as orgCapabilities,He as ownerPublicKey,ii as pageDeployment,ue as pageQuery,zn as parseRecoverySeed,Et as pendingApprovalsFrom,Ii as provisionAgent,Nr as provisionInfo,Xn as publisherBindingBytes,lr as publisherBindingMessage,ir as recoveryMessage,Zn as recoveryPublicKey,Jn as recoverySeedText,Di as releaseAgent,pr as releaseConsent,ur as releaseNotesUrl,wt as signRecovery,cr as stalledBy,Xe as transportKeyBinding,Re as trustSignedRelease,nt as trustedMeasurementsFromReleases,ri as upgradeConsent,Or as validateAgentId,gr as verifyReleaseUrl,_i as verifySignedAgentPolicy,Yt as verifySignedNodeRelease,ti as withdrawConsent};
8
+ `))p.startsWith("id:")?c=p.slice(3).trim():p.startsWith("event:")?d=p.slice(6).trim():p.startsWith("data:")&&(u+=p.slice(5).trim());if(!d&&!u)continue;let g=u;try{g=JSON.parse(u)}catch{}yield{id:c,kind:d,data:g}}}}function ft(t){return Array.from(t,e=>e.toString(16).padStart(2,"0")).join("")}function yt(){return`node:c-${P(crypto.getRandomValues(new Uint8Array(16)))}`}var li={retries:6,baseDelayMs:200,maxDelayMs:2e3};function di(t,e){return Math.min(e.baseDelayMs*2**t,e.maxDelayMs)}function ht(t){return t==="auth/refresh"||t.startsWith("auth/passkey/")||ui.has(t)}var ui=new Set(["auth/recovery/begin","auth/recovery/start","auth/recovery/finish"]),Pr=class t{constructor(e){this.at=0;this.channels=new Map;this.networkFailures=new WeakSet;this.packageOrigins={list:async e=>{let{origins:r}=await this.get(`package-origins/${l(e)}`);return r??[]},add:(e,r,n,i={})=>this.confirmed("POST",`package-origins/${l(e)}`,{origin:r,...i.rpId===void 0?{}:{rpId:i.rpId},...i.served?{served:!0}:{}},n),remove:(e,r,n)=>this.confirmed("DELETE",`package-origins/${l(e)}`,{origin:r},n)};let r=s=>s.replace(/\/+$/,"");this.nodeUrls=[...new Set([e.baseUrl,...e.nodes??[]].map(r))],this.policy=e.policy,this.retry={...li,...e.retry};let n=e.fetch??((s,o)=>fetch(s,o)),i=async(s,o)=>{try{return await n(s,o)}catch(a){throw a instanceof TypeError&&this.networkFailures.add(a),a}};this.raw=i}static async connect(e){let r=e.directory??gr,n=e.random??Math.random,i=e.fetch??((d,u)=>fetch(d,u)),s=await pr(r,e.cluster,i),[o,...a]=fr(s.nodes,e.zone,n),c=new t({baseUrl:o,nodes:a,policy:e.policy,fetch:e.fetch,retry:e.retry});return c.source={directory:r,cluster:e.cluster,zone:e.zone,random:n,due:Date.now()+s.refreshAfterSeconds*1e3},c}get nodeUrl(){return this.nodeUrls[this.at]}get nodes(){return[...this.nodeUrls]}channel(e){let r=this.channels.get(e);return r||(r=We({baseUrl:e,transportPublicKey:()=>ur(e,this.policy,this.raw),fetch:this.raw}),this.channels.set(e,r)),r}moveOn(e){return this.nodeUrls.length<2?!1:(this.nodeUrl===e&&(this.at=(this.at+1)%this.nodeUrls.length),!0)}failOver(e,r){if(this.nodeUrl!==e&&!r.has(this.nodeUrl))return!0;let n=this.nodeUrls.length;for(let i=1;i<n;i++){let s=(this.at+i)%n;if(!r.has(this.nodeUrls[s]))return this.at=s,this.reread(),!0}return!1}reread(){let e=this.source;!e||e.reading||(e.reading=pr(e.directory,e.cluster,this.raw).then(r=>{let n=this.nodeUrl,i=fr(r.nodes,e.zone,e.random);this.nodeUrls=[n,...i.filter(s=>s!==n)],this.at=0,e.due=Date.now()+r.refreshAfterSeconds*1e3}).catch(()=>{}).finally(()=>{e.reading=void 0}))}useApiKey(e){this.auth=e,this.current=void 0}useSession(e){this.auth=e.sessionToken,this.current=e}get session(){return this.current}async request(e,r,n,i,s="application/wasm",o){let a={};this.auth&&(a.authorization=`Bearer ${this.auth}`);let c;i?(a["content-type"]=s,c=i):n!==void 0&&(a["content-type"]="application/json",c=JSON.stringify(n)),this.source&&Date.now()>=this.source.due&&this.reread();let d=this.nodeUrl;try{return await this.channel(d)(`${d}/${r}`,{method:e,headers:a,body:c,signal:o})}catch(u){throw ai(u)}}async send(e,r,n,i,s,o){let a=!1,c=!1;for(;;){let[d,u]=[this.auth,this.nodeUrl],g=await this.request(e,r,n,i,s,o);if(g.ok)return g;let p=await Rr(g);if(p instanceof K&&!c){if(c=!0,this.moveOn(u)&&!ht(r))continue}else if(p instanceof B&&!a&&this.mayRefresh(d,r)){a=!0,await this.renew(d);continue}throw p}}mayRefresh(e,r){return e!==void 0&&this.current!==void 0&&!ht(r)}async renew(e){this.auth===e&&await this.refresh()}async json(e,r,n,i,s){let a=await(await this.send(e,r,n,i,s)).text();return a?JSON.parse(a):{}}async retried(e,r,n,i=!1){let s=i?0:this.retry.retries,o=new Set;for(;;){let a,c=this.nodeUrl;for(let d=0;;d++){c=this.nodeUrl,o.add(c);try{return await this.json(e,r,n)}catch(g){if(g instanceof L)a=g;else if(g instanceof TypeError&&this.networkFailures.has(g))a=new L("NETWORK",`the node could not be reached: ${g.message}`,{},void 0,g);else throw g}if(d>=s)break;let u=di(d,this.retry);await new Promise(g=>setTimeout(g,Math.max(u,(a.retryAfter??0)*1e3)))}if(i||!this.failOver(c,o))throw a}}post(e,r={}){return this.json("POST",e,r)}get(e){return this.json("GET",e)}put(e,r={}){return this.json("PUT",e,r)}delete(e,r){return this.json("DELETE",e,r)}async signUp(e,r,n={}){let i=this.pageOrigin(n),s=n.invite?{invite:n.invite}:{},o=await this.begin("auth/passkey/register/begin",i===void 0?{name:r,...s}:{name:r,origin:i,...s},i),a=n.signal,c=await(a?e.create(o.options,{signal:a}):e.create(o.options)),d=await this.confirmed("POST","auth/passkey/register/finish",{challengeId:o.challengeId,registration:c,...s},e,void 0,"preferred",a);return this.useSession(d),d}signUpPolicy(){return this.get("sign-up")}async signIn(e,r={}){let n=this.pageOrigin(r),i=await this.begin("auth/passkey/login/begin",n===void 0?void 0:{origin:n},n),s=i.options.rpId??i.options.rp?.id??"",o=O(i.options.challenge),a=await(r.signal?e.get(o,s,void 0,{signal:r.signal}):e.get(o,s)),c=await this.post("auth/passkey/login/finish",{challengeId:i.challengeId,assertion:a});return this.useSession(c),c}pageOrigin(e){if(e.origin!==void 0)return e.origin??void 0;let r=globalThis.location?.origin;return!r||r==="null"||new Set(this.nodeUrls.map(i=>{try{return new URL(i).origin}catch{return i}})).has(r)?void 0:r}async begin(e,r,n){try{return await this.post(e,r)}catch(i){throw i instanceof V&&!i.origin&&n!==void 0?new V(i.nodeMessage,{...i.details,origin:n}):i}}refresh(){if(!this.refreshing){let e=this.exchangeRefresh();this.refreshing=e;let r=()=>{this.refreshing===e&&(this.refreshing=void 0)};e.then(r,r)}return this.refreshing}async exchangeRefresh(){let e=this.current;if(!e)throw new Error("no session to refresh");let r;for(let n=1;r===void 0;n++)try{r=await this.post("auth/refresh",{refreshToken:e.refreshToken})}catch(i){if(!(i instanceof K)||n>=this.nodeUrls.length)throw i}return this.current===e&&this.useSession(r),r}async signOut(){await this.signingOut("auth/logout")}async signOutEverywhere(){await this.signingOut("auth/logout-all")}async listSessions(){let{sessions:e}=await this.get("auth/sessions");return e}async revokeSession(e){await this.delete(`auth/sessions/${l(e)}`)}async listActivity(e){let r=e===void 0?"":`?after=${encodeURIComponent(String(e))}`,{activity:n}=await this.get(`auth/activity${r}`);return n}async signingOut(e){try{await this.post(e)}finally{this.auth=void 0,this.current=void 0}}me(){return this.get("auth/me")}async addPasskey(e,r){let n=await this.post("auth/passkeys/add/begin"),i=await e.create(n.options),{credentialId:s}=await this.postConfirmed("auth/passkeys/add/finish",{challengeId:n.challengeId,registration:i},r);return s}async removePasskey(e,r){await this.deleteConfirmed(`auth/passkeys/${l(e)}`,r)}async labelPasskey(e,r){await this.post(`auth/passkeys/${l(e)}`,{label:r})}async createRecoveryCode(e){let{code:r}=await this.postConfirmed("auth/recovery",{},e);return r}async removeRecoveryCode(e){await this.deleteConfirmed("auth/recovery",e)}async startAccountRecovery(e,r){try{let n=await this.post("auth/recovery/begin",{code:e}),i=await r.create(n.options);return await this.post("auth/recovery/start",{challengeId:n.challengeId,code:e,registration:i})}catch(n){throw n instanceof B?new ce(n.message.replace(/^401 UNAUTHENTICATED: /,""),n.details):n}}async cancelAccountRecovery(e){await this.postConfirmed("auth/recovery/cancel",{},e)}async finishAccountRecovery(e,r){let n=await this.postConfirmed("auth/recovery/finish",r?{accountId:r}:{},e);return this.useSession(n),n}usage(){return this.get("auth/usage")}async attestation(){let e=ft(crypto.getRandomValues(new Uint8Array(32))),r=await this.raw(`${this.nodeUrl}/attestation?nonce=${e}`);if(!r.ok)throw await Rr(r);return await r.json()}async listApiKeys(){let{keys:e}=await this.get("auth/apikeys");return e}async revokeApiKey(e,r){await this.deleteConfirmed(`auth/apikeys/${l(e)}`,r)}createApiKey(e,r){return this.postConfirmed("auth/apikeys",{...e},r)}async uploadBundle(e){let{hash:r}=await this.json("POST","bundles",void 0,e);return r}uploadBlob(e,r,n={}){let i=(typeof n=="string"?n:n.contentType)??"application/octet-stream";return this.json("POST",`apps/${l(e)}/blobs`,void 0,r,i)}async downloadBlob(e,r){return(await this.blobContent(e,r)).data}async downloadBlobGranted(e,r,n){return(await this.blobContent(e,r,{grant:n})).data}async blobContent(e,r,n={}){let i=n.grant===void 0?"":`?grant=${encodeURIComponent(n.grant)}`,s=await this.send("GET",`apps/${l(e)}/blobs/${l(r)}${i}`);return{data:new Uint8Array(await s.arrayBuffer()),contentType:s.headers.get("content-type")??"application/octet-stream"}}async listBlobs(e){let{blobs:r}=await this.get(`apps/${l(e)}/blobs`);return r}blobInfo(e,r){return this.get(`apps/${l(e)}/blobs/${l(r)}/info`)}async deleteBlob(e,r){await this.delete(`apps/${l(e)}/blobs/${l(r)}`)}uploadPackage(e){return this.json("POST","packages",void 0,e,"application/octet-stream")}installPackage(e,r){return this.post("packages/install",{package:e,version:r})}async packages(){let{packages:e}=await this.get("packages");return e}package(e){return this.get(`packages/${l(e)}`)}uninstallPackage(e,r){return this.delete(r===void 0?`packages/${l(e)}`:`packages/${l(e)}/${l(r)}`)}async listApps(e={}){let r=new URLSearchParams;e.package&&r.set("package",e.package),e.bundle&&r.set("bundle",e.bundle);let n=r.toString(),{apps:i}=await this.get(n?`apps?${n}`:"apps");return i}getApp(e){return this.get(`apps/${l(e)}`)}async deleteApp(e){await this.delete(`apps/${l(e)}`)}async setAccess(e,r){await this.post(`apps/${l(e)}/access`,{access:r})}async setAppMetadata(e,r){await this.post(`apps/${l(e)}/metadata`,{metadata:r})}appXcalls(e){return this.get(`apps/${l(e)}/xcalls`)}appStorage(e){return this.get(`apps/${l(e)}/storage`)}appAbi(e){return this.get(`apps/${l(e)}/abi`)}async transferApp(e,r,n){await this.postConfirmed(`apps/${l(e)}/transfer`,{to:r},n)}moveApp(e,r,n={},i){let s=`apps/${l(e)}/move`,o={toOrg:r,bringMembers:n.bringMembers??!1};return i?this.postConfirmed(s,o,i):this.post(s,o)}upgradeApp(e,r,n){let i=`apps/${l(e)}/upgrade`;return n?this.postConfirmed(i,r,n):this.post(i,r)}postConfirmed(e,r,n){return this.confirmed("POST",e,r,n)}deleteConfirmed(e,r,n={}){return this.confirmed("DELETE",e,n,r)}async confirmed(e,r,n,i,s=c=>this.json(e,r,c),o="required",a){try{return await s(n)}catch(c){if(!(c instanceof Z)||!i)throw c;let d=c.details,u;try{u=await i.get(O(d.challenge),d.rpId,d.allowCredentials,{userVerification:si(d.userVerification,o),...a?{signal:a}:{}})}catch(g){throw oi(g)}return s({...n,confirm:{challengeId:d.challengeId,assertion:u}})}}async createApp(e,r,n={}){let i=typeof r=="string"?{bundle:r}:r,{appId:s}=await this.post("apps",{name:e,...i,...n});return s}call(e,r,n={},i){let s=i??yt();return this.retried("POST",`apps/${l(e)}/intents`,{method:r,args:n,idempotencyKey:s})}async callConfirmed(e,r,n,i,s){let o=`apps/${l(e)}/intents`,a=s??yt();return this.confirmed("POST",o,{method:r,args:n,idempotencyKey:a},i,c=>this.retried("POST",o,c,c.confirm!==void 0))}view(e,r,n={},i={}){return this.retried("POST",`apps/${l(e)}/views`,{method:r,args:n,consistency:i.stale?"stale":"strong",minIndex:i.minIndex??0})}events(e,r=0,n){return this.stream(`apps/${l(e)}/events?from=${r}`,n)}async*stream(e,r){let n=await this.send("GET",e,void 0,void 0,void 0,r);if(!n.body)throw new y(n.status,"EVENTS","the event stream has no body");yield*ci(n.body)}async publishPresence(e,r,n){await this.post(`apps/${l(e)}/presence`,{seq:r,state:n===null?null:ft(n)})}async presence(e){let{present:r}=await this.get(`apps/${l(e)}/presence`);return r}presenceStream(e,r){return this.stream(`apps/${l(e)}/presence/stream`,r)}async setAlias(e,r){await this.put(`auth/aliases/${l(e)}`,{app:r})}async aliases(){let{aliases:e}=await this.get("auth/aliases");return e}async alias(e){let{appId:r}=await this.get(`auth/aliases/${l(e)}`);return r}async deleteAlias(e){await this.delete(`auth/aliases/${l(e)}`)}async createOrg(e,r={}){let n={name:e};r.recoveryKey!==void 0&&(n.recoveryKey=r.recoveryKey);let{orgId:i}=await this.post("orgs",n);return i}async setRecoveryKey(e,r,n){await this.postConfirmed(`orgs/${l(e)}/recovery`,{publicKey:r},n)}async startRecovery(e,r){let n=(await this.me()).accountId,i=P(crypto.getRandomValues(new Uint8Array(16))),s=await wr(r,e,n,i);return this.post(`orgs/${l(e)}/recovery/start`,{nonce:i,signature:s})}async cancelRecovery(e,r){await this.postConfirmed(`orgs/${l(e)}/recovery/cancel`,{},r)}finishRecovery(e,r){return this.postConfirmed(`orgs/${l(e)}/recovery/finish`,{},r)}getOrg(e){return this.get(`orgs/${l(e)}`)}async orgMembersSecurity(e){let{members:r}=await this.get(`orgs/${l(e)}/members?detail=security`);return r}async deleteOrg(e,r){await this.deleteConfirmed(`orgs/${l(e)}`,r)}async setOrgMetadata(e,r){await this.post(`orgs/${l(e)}/metadata`,{metadata:r})}async setMemberMetadata(e,r,n){await this.post(`orgs/${l(e)}/members/${l(r)}/metadata`,{metadata:n})}upgradeOrg(e,r,n){return this.postConfirmed(`orgs/${l(e)}/upgrade`,{...r},n)}upgradeRun(e,r){return this.get(`orgs/${l(e)}/upgrades/${l(r)}`)}retryUpgradeRun(e,r,n){return this.postConfirmed(`orgs/${l(e)}/upgrades/${l(r)}/retry`,{},n)}async approveRelease(e,r,n,i=!0){let s=e===null?"auth/releases":`orgs/${l(e)}/releases`;return this.postConfirmed(s,{version:r,approved:i},n)}async approveOutbound(e,r,n,i={}){let s=e===null?"auth/outbound":`orgs/${l(e)}/outbound`;return this.postConfirmed(s,{package:r,prefixes:i.prefixes??"manifest",replace:i.replace??!1},n)}appsReport(e,r={}){let n=e===null?"auth/apps":`orgs/${l(e)}/apps`;return this.get(`${n}${ue(r)}`)}async appsReportAll(e){let r=await this.appsReport(e),n=[...r.apps],i=r.next;for(;i!==null;){let s=await this.appsReport(e,{after:i});n.push(...s.apps),i=s.next}return{...r,apps:n,next:null}}releaseRules(){return this.get("releases")}async pendingApprovals(e=null){let[r,n]=await Promise.all([this.appsReportAll(e),this.releaseRules()]);return Er(r,n)}requestConsent(e){return this.post("consent/requests",e)}async openConsentPage(e,r={}){let n=typeof r=="function"?{navigate:r}:r,i=n.navigate??(o=>{let a=globalThis.window;if(!a)throw new Error("no window to open the consent page in; pass `navigate`");a.location.assign(o)}),s=await this.requestConsent(e);if(s.code!==void 0){let o=await br(s.requestId);if(s.code!==o)throw new y(200,"CONSENT_CODE_MISMATCH","the consent page code does not match the request",{requestId:s.requestId,code:s.code,expected:o})}return n.confirm&&!await n.confirm(s)||i(s.url),s}consentResult(e){return this.get(`consent/${l(e)}/result`)}async waitForConsent(e,r={}){let n=r.intervalMs??2e3;for(;;){let i=await this.consentResult(e);if(i.status!=="pending"||r.signal?.aborted||r.expiresAt!==void 0&&Date.now()/1e3>=r.expiresAt)return i;await new Promise(s=>setTimeout(s,n))}}publisherBinding(e){return this.get(`publishers/${l(e)}`)}bindPublisher(e,r,n){return this.postConfirmed(`orgs/${l(e)}/publishers`,{...r},n)}upgradePublished(e,r,n,i){return this.postConfirmed(`orgs/${l(e)}/packages/${l(r)}/upgrade`,{...n},i)}opsApps(e={}){return this.get(`ops/apps${ue(e)}`)}opsOrgs(e={}){return this.get(`ops/orgs${ue(e)}`)}opsServedOrigins(){return this.get("ops/served-origins")}async setReleaseDeadline(e,r){let n=typeof r=="string"?r:r.toISOString();await this.post(`ops/releases/${l(e)}/deadline`,{after:n})}async liftReleaseDeadline(e){await this.delete(`ops/releases/${l(e)}/deadline`)}async setMember(e,r,n,i){await this.postConfirmed(`orgs/${l(e)}/members`,{account:r,role:n},i)}removeMember(e,r,n){return this.deleteConfirmed(`orgs/${l(e)}/members/${l(r)}`,n)}async setCapabilities(e,r,n,i={}){await this.postConfirmed(`orgs/${l(e)}/capabilities`,{capabilities:r,...i},n)}async setTeamDefaultCapabilities(e,r,n,i){await this.postConfirmed(`orgs/${l(e)}/capabilities`,{team:r,capabilities:n},i)}async createTeam(e,r,n,i){let{teamId:s}=await this.post(`orgs/${l(e)}/teams`,{name:r,join:n,parent:i});return s}getTeam(e,r){return this.get(`orgs/${l(e)}/teams/${l(r)}`)}async updateTeam(e,r,n){await this.post(`orgs/${l(e)}/teams/${l(r)}`,n)}async deleteTeam(e,r,n){let i=`orgs/${l(e)}/teams/${l(r)}`;await(n?this.deleteConfirmed(i,n):this.delete(i))}async setTeamMember(e,r,n,i,s={}){await this.postConfirmed(`orgs/${l(e)}/teams/${l(r)}/members`,{account:n,...s},i)}async removeTeamMember(e,r,n,i){await this.deleteConfirmed(`orgs/${l(e)}/teams/${l(r)}/members/${l(n)}`,i)}async invite(e,r,n,i=[],s={}){let{token:o}=await this.postConfirmed(`orgs/${l(e)}/invites`,{role:r,teams:i,...s},n);return o}redeemInvite(e){return this.post(`invites/${l(e)}/redeem`)}async listInvites(e){let{invites:r}=await this.get(`orgs/${l(e)}/invites`);return r}async revokeInvite(e,r,n){await this.deleteConfirmed(`orgs/${l(e)}/invites/${l(r)}`,n)}listAppTeams(e){return this.get(`orgs/${l(e)}/app-teams`)}scopeApps(e,r,n={}){let i={};return n.apps!==void 0&&(i.apps=n.apps),n.shared!==void 0&&(i.shared=n.shared),this.postConfirmed(`orgs/${l(e)}/app-teams`,i,r)}grantDeployer(e,r,n={}){let i=n.until instanceof Date?n.until.toISOString():n.until;return this.postConfirmed("deployers",{deployer:e,...i===void 0?{}:{until:i}},r)}deployers(){return this.get("deployers")}async revokeDeployer(e,r){let n=typeof e=="string"?e:mt(e);await this.deleteConfirmed(`deployers/${l(n)}`,r)}async createDeployment(e,r,n){let{id:i}=await this.postConfirmed("deployments",{name:e,owner:r},n);return i}async deployments(){let{deployments:e}=await this.get("deployments");return e}deployment(e){return this.get(`deployments/${l(e)}`)}async deleteDeployment(e,r){await this.deleteConfirmed(`deployments/${l(e)}`,r)}offerApp(e,r,n){return this.postConfirmed(`deployments/${l(e)}/apps`,{...r},n)}async withdrawApp(e,r,n){await this.deleteConfirmed(`deployments/${l(e)}/apps/${l(r)}`,n)}deploymentOrgs(e){return this.get(`deployments/${l(e)}/orgs`)}};var vr={CREATE_APP:1,INVITE_MEMBERS:2,JOIN_OPEN_TEAMS:4,MANAGE_MEMBERS:8,MANAGE_APPLICATION:16,CREATE_TEAM:32,DELETE_TEAM:64,MANAGE_VISIBILITY:128,MANAGE_METADATA:256,APPROVE_RELEASES:1024},gi=vr.JOIN_OPEN_TEAMS;function pi(...t){return t.reduce((e,r)=>e|vr[r],0)}function Ve(t,e){return(t<<e|t>>>32-e)>>>0}function I(t,e,r,n,i){t[e]=t[e]+t[r]>>>0,t[i]=Ve(t[i]^t[e],16),t[n]=t[n]+t[i]>>>0,t[r]=Ve(t[r]^t[n],12),t[e]=t[e]+t[r]>>>0,t[i]=Ve(t[i]^t[e],8),t[n]=t[n]+t[i]>>>0,t[r]=Ve(t[r]^t[n],7)}function wt(t,e){return(t[e]|t[e+1]<<8|t[e+2]<<16|t[e+3]<<24)>>>0}function Et(t,e,r){let n=new Uint32Array(16);n[0]=1634760805,n[1]=857760878,n[2]=2036477234,n[3]=1797285236;for(let o=0;o<8;o+=1)n[4+o]=wt(t,o*4);n[12]=e>>>0;for(let o=0;o<3;o+=1)n[13+o]=wt(r,o*4);let i=n.slice();for(let o=0;o<10;o+=1)I(i,0,4,8,12),I(i,1,5,9,13),I(i,2,6,10,14),I(i,3,7,11,15),I(i,0,5,10,15),I(i,1,6,11,12),I(i,2,7,8,13),I(i,3,4,9,14);let s=new Uint8Array(64);for(let o=0;o<16;o+=1){let a=i[o]+n[o]>>>0;s[o*4]=a&255,s[o*4+1]=a>>>8&255,s[o*4+2]=a>>>16&255,s[o*4+3]=a>>>24&255}return s}function fi(t,e,r,n){let i=new Uint8Array(n.length);for(let s=0,o=e;s<n.length;s+=64,o+=1){let a=Et(t,o,r),c=Math.min(s+64,n.length);for(let d=s;d<c;d+=1)i[d]=n[d]^a[d-s]}return i}function xr(t){let e=0n;for(let r=t.length-1;r>=0;r-=1)e=e<<8n|BigInt(t[r]);return e}var yi=(1n<<130n)-5n;function hi(t,e){let r=xr(t.subarray(0,16))&0x0ffffffc0ffffffc0ffffffc0fffffffn,n=xr(t.subarray(16,32)),i=0n;for(let a=0;a<e.length;a+=16){let c=e.subarray(a,Math.min(a+16,e.length)),d=xr(c)+(1n<<BigInt(8*c.length));i=(i+d)*r%yi}let s=i+n&(1n<<128n)-1n,o=new Uint8Array(16);for(let a=0;a<16;a+=1)o[a]=Number(s&0xffn),s>>=8n;return o}function At(t){return new Uint8Array((16-t%16)%16)}function bt(t){let e=new Uint8Array(8);return new DataView(e.buffer).setBigUint64(0,BigInt(t),!0),e}function mi(t,e){let r=[t,At(t.length),e,At(e.length),bt(t.length),bt(e.length)],n=new Uint8Array(r.reduce((s,o)=>s+o.length,0)),i=0;for(let s of r)n.set(s,i),i+=s.length;return n}function wi(t,e){if(t.length!==32)throw new Error("ChaCha20-Poly1305 needs a 32-byte key");if(e.length!==12)throw new Error("ChaCha20-Poly1305 needs a 12-byte nonce")}function Rt(t,e,r,n=new Uint8Array(0)){wi(t,e);let i=Et(t,0,e).subarray(0,32),s=fi(t,1,e,r),o=hi(i,mi(n,s)),a=new Uint8Array(s.length+16);return a.set(s),a.set(o,s.length),a}var vt=32,Ai=1,bi=3,Ei=2,Ri=32,Pi=32,vi=12,X=t=>new TextEncoder().encode(t),pe=t=>new Uint8Array([t>>8&255,t&255]),Pt=h(X("KEM"),pe(vt)),ge=h(X("HPKE"),pe(vt),pe(Ai),pe(bi));async function xt(t,e){let r=t.length===0?new Uint8Array(32):t,n=await crypto.subtle.importKey("raw",r,{name:"HMAC",hash:"SHA-256"},!1,["sign"]);return new Uint8Array(await crypto.subtle.sign("HMAC",n,e))}async function xi(t,e,r){let n=new Uint8Array(r),i=new Uint8Array(0);for(let s=1,o=0;o<r;s+=1)i=await xt(t,h(i,e,new Uint8Array([s]))),n.set(i.subarray(0,Math.min(i.length,r-o)),o),o+=i.length;return n}function Le(t,e,r,n){return xt(e,h(X("HPKE-v1"),t,X(r),n))}function kr(t,e,r,n,i){return xi(e,h(pe(i),X("HPKE-v1"),t,X(r),n),i)}async function ki(t,e){let r=await Le(Pt,new Uint8Array(0),"eae_prk",t);return kr(Pt,r,"shared_secret",e,Ri)}async function Ui(t,e){let r=new Uint8Array(0),n=await Le(ge,r,"psk_id_hash",r),i=await Le(ge,r,"info_hash",e),s=h(new Uint8Array([Ei]),n,i),o=await Le(ge,t,"secret",r);return{key:await kr(ge,o,"key",s,Pi),nonce:await kr(ge,o,"base_nonce",s,vi)}}async function kt(t,e,r,n,i=new Uint8Array(0),s){if(t.length!==32)throw new Error("The recipient key is not 32 bytes of X25519");let o=await q(s),a=await q(e),c=h(await ee(o.privateKey,t),await ee(a.privateKey,t)),d=await ki(c,h(o.publicKey,t,a.publicKey)),{key:u,nonce:g}=await Ui(d,r);return{enc:o.publicKey,ciphertext:Rt(u,g,n,i)}}var Tt="mero-agent-gate/attest/v3",Ct="mero-agent-gate/provision/v2",Si=/^[a-z0-9][a-z0-9-]{0,62}$/,Ti=/^[A-Za-z0-9][A-Za-z0-9_.-]{0,63}$/,Ut=64,St=64*1024,D=class extends Error{constructor(r,n,i){super(r);this.status=n;this.code=i;this.name="AgentGateError"}};function Ot(t){if(!Si.test(t))throw new Error(`Agent id ${JSON.stringify(t)} must match [a-z0-9][a-z0-9-]{0,62}`)}function fe(t){return new TextEncoder().encode(t)}function It(t){let e=fe(t);return h(new Uint8Array([e.length]),e)}function G(t){let e="";for(let r of t)e+=String.fromCharCode(r);return btoa(e)}function Ge(t,e,r){let n;try{n=Uint8Array.from(atob(t.trim()),i=>i.charCodeAt(0))}catch{throw new Error(`${e} is not base64`)}if(r!==void 0&&n.length!==r)throw new Error(`${e} is not ${r} bytes`);return n}async function Dt(t,e,r,n){let i=new Uint8Array(32),s=h(fe(Tt),t,It(e),r??i,n??i);return new Uint8Array(await crypto.subtle.digest("SHA-256",s))}function Nt(t,e){return h(fe(Ct),t,It(e))}async function Ci(){let t=crypto.getRandomValues(new Uint8Array(32));return{secret:t,publicKey:await He(t)}}async function He(t){if(t.length!==32)throw new Error("An owner key is 32 bytes");return G((await q(t)).publicKey)}function Mt(t,e){return`${t.replace(/\/+$/,"")}${e}`}async function _t(t,e,r){let n=await t(e,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(r)}),i=await n.text(),s;try{s=i?JSON.parse(i):void 0}catch{}if(!n.ok){let o=s;throw new D(`The gate answered ${n.status}${o?.error?` ${o.error}`:""}: ${o?.details??i.slice(0,200)}`,n.status,o?.error)}return s}async function Ur(t){let e=t.agentId??"";e&&Ot(e);let r=crypto.getRandomValues(new Uint8Array(32)),n=await _t(t.fetch??fetch,Mt(t.gateUrl,"/attest"),{nonceB64:G(r),...e?{agentId:e}:{}});if((n?.agentId??"")!==e)throw new Error(`Asked about agent ${JSON.stringify(e)}, the gate answered for ${JSON.stringify(n?.agentId)}`);let i=Ge(n.provisioningPublicKeyB64??"","provisioningPublicKeyB64",32),s=n.signingPublicKeyB64?Ge(n.signingPublicKeyB64,"signingPublicKeyB64",32):void 0,o=n.ownerPublicKeyB64?Ge(n.ownerPublicKeyB64,"ownerPublicKeyB64",32):void 0;if(!s!=!o)throw new Error("A claimed agent has both a signing key and an owner; the gate named one");let a=await Dt(i,e,s,o);return await t.verifier({quoteB64:n.quoteB64,nonce:R(r),reportDataSuffix:R(a)}),{agentId:e,provisioningPublicKey:G(i),...s?{signingPublicKey:G(s)}:{},...o?{ownerPublicKey:G(o)}:{}}}async function $t(t,e){let r=await He(e);if(t.ownerPublicKey&&t.ownerPublicKey!==r)throw new D(`This agent is claimed by another key (${t.ownerPublicKey}); it is not yours. Send it nothing and do not authorize its signing key`,void 0,"not_yours");return r}function Oi(t){let e=Object.keys(t);if(e.length===0)throw new Error("There are no secrets to provision");if(e.length>Ut)throw new Error(`At most ${Ut} secrets at once`);for(let r of e){if(!Ti.test(r))throw new Error(`Secret name ${JSON.stringify(r)} must match [A-Za-z0-9][A-Za-z0-9_.-]{0,63}`);if(typeof t[r]!="string")throw new Error(`Secret ${r} is not a string`);if(fe(t[r]).length>St)throw new Error(`Secret ${r} is over ${St} bytes`)}}async function Bt(t,e,r,n,i,s){if(!n.agentId)throw new Error("This quote names no agent; attest with the agent id");let o=await $t(n,i),a=Ge(n.provisioningPublicKey,"provisioningPublicKey",32),c=await kt(a,i,Nt(a,n.agentId),fe(JSON.stringify(s)));return _t(t,Mt(e,r),{agentId:n.agentId,provisioningPublicKeyB64:n.provisioningPublicKey,senderPublicKeyB64:o,encappedKeyB64:G(c.enc),ciphertextB64:G(c.ciphertext)})}async function Ii(t){Oi(t.secrets);let e=t.fetch??fetch,r=await Bt(e,t.gateUrl,"/provision",t.agent,t.ownerSecret,{secrets:t.secrets}),n=await Ur({gateUrl:t.gateUrl,agentId:t.agent.agentId,verifier:t.verifier,fetch:e}),i=await He(t.ownerSecret);if(n.ownerPublicKey!==i||!n.signingPublicKey)throw new D("The gate accepted the secrets, but its quote does not name your key as owner");if(t.agent.signingPublicKey&&t.agent.signingPublicKey!==n.signingPublicKey)throw new D("The agent's signing key changed while provisioning");return{agentId:n.agentId,provisioningPublicKey:n.provisioningPublicKey,signingPublicKey:n.signingPublicKey,ownerPublicKey:i,written:r?.written??[],claimed:r?.claimed===!0}}async function Di(t){if(!t.agent.ownerPublicKey)throw new Error("This agent is not claimed; there is nothing to release");let e=t.fetch??fetch;if(await Bt(e,t.gateUrl,"/release",t.agent,t.ownerSecret,{release:!0}),(await Ur({gateUrl:t.gateUrl,agentId:t.agent.agentId,verifier:t.verifier,fetch:e})).ownerPublicKey)throw new D("The gate says it released the agent, but its quote still names an owner")}var Sr=Object.freeze({identity:"https://github.com/calimero-network/mero-tee/.github/workflows/release-kms.yaml@refs/heads/master",issuer:"https://token.actions.githubusercontent.com"}),Ni=["allowed_tcb_statuses","allowed_mrtd","allowed_rtmr0","allowed_rtmr1","allowed_rtmr2","allowed_rtmr3"];async function Mi(t,e,r={}){let n=typeof t=="string"?new TextEncoder().encode(t):t;await be(n,e,{identity:r.identity??Sr.identity,issuer:r.issuer??Sr.issuer});let i;try{i=JSON.parse(new TextDecoder().decode(n))}catch{throw new Error("The signed agent policy is not JSON")}let s=r.role??"agent";if(i?.role!==s)throw new Error(`The signed file is a ${JSON.stringify(i?.role)} policy, not an ${s} one`);let o=r.profile??_;if(i.profile!==o)throw new Error(`The signed agent policy is for the ${JSON.stringify(i.profile)} profile, not ${o}`);if(r.expectedVersion!==void 0&&i.version!==r.expectedVersion)throw new Error(`The signed agent policy is release ${JSON.stringify(i.version)}, not ${r.expectedVersion}`);return Kt(i),i}function Kt(t){for(let e of Ni)if(!Array.isArray(t?.[e])||t[e].length===0)throw new Error(`The agent policy's ${e} is empty, so no agent would be accepted`)}var _i=["UpToDate","SWHardeningNeeded","ConfigurationNeeded","ConfigurationAndSWHardeningNeeded","OutOfDate","OutOfDateConfigurationNeeded"];function $i(t){let e=_i.find(r=>r.toLowerCase()===t.trim().toLowerCase());if(!e)throw new Error(`The agent policy allows an unknown TCB status ${JSON.stringify(t)}`);return e}var ye=t=>t.trim().replace(/^0x/i,"");function Bi(t,e){return Kt(t),$({dcapVerify:e.dcapVerify,fetchCollateral:e.fetchCollateral,now:e.now,allowedTcbStatuses:t.allowed_tcb_statuses.map($i),allowedMrtd:t.allowed_mrtd.map(ye),allowedRtmr0:t.allowed_rtmr0.map(ye),allowedRtmr1:t.allowed_rtmr1.map(ye),allowedRtmr2:t.allowed_rtmr2.map(ye),allowedRtmr3:t.allowed_rtmr3.map(ye)})}export{Tt as AGENT_ATTEST_DOMAIN,Ct as AGENT_PROVISION_INFO_DOMAIN,D as AgentGateError,_e as AppError,xe as ArgsTooLarge,Te as BadOrigin,Pr as CalimeroClient,y as CalimeroError,Ie as ClusterNotUpgraded,oe as ConfirmCancelled,ae as ConfirmPromptBlocked,Z as ConfirmRequired,Se as ConsentStale,sr as DEFAULT_COLLATERAL_MIRROR,gr as DEFAULT_DIRECTORY,gi as DEFAULT_ORG_CAPABILITIES,Ee as DEFAULT_RELEASE_MIRROR,U as DirectoryError,Jr as GITHUB_RELEASES,Mr as HANDSHAKE_PATH,ke as IdempotencyMismatch,Sr as KMS_RELEASE_SIGNER,B as LoginRequired,mr as MAX_RECOVERY_NONCE_BYTES,Ar as MAX_REPORT_PAGE,Xr as MOCK_QUOTE_HEADER,ir as NODE_RELEASE_SIGNER,ve as NotFound,Oe as NotServing,vr as ORG_CAPABILITIES,V as OriginNotRegistered,Ce as OriginTaken,_ as PRODUCTION_PROFILE,Pe as PasskeyUnknownHere,Me as QuotaExceeded,nt as RECOVERY_DOMAIN,dt as RELEASE_VERIFIER,De as RecoveryNotReady,Ue as ReleaseDeadlineError,te as SEALED_CONTENT_TYPE,_r as SEALED_PATH,S as SealedTransportError,Ne as SignUpRefused,ne as StaleTransportKeyError,$e as TrapError,L as UnavailableError,K as WrongNode,ce as WrongRecoveryCode,Dt as agentKeyBinding,Bi as agentQuoteVerifier,Ur as attestAgent,P as b64url,Qn as browserPasskey,$t as checkOwner,Wr as claimedRelease,cr as cloudNodeReleaseUrl,de as compareVersions,br as confirmationCode,ei as consentReturn,$ as createQuoteVerifier,We as createSealedFetch,_n as createSignedReleaseVerifier,mt as deployerKey,Ke as errorFrom,ur as fetchAttestedKey,ar as fetchGithubNodeRelease,or as fetchNodeRelease,et as freshCollateral,O as fromB64url,ni as frontendManifest,Ci as generateOwnerKey,Yn as newRecoverySeed,pi as orgCapabilities,He as ownerPublicKey,ii as pageDeployment,ue as pageQuery,zn as parseRecoverySeed,Er as pendingApprovalsFrom,Ii as provisionAgent,Nt as provisionInfo,Xn as publisherBindingBytes,lt as publisherBindingMessage,it as recoveryMessage,Zn as recoveryPublicKey,Jn as recoverySeedText,Di as releaseAgent,pt as releaseConsent,ut as releaseNotesUrl,wr as signRecovery,ct as stalledBy,Xe as transportKeyBinding,Re as trustSignedRelease,nr as trustedMeasurementsFromReleases,ti as upgradeConsent,Ot as validateAgentId,gt as verifyReleaseUrl,Mi as verifySignedAgentPolicy,Yr as verifySignedNodeRelease,ri as withdrawConsent};
9
9
  //# sourceMappingURL=index.browser.mjs.map