@calimero-network/mero-js 17.0.0 → 18.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin-api/admin-client.d.ts +98 -9
- package/dist/admin-api/admin-client.js +113 -26
- package/dist/admin-api/admin-types.d.ts +345 -11
- package/dist/index.browser.mjs +2 -2
- package/dist/index.browser.mjs.map +3 -3
- package/dist/index.cjs +129 -26
- package/dist/index.cjs.map +2 -2
- package/dist/index.mjs +129 -26
- package/dist/index.mjs.map +2 -2
- package/package.json +1 -1
|
@@ -7,18 +7,16 @@ export interface AdminAuthStatus {
|
|
|
7
7
|
status: string;
|
|
8
8
|
};
|
|
9
9
|
}
|
|
10
|
+
/**
|
|
11
|
+
* Install by coordinates. The node fetches only from its own configured
|
|
12
|
+
* `[registry]`, so there is no caller-supplied URL; both halves are required.
|
|
13
|
+
*/
|
|
10
14
|
export interface InstallApplicationRequest {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
metadata: number[];
|
|
14
|
-
package?: string;
|
|
15
|
-
version?: string;
|
|
15
|
+
package: string;
|
|
16
|
+
version: string;
|
|
16
17
|
}
|
|
17
18
|
export interface InstallDevApplicationRequest {
|
|
18
19
|
path: string;
|
|
19
|
-
metadata: number[];
|
|
20
|
-
package?: string;
|
|
21
|
-
version?: string;
|
|
22
20
|
}
|
|
23
21
|
export interface InstallApplicationResponseData {
|
|
24
22
|
applicationId: string;
|
|
@@ -86,9 +84,9 @@ export interface BundleMigration {
|
|
|
86
84
|
toVersion?: string;
|
|
87
85
|
}
|
|
88
86
|
/**
|
|
89
|
-
* The subset of a registry bundle manifest that `
|
|
90
|
-
*
|
|
91
|
-
*
|
|
87
|
+
* The subset of a registry bundle manifest that `getRegistryVersions` consumes.
|
|
88
|
+
* The registry serves these at `GET {registry}/api/v2/bundles?package={package}`;
|
|
89
|
+
* installation itself needs only the coordinates, which the node resolves.
|
|
92
90
|
*/
|
|
93
91
|
export interface RegistryBundleManifest {
|
|
94
92
|
package: string;
|
|
@@ -443,6 +441,18 @@ export interface NodeIdentity {
|
|
|
443
441
|
* claim something the node the caller chose may not report.
|
|
444
442
|
*/
|
|
445
443
|
accountRootPublicKey?: string;
|
|
444
|
+
/**
|
|
445
|
+
* Whether this node holds the root key of the account it speaks for. `false`
|
|
446
|
+
* means it runs on a delegate device key, so it cannot certify another device
|
|
447
|
+
* into the account — which is what a pairing invite needs to know before
|
|
448
|
+
* offering the option.
|
|
449
|
+
*
|
|
450
|
+
* Optional for the same reason as `accountRootPublicKey`: a node at or below
|
|
451
|
+
* `0.11.0-rc.30` does not send it. `undefined` is therefore "this node is too
|
|
452
|
+
* old to say", which is not the same answer as `false`, and a caller gating an
|
|
453
|
+
* invite on it should not collapse the two.
|
|
454
|
+
*/
|
|
455
|
+
holdsAccountRoot?: boolean;
|
|
446
456
|
}
|
|
447
457
|
/**
|
|
448
458
|
* @deprecated Use {@link AdminApiClient.getNodeIdentity} instead. Nothing here
|
|
@@ -532,6 +542,330 @@ export interface SubgroupEntry {
|
|
|
532
542
|
groupId: string;
|
|
533
543
|
name?: string;
|
|
534
544
|
}
|
|
545
|
+
/**
|
|
546
|
+
* Adopt an account that already lives on another device, and mint this node a
|
|
547
|
+
* device of its own for it.
|
|
548
|
+
*
|
|
549
|
+
* The first half of pairing, run on the joining node. It publishes nothing and
|
|
550
|
+
* needs no key: it produces the values the account holder's
|
|
551
|
+
* {@link AdminApiClient.completeAccountPairing} certifies, plus a confirmation
|
|
552
|
+
* code to read out to them.
|
|
553
|
+
*
|
|
554
|
+
* Account-level, and that is the whole point of it: both credentials pairing
|
|
555
|
+
* mints were always account-wide - the certificate is root-signed and the
|
|
556
|
+
* endorsement node-level, so neither ever named a namespace - while the older
|
|
557
|
+
* per-namespace route still made the caller name one, and the device then
|
|
558
|
+
* listened on that one topic while its holder's link fanned out across all of
|
|
559
|
+
* them.
|
|
560
|
+
*/
|
|
561
|
+
export interface AccountPairInitRequest {
|
|
562
|
+
/**
|
|
563
|
+
* The epoch-0 root **public** key of the account to join, 64 hex characters -
|
|
564
|
+
* exactly what {@link NodeIdentity.accountRootPublicKey} reports on the node
|
|
565
|
+
* that already holds the account.
|
|
566
|
+
*
|
|
567
|
+
* Named for the half it carries. An ed25519 private and public key are both 32
|
|
568
|
+
* bytes and both hex, so nothing but the name tells them apart; the private
|
|
569
|
+
* root never crosses this boundary at all.
|
|
570
|
+
*/
|
|
571
|
+
accountRootPublicKey: string;
|
|
572
|
+
/**
|
|
573
|
+
* Ids of the namespaces to enroll into, 64 hex characters each. At least one:
|
|
574
|
+
* a device certified into nothing listens on no topic.
|
|
575
|
+
*
|
|
576
|
+
* The caller has to supply these, because the joining node cannot discover
|
|
577
|
+
* them - it is a member of nothing and holds no scope key, so it can neither
|
|
578
|
+
* read the account's namespace set off a DAG nor derive it. The device that
|
|
579
|
+
* already holds the account is the only party that knows it.
|
|
580
|
+
*
|
|
581
|
+
* This decides what the new device *listens* on, and it does not have to agree
|
|
582
|
+
* with the applications the holder scopes `pair-complete` to: a binding
|
|
583
|
+
* published where the device is not listening is picked up whenever it does
|
|
584
|
+
* subscribe, and a subscription the holder never reaches costs nothing.
|
|
585
|
+
*/
|
|
586
|
+
namespaces: string[];
|
|
587
|
+
}
|
|
588
|
+
/**
|
|
589
|
+
* What the joining device minted, for the account holder to certify.
|
|
590
|
+
*
|
|
591
|
+
* These are round-trip tokens: a caller copies them verbatim into
|
|
592
|
+
* {@link AdminApiClient.completeAccountPairing}. The signing key is the NEW
|
|
593
|
+
* device's, so it appears in no member listing yet and there is nothing here to
|
|
594
|
+
* compare it against.
|
|
595
|
+
*
|
|
596
|
+
* One device is minted however many namespaces were named, so there is one of
|
|
597
|
+
* each of these to hand over, not one per namespace.
|
|
598
|
+
*/
|
|
599
|
+
export interface AccountPairInitResponseData {
|
|
600
|
+
/** The account this device will speak for once linked, 64 hex characters. */
|
|
601
|
+
accountId: string;
|
|
602
|
+
/** The device that was minted, 64 hex characters. */
|
|
603
|
+
deviceId: string;
|
|
604
|
+
/** X25519 agreement key a scope key must be wrapped under to reach this device, hex. */
|
|
605
|
+
kemPublicKey: string;
|
|
606
|
+
/**
|
|
607
|
+
* The Ed25519 key this device signs its ops with, hex.
|
|
608
|
+
*
|
|
609
|
+
* The account holder cannot derive this - it is minted here - and the
|
|
610
|
+
* certificate names it, so it has to travel with the other two.
|
|
611
|
+
*/
|
|
612
|
+
signPublicKey: string;
|
|
613
|
+
/**
|
|
614
|
+
* Ed25519 signature over the account, the device id and both keys above, hex.
|
|
615
|
+
*
|
|
616
|
+
* Carried so the three values arrive as a statement by the device that minted
|
|
617
|
+
* them rather than as assertions by whoever relayed them; `pair-complete`
|
|
618
|
+
* refuses without it.
|
|
619
|
+
*/
|
|
620
|
+
statement: string;
|
|
621
|
+
/**
|
|
622
|
+
* The value to read out to the account holder, who compares it against what
|
|
623
|
+
* their `pair-complete` reports.
|
|
624
|
+
*
|
|
625
|
+
* The part a substituting attacker cannot fake: it can re-sign its own
|
|
626
|
+
* statement, but it would have to make its own keys derive the code the other
|
|
627
|
+
* side is already reading.
|
|
628
|
+
*/
|
|
629
|
+
confirmationCode: string;
|
|
630
|
+
}
|
|
631
|
+
/**
|
|
632
|
+
* Certify a device another node minted, link it, and deliver its scope keys.
|
|
633
|
+
*
|
|
634
|
+
* The second half of pairing, run on the node that holds the account root - the
|
|
635
|
+
* only party that can sign the certificate that makes the device real. Every
|
|
636
|
+
* field but `applications` is copied verbatim from that other node's
|
|
637
|
+
* {@link AccountPairInitResponseData}.
|
|
638
|
+
*/
|
|
639
|
+
export interface AccountPairCompleteRequest {
|
|
640
|
+
/** The `deviceId` the other node minted, 64 hex characters. */
|
|
641
|
+
deviceId: string;
|
|
642
|
+
/** That device's X25519 agreement key, 64 hex characters. */
|
|
643
|
+
kemPublicKey: string;
|
|
644
|
+
/** That device's Ed25519 signing key, 64 hex characters. */
|
|
645
|
+
signPublicKey: string;
|
|
646
|
+
/**
|
|
647
|
+
* The signature from that node's pair-init, 128 hex characters (64 bytes).
|
|
648
|
+
*
|
|
649
|
+
* Not optional: without it the three values above are only claims by whoever
|
|
650
|
+
* sent them, and certifying those would make attacker-supplied keys a trusted
|
|
651
|
+
* device of this account.
|
|
652
|
+
*/
|
|
653
|
+
statement: string;
|
|
654
|
+
/**
|
|
655
|
+
* The code the account holder read off the pairing device, e.g.
|
|
656
|
+
* `7BC0-DAAC-CCB4-84A4`. Grouping and case are ignored.
|
|
657
|
+
*
|
|
658
|
+
* Required so the comparison cannot be skipped: this side re-derives the code
|
|
659
|
+
* for the key material that actually arrived and refuses a mismatch. Its value
|
|
660
|
+
* rests on the code reaching the holder independently of this payload - sent
|
|
661
|
+
* beside the keys, it proves nothing. One code covers the whole pairing,
|
|
662
|
+
* because one device was minted for it.
|
|
663
|
+
*/
|
|
664
|
+
confirmationCode: string;
|
|
665
|
+
/**
|
|
666
|
+
* Which applications this device may speak for, 64 hex each. Omitted or empty means
|
|
667
|
+
* every one of them.
|
|
668
|
+
*
|
|
669
|
+
* Scoped by application rather than by namespace because a person can answer
|
|
670
|
+
* "which apps may this device use" and cannot answer "which namespaces" - a
|
|
671
|
+
* namespace is an implementation unit they never named. The node resolves
|
|
672
|
+
* these to namespaces through the same lookup
|
|
673
|
+
* {@link AdminApiClient.listNamespacesForApplication} reads.
|
|
674
|
+
*/
|
|
675
|
+
applications?: string[];
|
|
676
|
+
}
|
|
677
|
+
/** What pairing established. */
|
|
678
|
+
export interface AccountPairCompleteResponseData {
|
|
679
|
+
/** The account the device now speaks for, 64 hex characters. */
|
|
680
|
+
accountId: string;
|
|
681
|
+
/** The device that was linked, 64 hex characters. */
|
|
682
|
+
deviceId: string;
|
|
683
|
+
/**
|
|
684
|
+
* Whether the current scope key was wrapped and published for the device.
|
|
685
|
+
*
|
|
686
|
+
* `false` does not mean pairing failed - the link is what confers authority,
|
|
687
|
+
* and the device's own sync pull re-requests the key. It does mean the device
|
|
688
|
+
* cannot read until that lands.
|
|
689
|
+
*/
|
|
690
|
+
keyDelivered: boolean;
|
|
691
|
+
/**
|
|
692
|
+
* The code for the key material this certified - the same value the request
|
|
693
|
+
* carried, echoed so the operator can see what the certificate names.
|
|
694
|
+
*/
|
|
695
|
+
confirmationCode: string;
|
|
696
|
+
/**
|
|
697
|
+
* The `AccountProof<DeviceCert>` this pairing minted, hex-encoded borsh.
|
|
698
|
+
*
|
|
699
|
+
* The certified device needs this to present itself as a device of the
|
|
700
|
+
* account, and cannot read it off the DAG: doing so means being a member of a
|
|
701
|
+
* group the account speaks in, which a thin client never is. Not a secret - a
|
|
702
|
+
* certificate is public and proves nothing without the device key it names.
|
|
703
|
+
*/
|
|
704
|
+
credential: string;
|
|
705
|
+
}
|
|
706
|
+
/**
|
|
707
|
+
* Repair or widen the reach of a device this account already certified.
|
|
708
|
+
*
|
|
709
|
+
* Pairing is a snapshot: it bound the device wherever this node took part at the
|
|
710
|
+
* time, so a namespace created or joined afterwards holds no binding for it and
|
|
711
|
+
* the paired device silently never sees that namespace. This re-runs the fan-out
|
|
712
|
+
* against the namespaces this node takes part in now. The device need not be
|
|
713
|
+
* online, and nothing but its id is required - the certificate is already held
|
|
714
|
+
* here, root-signed and naming no namespace, so a fresh endorsement and a key
|
|
715
|
+
* wrap are all a later namespace is missing.
|
|
716
|
+
*/
|
|
717
|
+
export interface RelinkDeviceRequest {
|
|
718
|
+
/**
|
|
719
|
+
* Applications to add to the device's stored scope, 64 hex each.
|
|
720
|
+
*
|
|
721
|
+
* **Omitted or empty changes nothing** and repairs against the scope already
|
|
722
|
+
* stored, which is the request an operator makes to heal drift. Note that this
|
|
723
|
+
* is the one place an empty list does not mean "all": widening a narrow scope
|
|
724
|
+
* to every application is deliberately not expressible here, because
|
|
725
|
+
* overloading the empty list would make the accidental request the widest one.
|
|
726
|
+
*/
|
|
727
|
+
applications?: string[];
|
|
728
|
+
}
|
|
729
|
+
/** One namespace the relink published the device's link into. */
|
|
730
|
+
export interface RelinkOutcomeEntry {
|
|
731
|
+
/** The namespace id, 64 hex characters. */
|
|
732
|
+
namespaceId: string;
|
|
733
|
+
/**
|
|
734
|
+
* Whether the scope key was wrapped and published for the device here.
|
|
735
|
+
*
|
|
736
|
+
* `false` means the link landed and the delivery did not; the link is what
|
|
737
|
+
* confers authority, and the device's own sync pull re-requests the key.
|
|
738
|
+
*/
|
|
739
|
+
keyDelivered: boolean;
|
|
740
|
+
}
|
|
741
|
+
/** One namespace the relink published nothing into, and why. */
|
|
742
|
+
export interface RelinkSkipEntry {
|
|
743
|
+
/** The namespace id, 64 hex characters. */
|
|
744
|
+
namespaceId: string;
|
|
745
|
+
/**
|
|
746
|
+
* Why nothing was published there. Currently one of `outOfScope`,
|
|
747
|
+
* `alreadyBound`, `noScopeKey`, `revoked`, `ownDevice`, `failed`; left as a
|
|
748
|
+
* string because a node may report a reason newer than this SDK.
|
|
749
|
+
*/
|
|
750
|
+
reason: string;
|
|
751
|
+
}
|
|
752
|
+
/** What the relink repaired, and what it left alone. */
|
|
753
|
+
export interface RelinkDeviceResponseData {
|
|
754
|
+
/** The account the device speaks for, 64 hex characters. */
|
|
755
|
+
accountId: string;
|
|
756
|
+
/** The device that was repaired, 64 hex characters. */
|
|
757
|
+
deviceId: string;
|
|
758
|
+
/**
|
|
759
|
+
* The device's scope after the request, 64 hex each. Empty means every
|
|
760
|
+
* application, which is what a pairing that named none asked for.
|
|
761
|
+
*/
|
|
762
|
+
applications: string[];
|
|
763
|
+
/**
|
|
764
|
+
* Namespaces the link was published into by this call. Reported per namespace
|
|
765
|
+
* because publication is per-DAG, so which namespaces a device actually
|
|
766
|
+
* reached is a state the caller has to be able to see.
|
|
767
|
+
*/
|
|
768
|
+
linkedIn: RelinkOutcomeEntry[];
|
|
769
|
+
/** Namespaces nothing was published into. */
|
|
770
|
+
skipped: RelinkSkipEntry[];
|
|
771
|
+
}
|
|
772
|
+
/**
|
|
773
|
+
* One device of this account, joined from the node-local certificate cache and
|
|
774
|
+
* the live bindings of every namespace this node takes part in.
|
|
775
|
+
*/
|
|
776
|
+
export interface AccountDeviceEntry {
|
|
777
|
+
/** This device's id, 64 hex characters. */
|
|
778
|
+
deviceId: string;
|
|
779
|
+
/** The key this device signs its ops with, 64 hex. */
|
|
780
|
+
signingKey: string;
|
|
781
|
+
/** Set only on the device this node itself presents. */
|
|
782
|
+
isSelf: boolean;
|
|
783
|
+
revoked: boolean;
|
|
784
|
+
/**
|
|
785
|
+
* Applications this device may speak for, 64 hex each. **Empty means every
|
|
786
|
+
* application**, the same convention the stored certificate uses - and the
|
|
787
|
+
* opposite of what an empty {@link RelinkDeviceRequest.applications} asks for.
|
|
788
|
+
* Empty also for a device this node holds no cached certificate for: one bound
|
|
789
|
+
* before the cache existed, or certified by another holder.
|
|
790
|
+
*/
|
|
791
|
+
applications: string[];
|
|
792
|
+
/**
|
|
793
|
+
* Ids of the namespaces currently holding a live binding for this device, 64
|
|
794
|
+
* hex characters each. Empty for a certified device not yet bound anywhere.
|
|
795
|
+
*/
|
|
796
|
+
namespaces: string[];
|
|
797
|
+
}
|
|
798
|
+
/**
|
|
799
|
+
* One application this account speaks in, derived from the namespaces this node
|
|
800
|
+
* takes part in that target it.
|
|
801
|
+
*
|
|
802
|
+
* An application installed with no namespace yet is absent here: it has no
|
|
803
|
+
* cross-device meaning until a namespace exists, so there is nothing to scope a
|
|
804
|
+
* device to.
|
|
805
|
+
*/
|
|
806
|
+
export interface AccountApplicationEntry {
|
|
807
|
+
/** The application id, 64 hex. */
|
|
808
|
+
applicationId: string;
|
|
809
|
+
/** Ids of the namespaces targeting it, 64 hex characters each. */
|
|
810
|
+
namespaces: string[];
|
|
811
|
+
}
|
|
812
|
+
/** Withdraw a device from an account, terminally. */
|
|
813
|
+
export interface RevokeAccountDeviceRequest {
|
|
814
|
+
/** The device to withdraw, 64 hex. */
|
|
815
|
+
deviceId: string;
|
|
816
|
+
/**
|
|
817
|
+
* A hex-encoded, borsh-serialized signed revocation minted elsewhere -
|
|
818
|
+
* the output of `merod account revoke-proof`.
|
|
819
|
+
*
|
|
820
|
+
* The lost-device path: the account root that owns the device is not on this
|
|
821
|
+
* node, so the proof is signed offline and this node only publishes it. Omit
|
|
822
|
+
* it and the node mints its own proof if it owns the account, and otherwise
|
|
823
|
+
* revokes as an admin.
|
|
824
|
+
*
|
|
825
|
+
* Not a credential and not a secret - it authorises this one revocation of
|
|
826
|
+
* this one device, and only alongside a stored binding naming the same
|
|
827
|
+
* account.
|
|
828
|
+
*/
|
|
829
|
+
proof?: string;
|
|
830
|
+
}
|
|
831
|
+
/** What a revocation withdrew in one namespace. */
|
|
832
|
+
export interface RevocationOutcome {
|
|
833
|
+
/** The namespace, 64 hex. */
|
|
834
|
+
namespaceId: string;
|
|
835
|
+
/**
|
|
836
|
+
* Whether the scope key rotated in the same op, in THIS namespace.
|
|
837
|
+
*
|
|
838
|
+
* `false` means the device stopped writing there at once but still holds the
|
|
839
|
+
* key it had, so it can keep READING until an admin rotates. Only an admin
|
|
840
|
+
* may rotate and an account holder revoking their own device usually is not
|
|
841
|
+
* one, so this is commonly owed rather than exceptional.
|
|
842
|
+
*/
|
|
843
|
+
keyRotated: boolean;
|
|
844
|
+
}
|
|
845
|
+
export interface RevokeAccountDeviceResponseData {
|
|
846
|
+
/** The account the device spoke for, 64 hex. */
|
|
847
|
+
accountId: string;
|
|
848
|
+
/** The device that was withdrawn, 64 hex. */
|
|
849
|
+
deviceId: string;
|
|
850
|
+
/**
|
|
851
|
+
* Whether the scope key rotated in the namespace named in the request.
|
|
852
|
+
*
|
|
853
|
+
* {@link revokedIn} is the full picture; prefer it. This reports only the one
|
|
854
|
+
* namespace the caller asked about and is retained because core keeps it for
|
|
855
|
+
* a released `calimero-client-py` wheel that requires the field.
|
|
856
|
+
*/
|
|
857
|
+
keyRotated: boolean;
|
|
858
|
+
/**
|
|
859
|
+
* Every namespace the revocation was published into.
|
|
860
|
+
*
|
|
861
|
+
* A device belongs to an account rather than to a scope, so revoking it
|
|
862
|
+
* withdraws it from every namespace holding a binding for it - not only the
|
|
863
|
+
* one named in the request. Per namespace because publication is per-DAG: a
|
|
864
|
+
* namespace absent here did not receive the op, and a partially propagated
|
|
865
|
+
* revocation is a state the caller has to be able to see.
|
|
866
|
+
*/
|
|
867
|
+
revokedIn: RevocationOutcome[];
|
|
868
|
+
}
|
|
535
869
|
export interface CreateGroupRequest {
|
|
536
870
|
applicationId: string;
|
|
537
871
|
groupId?: string;
|
package/dist/index.browser.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
function F(s){let e=s.filter(Boolean);if(e.length===0)return;let t=AbortSignal;if(typeof t.any=="function")try{return t.any(e)}catch{}let n=new AbortController,r=i=>{n.abort(i.target.reason);for(let a of e)a.removeEventListener("abort",r)};for(let i of e){if(i.aborted)return AbortSignal.abort(i.reason);i.addEventListener("abort",r,{once:!0})}return n.signal}function z(s){if(typeof AbortSignal.timeout=="function")return AbortSignal.timeout(s);let e=new AbortController;return setTimeout(()=>{e.abort(new DOMException("Timeout","TimeoutError"))},s),e.signal}var _e=new Set(["token_reuse","token_revoked"]);function Ne(s){if(s)try{let e=JSON.parse(s)?.error;if(typeof e=="string"&&e.trim()!=="")return e;let t=e?.message;if(typeof t=="string"&&t.trim()!=="")return t}catch{}}var C=class extends Error{constructor(t,n,r,i,a){let c=Ne(a);super(c?`HTTP ${t} ${n}: ${c}`:`HTTP ${t} ${n}`);this.status=t;this.statusText=n;this.url=r;this.headers=i;this.bodyText=a;this.name="HTTPError"}toJSON(){return{status:this.status,statusText:this.statusText,url:this.url,headers:ue(this.headers),bodyText:this.bodyText}}},D=class extends C{constructor(t,n,r,i,a,c){super(n,r,i,a,c);this.reason=t;this.name="AuthRevokedError";this.message=`Authentication revoked (${t}): HTTP ${n} ${r}`}};function ue(s){let e={};return s.forEach((t,n)=>{e[n]=t}),e}var G=class{constructor(e){this.transport=e;this.refreshTokenPromise=null;this.onTokenRefreshPromise=null}async get(e,t){return this.request(e,{...t,method:"GET"})}async post(e,t,n){return this.request(e,{...n,method:"POST",body:t?JSON.stringify(t):void 0,headers:{"Content-Type":"application/json",...n?.headers}})}async put(e,t,n){return this.request(e,{...n,method:"PUT",body:t?JSON.stringify(t):void 0,headers:{"Content-Type":"application/json",...n?.headers}})}async delete(e,t){return this.request(e,{...t,method:"DELETE"})}async patch(e,t,n){return this.request(e,{...n,method:"PATCH",body:t?JSON.stringify(t):void 0,headers:{"Content-Type":"application/json",...n?.headers}})}async head(e,t){let n=await this.makeRequest(e,{...t,method:"HEAD",parse:"response"});return{headers:ue(n.headers),status:n.status}}async request(e,t){return this.makeRequest(e,t)}async makeRequest(e,t,n=0,r){let a=this.buildUrl(e),c=r??Date.now(),m=this.createAbortSignal(t),p=await this.buildHeaders(t?.headers),d;p instanceof Headers?(d={},p.forEach((l,P)=>{d[P]=l})):d=p;let h={method:t?.method||"GET",headers:d},f=t?.body instanceof ReadableStream||typeof t?.body=="object"&&t?.body!==null&&"getReader"in t.body&&!(t.body instanceof Blob);(t?.body!==void 0&&!f||t?.body!==void 0&&f&&n===0)&&(h.body=t.body);let y;if(n>0&&r!==void 0){let l=t?.timeoutMs||this.transport.timeoutMs;if(l){let P=Date.now()-c,U=Math.max(0,l-P);y=this.createAbortSignal({...t,timeoutMs:U})}else y=this.createAbortSignal(t)}else y=m;y&&(h.signal=y),this.transport.credentials!==void 0&&(h.credentials=this.transport.credentials),t?.mode!==void 0&&(h.mode=t.mode),t?.cache!==void 0&&(h.cache=t.cache),t?.redirect!==void 0&&(h.redirect=t.redirect),t?.referrer!==void 0&&(h.referrer=t.referrer),t?.referrerPolicy!==void 0&&(h.referrerPolicy=t.referrerPolicy),t?.integrity!==void 0&&(h.integrity=t.integrity),t?.keepalive!==void 0&&(h.keepalive=t.keepalive);try{let l=await this.transport.fetch(a,h);if(!l.ok){let P=await this.getBodyText(l),U=new C(l.status,l.statusText,a,l.headers,P),$=l.headers.get("x-auth-error");if((l.status===401||l.status===403)&&$&&_e.has($)){if(this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,this.transport.onAuthRevoked)try{await this.transport.onAuthRevoked()}catch{}throw new D($,l.status,l.statusText,a,l.headers,P)}let Ue=t?.signal?.aborted===!0;if(l.status===401&&this.transport.refreshToken&&$==="token_expired"&&n<1&&!f&&!Ue)try{let A=this.refreshTokenPromise;A||(A=this.transport.refreshToken(),this.refreshTokenPromise=A);let B=await A;if(!B||B.trim()==="")throw this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,new Error("Refresh token returned empty token");if(!this.transport.onTokenRefresh)throw this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,new Error("onTokenRefresh callback is required when refreshToken is provided. The callback must update the token storage so getAuthToken() returns the new token.");let q=this.onTokenRefreshPromise;q||(q=this.transport.onTokenRefresh(B),this.onTokenRefreshPromise=q),await q,this.refreshTokenPromise=null,this.onTokenRefreshPromise=null;let le=t?.timeoutMs||this.transport.timeoutMs;if(le&&r!==void 0){let Ge=Date.now()-c;if(le-Ge<=0)throw U}return this.makeRequest(e,t,n+1,c)}catch(A){throw this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,A instanceof Error&&A.message.includes("onTokenRefresh")?A:U}throw U}return this.parseResponse(l,t?.parse)}catch(l){throw l instanceof C||l instanceof Error&&l.message.includes("onTokenRefresh")?l:new C(0,"Network Error",a,new Headers,l instanceof Error?l.message:"Unknown error")}}buildUrl(e){if(e.startsWith("http://")||e.startsWith("https://"))return e;let t=this.transport.baseUrl;return e.startsWith("/")?`${t.endsWith("/")?t.slice(0,-1):t}${e}`:`${t.endsWith("/")?t:`${t}/`}${e}`}createAbortSignal(e){let t=[];this.transport.defaultAbortSignal&&t.push(this.transport.defaultAbortSignal),e?.signal&&t.push(e.signal);let n=e?.timeoutMs||this.transport.timeoutMs;return n&&t.push(z(n)),t.length>0?F(t):void 0}async buildHeaders(e){let t={...this.transport.defaultHeaders};if(this.transport.getAuthToken)try{let n=await this.transport.getAuthToken();n&&n.trim()!==""&&(t.Authorization=`Bearer ${n}`)}catch{}return e&&(e instanceof Headers?e.forEach((n,r)=>{t[r]=n}):Array.isArray(e)?e.forEach(([n,r])=>{t[n]=r}):Object.assign(t,e)),t}async parseResponse(e,t){switch(t){case"text":return await e.text();case"blob":return await e.blob();case"arrayBuffer":return await e.arrayBuffer();case"response":return e;default:{let n=await e.text();if(!n)return null;try{return JSON.parse(n)}catch{throw new Error(`Expected a JSON response (status ${e.status}) but body was not JSON: ${n.slice(0,200)}`)}}}}async getBodyText(e){try{let t=await e.text();return t.length>65536?t.slice(0,65536)+"...":t}catch{return""}}};function Q(s){return new G(s)}function S(s){let e={fetch:(t,n)=>globalThis.fetch(t,n),baseUrl:s.baseUrl,getAuthToken:s.getAuthToken,onTokenRefresh:s.onTokenRefresh,refreshToken:s.refreshToken,onAuthRevoked:s.onAuthRevoked,defaultHeaders:s.defaultHeaders,timeoutMs:s.timeoutMs,credentials:s.credentials,defaultAbortSignal:s.defaultAbortSignal};return Q(e)}function L(s){let e=s.fetch??globalThis.fetch;if(!e)throw new Error("No fetch implementation available. Please provide a fetch implementation (e.g., undici.fetch) or use Node.js 18+ which has native fetch support.");let n={fetch:e===globalThis.fetch?(r,i)=>globalThis.fetch(r,i):(r,i)=>e(r,i),baseUrl:s.baseUrl,getAuthToken:s.getAuthToken,onTokenRefresh:s.onTokenRefresh,refreshToken:s.refreshToken,onAuthRevoked:s.onAuthRevoked,defaultHeaders:s.defaultHeaders,timeoutMs:s.timeoutMs,credentials:s.credentials,defaultAbortSignal:s.defaultAbortSignal};return Q(n)}function X(s){return typeof window<"u"?S(s):L(s)}function He(s,e){if(e<=0)return!1;let n=s?.name;if(n==="TimeoutError")return!0;if(n==="AbortError")return!1;let r=s;if("status"in r&&typeof r.status=="number"){let i=r.status;return i>=500||i===429}return n==="TypeError"}function $e(s){let t=250*Math.pow(2,s-1),n=(Math.random()-.5)*.4*t;return Math.max(0,t+n)}async function O(s,e={}){let{attempts:t=3}=e,n;for(let r=1;r<=t;r++)try{return await s(r)}catch(i){if(n=i,!He(n,t-r))throw n;let a=$e(r),p=n.headers?.get?.("Retry-After");if(p){let d=parseInt(p,10);if(!isNaN(d))a=Math.max(a,d*1e3);else{let h=new Date(p);if(!isNaN(h.getTime())){let f=Math.max(0,h.getTime()-Date.now());a=Math.max(a,Math.min(f,6e4))}}}await new Promise(d=>setTimeout(d,a))}throw n||new Error("Retry failed without error")}function qe(s,e={}){return async(...t)=>O(()=>s(...t),e)}var v=class{constructor(e){this.httpClient=e}async getHealth(){let e=await this.httpClient.get("/auth/health");if(!e.data)throw new Error("Health response data is null");return e.data}async getIdentity(){let e=await this.httpClient.get("/admin/identity");if(!e.data)throw new Error("Identity response data is null");return e.data}async getProviders(){let e=await this.httpClient.get("/auth/providers");if(!e.data)throw new Error("Providers response data is null");return e.data}async getLoginPage(){return this.httpClient.get("/auth/login",{parse:"text"})}async generateTokens(e){return this.httpClient.post("/auth/token",e)}async refreshToken(e){return this.httpClient.post("/auth/refresh",e)}async generateMockTokens(e){return this.httpClient.post("/auth/mock-token",e)}async validateToken(e){try{let t=await this.validateTokenGet(e);return{valid:t.status===200,headers:t.headers,status:t.status}}catch{return{valid:!1,headers:{},status:401}}}async validateTokenGet(e){let t=await this.httpClient.head("/auth/validate",{headers:{Authorization:`Bearer ${e}`}});return{status:t.status,headers:t.headers}}async revokeTokens(e){let t=await this.httpClient.post("/admin/revoke",e);if(!t.data)throw new Error("Revoke tokens response data is null");return t.data}async listRootKeys(){let e=await this.httpClient.get("/admin/keys");if(!e.data)throw new Error("Root keys response data is null");return e.data}async createRootKey(e){let t=await this.httpClient.post("/admin/keys",e);if(!t.data)throw new Error("Create root key response data is null");return t.data}async deleteRootKey(e){return this.httpClient.delete(`/admin/keys/${e}`)}async listClientKeys(){let e=await this.httpClient.get("/admin/keys/clients");if(!e.data)throw new Error("Client keys response data is null");return e.data}async generateClientKey(e){return this.httpClient.post("/admin/client-key",e)}async deleteClientKey(e,t){return this.httpClient.delete(`/admin/keys/${e}/clients/${t}`)}async getKeyPermissions(e){return this.httpClient.get(`/admin/keys/${e}/permissions`)}async updateKeyPermissions(e,t){return this.httpClient.put(`/admin/keys/${e}/permissions`,{add:t.add,remove:t.remove})}};var _=class{async get(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async post(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async put(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async delete(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async patch(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async head(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async request(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}};function bt(s){let e=new _;return new v(e)}function Ct(s){let e=new _;return new v(e)}function Rt(s){let e=new _;return new v(e)}function de(s,e){return new v(s)}function o(s){return s?.data}function Le(s,e){let[t,n]=he(s),[r,i]=he(e),a=t.split("."),c=r.split("."),m=Math.max(a.length,c.length);for(let f=0;f<m;f++){let y=me(a[f]??"0",c[f]??"0");if(y!==0)return y}if(n===void 0&&i===void 0)return 0;if(n===void 0)return 1;if(i===void 0)return-1;let p=n.split("."),d=i.split("."),h=Math.max(p.length,d.length);for(let f=0;f<h;f++){if(f>=p.length)return-1;if(f>=d.length)return 1;let y=me(p[f],d[f]);if(y!==0)return y}return 0}function he(s){let e=s.split("+",1)[0],t=e.indexOf("-");return t===-1?[e,void 0]:[e.slice(0,t),e.slice(t+1)]}function me(s,e){let t=/^\d+$/.test(s),n=/^\d+$/.test(e);if(t&&n){let r=Number(s)-Number(e);return r<0?-1:r>0?1:0}return t?-1:n?1:s<e?-1:s>e?1:0}async function ge(s,e,t){return O(async()=>{let n=await fetch(s,{signal:AbortSignal.timeout(1e4)});if(!n.ok){let r=new Error(`registry ${e} fetch failed (${n.status}) for ${t}`);throw r.status=n.status,r}return n},{attempts:3})}var x=class{constructor(e){this.httpClient=e}async healthCheck(){return o(await this.httpClient.get("/admin-api/health"))}async isAuthed(){return this.httpClient.get("/admin-api/is-authed")}async installApplication(e){return o(await this.httpClient.post("/admin-api/install-application",e))}async installFromRegistry(e,t,n){let r=new URL(e).origin,i=new URL(`/api/v2/bundles/${encodeURIComponent(t)}/${encodeURIComponent(n)}`,r).toString(),c=await(await ge(i,"manifest",`${t}@${n}`)).json(),m=encodeURIComponent(c.package),p=encodeURIComponent(c.appVersion),d=`${r}/artifacts/${m}/${p}/${m}-${p}.mpk`;return this.installApplication({url:d,package:c.package,version:c.appVersion,metadata:[]})}async getRegistryVersions(e,t){let n=new URL("/api/v2/bundles",new URL(e).origin);n.searchParams.set("package",t);let i=await(await ge(n.toString(),"versions",t)).json();return(Array.isArray(i)?i:[]).map(a=>a.appVersion).filter(a=>typeof a=="string").sort((a,c)=>Le(c,a))}async installDevApplication(e){return o(await this.httpClient.post("/admin-api/install-dev-application",e))}async uninstallApplication(e){return o(await this.httpClient.delete(`/admin-api/applications/${e}`))}async listApplications(){return o(await this.httpClient.get("/admin-api/applications"))}async getApplication(e){return o(await this.httpClient.get(`/admin-api/applications/${e}`))}async listApplicationVersions(e){return o(await this.httpClient.get(`/admin-api/applications/${e}/versions`))}async getApplicationAbi(e,t){let n=t?`?service_name=${encodeURIComponent(t)}`:"";return o(await this.httpClient.get(`/admin-api/applications/${e}/abi${n}`))}async listPackages(){let e=await this.httpClient.get("/admin-api/packages");return e?.data??e}async listPackageVersions(e){let t=await this.httpClient.get(`/admin-api/packages/${encodeURIComponent(e)}/versions`);return t?.data??t}async getLatestPackageVersion(e){return this.httpClient.get(`/admin-api/packages/${encodeURIComponent(e)}/latest`)}async createContext(e){let t={...e,initializationParams:e.initializationParams??[]};return o(await this.httpClient.post("/admin-api/contexts",t))}async deleteContext(e,t){return o(t?await this.httpClient.request(`/admin-api/contexts/${e}`,{method:"DELETE",body:JSON.stringify(t),headers:{"Content-Type":"application/json"}}):await this.httpClient.delete(`/admin-api/contexts/${e}`))}async getContexts(){return o(await this.httpClient.get("/admin-api/contexts"))}async getContext(e){return o(await this.httpClient.get(`/admin-api/contexts/${e}`))}async getContextsForApplication(e){return o(await this.httpClient.get(`/admin-api/contexts/for-application/${e}`))}async generateContextIdentity(){return o(await this.httpClient.post("/admin-api/identity/context",{}))}async getContextIdentities(e){return o(await this.httpClient.get(`/admin-api/contexts/${e}/identities`))}async getContextIdentitiesOwned(e){return o(await this.httpClient.get(`/admin-api/contexts/${e}/identities-owned`))}async joinContext(e){return o(await this.httpClient.post(`/admin-api/contexts/${e}/join`,{}))}async getContextGroup(e){return o(await this.httpClient.get(`/admin-api/contexts/${e}/group`))}async getContextStorage(e){return o(await this.httpClient.get(`/admin-api/contexts/${e}/storage`))}async syncContext(e){await this.httpClient.post(`/admin-api/contexts/sync/${e??""}`,{})}async resyncContext(e,t={}){return await this.httpClient.post(`/admin-api/contexts/${e}/resync`,t)??{contextId:e,resyncStarted:!0}}async inviteSpecializedNode(e){return o(await this.httpClient.post("/admin-api/contexts/invite-specialized-node",e))}async updateContextApplication(e,t){await this.httpClient.post(`/admin-api/contexts/${e}/application`,t)}async getContextsWithExecutorsForApplication(e){let t=await this.httpClient.get(`/admin-api/contexts/with-executors/for-application/${e}`);return Array.isArray(t)?t:t?.contexts??t?.data??[]}async uploadBlob(e){let t=new URLSearchParams;e.hash&&t.set("hash",e.hash),e.contextId&&t.set("context_id",e.contextId);let n=t.toString(),r=n?`/admin-api/blobs?${n}`:"/admin-api/blobs",i=o(await this.httpClient.request(r,{method:"PUT",body:e.data,headers:{"Content-Type":"application/octet-stream"}}));return{blobId:i.blob_id,size:i.size}}async deleteBlob(e){let t=await this.httpClient.delete(`/admin-api/blobs/${e}`);return{blobId:t.blob_id,deleted:t.deleted}}async listBlobs(){return{blobs:o(await this.httpClient.get("/admin-api/blobs")).blobs.map(t=>({blobId:t.blob_id,size:t.size}))}}async getBlob(e){return this.httpClient.get(`/admin-api/blobs/${e}`,{parse:"arrayBuffer"})}async getBlobInfo(e){let{headers:t}=await this.httpClient.head(`/admin-api/blobs/${e}`),n=Number(t["content-length"]);return{blobId:t["x-blob-id"]??e,size:Number.isFinite(n)?n:0,hash:t["x-blob-hash"],mimeType:t["x-blob-mime-type"]}}async createContextAlias(e){return o(await this.httpClient.post("/admin-api/alias/create/context",{alias:e.alias,contextId:e.contextId}))}async createApplicationAlias(e){return o(await this.httpClient.post("/admin-api/alias/create/application",{alias:e.alias,applicationId:e.applicationId}))}async lookupContextAlias(e){return o(await this.httpClient.post(`/admin-api/alias/lookup/context/${encodeURIComponent(e)}`,{}))}async lookupApplicationAlias(e){return o(await this.httpClient.post(`/admin-api/alias/lookup/application/${encodeURIComponent(e)}`,{}))}async deleteContextAlias(e){return o(await this.httpClient.post(`/admin-api/alias/delete/context/${encodeURIComponent(e)}`,{}))}async deleteApplicationAlias(e){return o(await this.httpClient.post(`/admin-api/alias/delete/application/${encodeURIComponent(e)}`,{}))}async listContextAliases(){return o(await this.httpClient.get("/admin-api/alias/list/context"))}async listApplicationAliases(){return o(await this.httpClient.get("/admin-api/alias/list/application"))}async listNamespaces(){return o(await this.httpClient.get("/admin-api/namespaces"))}async getNamespace(e){return o(await this.httpClient.get(`/admin-api/namespaces/${e}`))}async getNodeIdentity(){return o(await this.httpClient.get("/admin-api/identity"))}async getNamespaceIdentity(e){let t=await this.getNodeIdentity();return{namespaceId:e,publicKey:t.publicKey,account:t.accountId}}async performIntent(e,t){return o(await this.httpClient.post(`/admin-api/contexts/${e}/intents`,t))}async listNamespacesForApplication(e){return o(await this.httpClient.get(`/admin-api/namespaces/for-application/${e}`))}async createNamespace(e){return o(await this.httpClient.post("/admin-api/namespaces",{upgradePolicy:"LazyOnAccess",...e}))}async deleteNamespace(e,t){return o(await this.httpClient.request(`/admin-api/namespaces/${e}`,{method:"DELETE",body:JSON.stringify(t??{}),headers:{"Content-Type":"application/json"}}))}async createNamespaceInvitation(e,t){return o(await this.httpClient.post(`/admin-api/namespaces/${e}/invite`,t??{}))}async admitJoin(e,t){return o(await this.httpClient.post(`/admin-api/namespaces/${e}/admit`,t,{timeoutMs:65e3}))}async joinNamespace(e,t){let n=o(await this.httpClient.post(`/admin-api/namespaces/${e}/join`,t,{timeoutMs:65e3}));return n&&n.namespaceId===void 0&&n.groupId!==void 0?{...n,namespaceId:n.groupId}:n}async createGroupInNamespace(e,t){return o(await this.httpClient.post(`/admin-api/namespaces/${e}/groups`,t??{}))}async listNamespaceGroups(e){return o(await this.httpClient.get(`/admin-api/namespaces/${e}/groups`))}async getGroupInfo(e){return o(await this.httpClient.get(`/admin-api/groups/${e}`))}async getDefaultCapabilities(e){return(await this.getGroupInfo(e)).defaultCapabilities}async getSubgroupVisibility(e){return(await this.getGroupInfo(e)).subgroupVisibility}async deleteGroup(e,t){return o(await this.httpClient.request(`/admin-api/groups/${e}`,{method:"DELETE",body:JSON.stringify(t??{}),headers:{"Content-Type":"application/json"}}))}async listGroupMembers(e){let t=await this.httpClient.get(`/admin-api/groups/${e}/members`);if(!Array.isArray(t?.members)){let n=String(e).replace(/[\r\n\t\s]/g,"").slice(0,64);throw new Error(`Invalid listGroupMembers response for group ${n}: missing or non-array \`members\` field`)}return t}async listGroupContexts(e){return o(await this.httpClient.get(`/admin-api/groups/${e}/contexts`))}async addGroupMembers(e,t){await this.httpClient.post(`/admin-api/groups/${e}/members`,t)}async removeGroupMembers(e,t){await this.httpClient.post(`/admin-api/groups/${e}/members/remove`,t)}async updateMemberRole(e,t,n){await this.httpClient.put(`/admin-api/groups/${e}/members/${t}/role`,n)}async getMemberCapabilities(e,t){return o(await this.httpClient.get(`/admin-api/groups/${e}/members/${t}/capabilities`))}async setMemberCapabilities(e,t,n){await this.httpClient.put(`/admin-api/groups/${e}/members/${t}/capabilities`,n)}async setDefaultCapabilities(e,t){await this.httpClient.put(`/admin-api/groups/${e}/settings/default-capabilities`,t)}async setSubgroupVisibility(e,t){await this.httpClient.put(`/admin-api/groups/${e}/settings/subgroup-visibility`,t)}async setTeeAdmissionPolicy(e,t){await this.httpClient.put(`/admin-api/groups/${e}/settings/tee-admission-policy`,t)}async getTeeAdmissionPolicy(e){let t=await this.httpClient.get(`/admin-api/groups/${e}/settings/tee-admission-policy`);return t.data??t}async setGroupMetadata(e,t){await this.httpClient.put(`/admin-api/groups/${e}/metadata`,t)}async getGroupMetadata(e){return(await this.httpClient.get(`/admin-api/groups/${e}/metadata`))?.data??null}async setMemberMetadata(e,t,n){await this.httpClient.put(`/admin-api/groups/${e}/members/${t}/metadata`,n)}async getMemberMetadata(e,t){return(await this.httpClient.get(`/admin-api/groups/${e}/members/${t}/metadata`))?.data??null}async setContextMetadata(e,t,n){await this.httpClient.put(`/admin-api/groups/${e}/contexts/${t}/metadata`,n)}async getContextMetadata(e,t){return(await this.httpClient.get(`/admin-api/groups/${e}/contexts/${t}/metadata`))?.data??null}async syncGroup(e,t){return o(await this.httpClient.post(`/admin-api/groups/${e}/sync`,t??{}))}async upgradeGroup(e,t){return o(await this.httpClient.post(`/admin-api/groups/${e}/upgrade`,t))}async getGroupUpgradeStatus(e){return o(await this.httpClient.get(`/admin-api/groups/${e}/upgrade/status`))}async getMigrationStatus(e){let t=encodeURIComponent(e);return this.httpClient.get(`/admin-api/groups/${t}/migration-status`)}async getCascadeStatus(e){let t=encodeURIComponent(e);return o(await this.httpClient.get(`/admin-api/groups/${t}/cascade-status`))}async retryGroupUpgrade(e,t){return o(await this.httpClient.post(`/admin-api/groups/${e}/upgrade/retry`,t??{}))}async reparentGroup(e,t){let n=await this.httpClient.post(`/admin-api/groups/${e}/reparent`,t);return n?.data??n}async listSubgroups(e){let t=await this.httpClient.get(`/admin-api/groups/${e}/subgroups`);return t.subgroups??t.data??[]}async detachContextFromGroup(e,t,n){await this.httpClient.post(`/admin-api/groups/${e}/contexts/${t}/remove`,n??{})}async createGroupInvitation(e,t){return o(await this.httpClient.post(`/admin-api/groups/${e}/invite`,t??{}))}async joinGroup(e){return o(await this.httpClient.post("/admin-api/groups/join",e))}async joinSubgroupInheritance(e){return o(await this.httpClient.post(`/admin-api/groups/${e}/join-via-inheritance`,{}))}async getTeeInfo(){return o(await this.httpClient.get("/admin-api/tee/info"))}async teeAttest(e){return o(await this.httpClient.post("/admin-api/tee/attest",e))}async teeVerifyQuote(e){return o(await this.httpClient.post("/admin-api/tee/verify-quote",e))}async getPeersCount(){return this.httpClient.get("/admin-api/peers")}async getNetworkStatus(){return this.httpClient.get("/admin-api/network/status")}async getUsage(){return this.httpClient.get("/admin-api/usage")}async getCertificate(){return this.httpClient.get("/admin-api/certificate",{parse:"text"})}async createGroup(e){return o(await this.httpClient.post("/admin-api/groups",{upgradePolicy:"LazyOnAccess",...e}))}async leaveGroup(e,t){await this.httpClient.post(`/admin-api/groups/${e}/leave`,t??{})}async leaveContext(e,t){await this.httpClient.post(`/admin-api/contexts/${e}/leave`,t??{})}async leaveNamespace(e,t){await this.httpClient.post(`/admin-api/namespaces/${e}/leave`,t??{})}async issueOwnershipProof(e,t){return this.httpClient.post(`/admin-api/groups/${e}/issue-ownership-proof`,t??{})}async issueNamespaceOwnershipProof(e,t){return this.httpClient.post(`/admin-api/groups/${e}/issue-namespace-ownership-proof`,t??{})}async setMemberAutoFollow(e,t,n){await this.httpClient.put(`/admin-api/groups/${e}/members/${t}/auto-follow`,n)}async abortMigration(e,t){return this.httpClient.post(`/admin-api/groups/${e}/migration/abort`,t??{})}};function Dt(s){return new x(S(s))}function St(s){return new x(L(s))}function Et(s){return new x(X(s))}function fe(s,e){return new x(s)}function Y(s){try{let e=s.indexOf("#");if(e===-1)return null;let t=s.substring(e+1),n=new URLSearchParams(t),r=n.get("access_token");return r?{accessToken:r,refreshToken:n.get("refresh_token")??"",applicationId:n.get("application_id")??"",contextId:n.get("context_id")??"",contextIdentity:n.get("context_identity")??"",nodeUrl:n.get("node_url")??""}:null}catch{return null}}function Z(s,e){let t=new URLSearchParams;return t.set("callback-url",e.callbackUrl),e.permissions&&e.permissions.length>0&&t.set("permissions",e.permissions.join(",")),t.set("mode",e.mode),e.packageName&&(t.set("package-name",e.packageName),e.packageVersion&&t.set("package-version",e.packageVersion),e.registryUrl&&t.set("registry-url",e.registryUrl)),`${s.replace(/\/+$/,"")}/auth/login?${t.toString()}`}var j=class extends Error{constructor(e,t,n,r){super(t),this.name="RpcError",this.code=e,this.data=n,this.type=r}};async function ee(s,e,t){let n=await s.post("/jsonrpc",{jsonrpc:"2.0",id:1,method:e,params:t});if(n.error){let r=n.error;throw new j(r.code??-1,r.message??r.type??"RPC error",r.data,r.type)}return n.result}var N=class{constructor(e){this.httpClient=e.httpClient}async execute(e){let t=await ee(this.httpClient,"execute",{contextId:e.contextId,method:e.method,argsJson:e.argsJson??{}});return t&&"output"in t?t.output:t}async migrateMyEntries(e){return this.execute({contextId:e,method:"migrate_my_entries"})}async countMyPending(e){return this.execute({contextId:e,method:"count_my_pending"})}};var Oe=new Set(["MigrationStarted","MigrationProgress","CascadeProgress","MigrationCompleted"]);function ye(s){return s.type!==void 0&&Oe.has(s.type)}var je=new Set(["token_reuse","token_revoked"]),E=class{constructor(e){this.sessionId=null;this.abortController=null;this.reconnectTimer=null;this.subscribedContextIds=new Set;this.subscribedGroupIds=new Set;this.closed=!1;this.listeners={connect:[],event:[],error:[]};this.baseUrl=e.baseUrl.replace(/\/+$/,""),this.getAuthToken=e.getAuthToken,this.reconnectDelayMs=e.reconnectDelayMs??3e3}on(e,t){let n=e;if(n in this.listeners){let r=this.listeners[n];r.includes(t)||r.push(t)}}off(e,t){let n=e;if(n in this.listeners){let r=this.listeners[n],i=r.indexOf(t);i!==-1&&r.splice(i,1)}}onAppVersionChanged(e){let t=n=>{if(n.type!=="AppVersionChanged")return;let r=n.data;e({contextId:n.contextId,fromVersion:r?.fromVersion,toVersion:r?.toVersion})};return this.on("event",t),()=>this.off("event",t)}onMigrationEvent(e){let t=n=>{ye(n)&&e(n)};return this.on("event",t),()=>this.off("event",t)}emit(e,t){let n=e;if(n in this.listeners)for(let r of this.listeners[n])try{r(t)}catch{}}async connect(){if(!(this.abortController&&!this.closed)){this.closed=!1,this.abortController=new AbortController;try{let e=await this.getAuthToken(),t=`${this.baseUrl}/sse`,n=await fetch(t,{headers:{Authorization:`Bearer ${e}`,Accept:"text/event-stream"},signal:this.abortController.signal});if(!n.ok){let r=n.headers.get("x-auth-error"),i=await n.text().catch(()=>{});throw n.status===401&&r&&je.has(r)?new D(r,n.status,n.statusText,t,n.headers,i):new C(n.status,n.statusText,t,n.headers,i)}if(!n.body)throw new Error("SSE response has no body");this.readStream(n.body).catch(r=>{if(this.closed)return;let i=r instanceof Error?r:new Error(String(r));this.emit("error",i),this.scheduleReconnect()})}catch(e){if(this.closed)return;let t=e instanceof Error?e:new Error(String(e));this.emit("error",t),this.scheduleReconnect()}}}async readStream(e){let t=e.getReader(),n=new TextDecoder,r="";try{for(;;){let{done:i,value:a}=await t.read();if(i)break;r+=n.decode(a,{stream:!0});let c=r.split(`
|
|
2
|
-
`);r=c.pop()??"";for(let m of c)if(m.startsWith("data:")){let p=m.slice(5).trim();p&&this.handleMessage(p)}}if(r+=n.decode(),r.startsWith("data:")){let i=r.slice(5).trim();i&&this.handleMessage(i)}}catch(i){if(this.closed)return;let a=i instanceof Error?i:new Error(String(i));this.emit("error",a)}this.closed||this.scheduleReconnect()}handleMessage(e){try{let t=JSON.parse(e);if(t.type==="connect"&&t.session_id){this.sessionId=t.session_id,this.emit("connect",t.session_id),(this.subscribedContextIds.size>0||this.subscribedGroupIds.size>0)&&this.sendSubscription("subscribe",{contextIds:[...this.subscribedContextIds],groupIds:[...this.subscribedGroupIds]});return}if(!t.result)return;let n=t.result.data;if(Array.isArray(n))try{let r=new Uint8Array(n),i=new TextDecoder().decode(r);n=JSON.parse(i)}catch{}if(t.result.contextId){this.emit("event",{contextId:t.result.contextId,type:t.result.type,data:n});return}t.result.groupId&&this.emit("event",{groupId:t.result.groupId,type:t.result.type,data:n})}catch{}}async subscribe(e){let t=Array.isArray(e)?{contextIds:e}:e,n=(t.contextIds??[]).filter(i=>!this.subscribedContextIds.has(i)),r=(t.groupIds??[]).filter(i=>!this.subscribedGroupIds.has(i));for(let i of t.contextIds??[])this.subscribedContextIds.add(i);for(let i of t.groupIds??[])this.subscribedGroupIds.add(i);(n.length>0||r.length>0)&&this.sessionId&&await this.sendSubscription("subscribe",{contextIds:n,groupIds:r})}async unsubscribe(e){let t=Array.isArray(e)?{contextIds:e}:e,n=(t.contextIds??[]).filter(i=>this.subscribedContextIds.has(i)),r=(t.groupIds??[]).filter(i=>this.subscribedGroupIds.has(i));for(let i of t.contextIds??[])this.subscribedContextIds.delete(i);for(let i of t.groupIds??[])this.subscribedGroupIds.delete(i);(n.length>0||r.length>0)&&this.sessionId&&await this.sendSubscription("unsubscribe",{contextIds:n,groupIds:r})}async sendSubscription(e,t){try{let n=await this.getAuthToken(),r={};t.contextIds&&t.contextIds.length>0&&(r.contextIds=t.contextIds),t.groupIds&&t.groupIds.length>0&&(r.groupIds=t.groupIds);let i=await fetch(`${this.baseUrl}/sse/subscription`,{method:"POST",headers:{Authorization:`Bearer ${n}`,"Content-Type":"application/json"},body:JSON.stringify({id:this.sessionId,method:e,params:r})});i.ok||this.emit("error",new Error(`SSE ${e} failed: ${i.status}`))}catch(n){this.emit("error",n instanceof Error?n:new Error(`SSE ${e} failed`))}}forceReconnect(){this.abortController&&(this.abortController.abort(),this.abortController=null),this.sessionId=null,this.connect()}scheduleReconnect(){this.closed||(this.reconnectTimer&&clearTimeout(this.reconnectTimer),this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.forceReconnect()},this.reconnectDelayMs))}close(){this.closed=!0,this.abortController&&(this.abortController.abort(),this.abortController=null),this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.sessionId=null,this.subscribedContextIds.clear(),this.subscribedGroupIds.clear()}};var W=class W{constructor(e){this.ws=null;this.closed=!1;this.reconnectAttempt=0;this.reconnectTimer=null;this.subscribedContextIds=new Set;this.subscribedGroupIds=new Set;this.listeners={connect:[],event:[],error:[]};this.baseUrl=e.baseUrl.replace(/\/+$/,""),this.getAuthToken=e.getAuthToken}on(e,t){let n=e;if(n in this.listeners){let r=this.listeners[n];r.includes(t)||r.push(t)}}off(e,t){let n=e;if(n in this.listeners){let r=this.listeners[n],i=r.indexOf(t);i!==-1&&r.splice(i,1)}}emit(e,t){let n=e;if(n in this.listeners)for(let r of this.listeners[n])try{r(t)}catch{}}async connect(){if(!(this.ws&&(this.ws.readyState===0||this.ws.readyState===1))){this.closed=!1;try{let e=await this.getAuthToken();if(!e)throw new Error("No authentication token available for WebSocket connection");let t=this.baseUrl.replace(/^http/,"ws");this.ws=new WebSocket(`${t}/ws?token=${encodeURIComponent(e)}`),this.ws.onopen=()=>{this.reconnectAttempt=0,this.emit("connect"),this.resubscribeAfterReconnect()},this.ws.onmessage=n=>{this.handleMessage(n.data)},this.ws.onerror=()=>{this.emit("error",new Error("WebSocket error"))},this.ws.onclose=()=>{this.closed||this.scheduleReconnect()}}catch(e){if(this.closed)return;let t=e instanceof Error?e:new Error(String(e));this.emit("error",t),this.scheduleReconnect()}}}handleMessage(e){if(typeof e=="string")try{let t=JSON.parse(e);if(!t.result)return;let n=t.result.data;if(Array.isArray(n))try{let r=new Uint8Array(n),i=new TextDecoder().decode(r);n=JSON.parse(i)}catch{}if(t.result.contextId){this.emit("event",{contextId:t.result.contextId,type:t.result.type,data:n});return}t.result.groupId&&this.emit("event",{groupId:t.result.groupId,type:t.result.type,data:n})}catch{}}subscribe(e){let t=Array.isArray(e)?{contextIds:e}:e;for(let n of t.contextIds??[])this.subscribedContextIds.add(n);for(let n of t.groupIds??[])this.subscribedGroupIds.add(n);this.ws&&this.ws.readyState===1&&this.sendMessage({id:null,method:"subscribe",params:this.buildSubscriptionParams(t.contextIds??[],t.groupIds??[])})}unsubscribe(e){let t=Array.isArray(e)?{contextIds:e}:e;for(let n of t.contextIds??[])this.subscribedContextIds.delete(n);for(let n of t.groupIds??[])this.subscribedGroupIds.delete(n);this.ws&&this.ws.readyState===1&&this.sendMessage({id:null,method:"unsubscribe",params:this.buildSubscriptionParams(t.contextIds??[],t.groupIds??[])})}resubscribeAfterReconnect(){this.subscribedContextIds.size===0&&this.subscribedGroupIds.size===0||this.sendMessage({id:null,method:"subscribe",params:this.buildSubscriptionParams([...this.subscribedContextIds],[...this.subscribedGroupIds])})}buildSubscriptionParams(e,t){let n={};return e.length>0&&(n.contextIds=e),t.length>0&&(n.groupIds=t),n}sendMessage(e){this.ws&&this.ws.readyState===1&&this.ws.send(JSON.stringify(e))}scheduleReconnect(){if(this.closed)return;this.reconnectTimer&&clearTimeout(this.reconnectTimer);let e=Math.min(1e3*Math.pow(2,this.reconnectAttempt),W.MAX_BACKOFF_MS);this.reconnectAttempt++,this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.connect()},e)}close(){this.closed=!0,this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.ws&&(this.ws.onclose=null,this.ws.close(),this.ws=null),this.subscribedContextIds.clear(),this.subscribedGroupIds.clear()}};W.MAX_BACKOFF_MS=3e4;var I=W;function J(){return{encode(s){return Array.from(new TextEncoder().encode(JSON.stringify(s)))},decode(s){return JSON.parse(new TextDecoder().decode(new Uint8Array(s)))}}}var H=class{constructor(e){this.httpClient=e.httpClient,this.sse=e.sse}async set(e,t,n=J()){await ee(this.httpClient,"set_ephemeral",{contextId:e,state:n.encode(t)})}subscribe(e,t,n=J()){let r=i=>{let a=i;if(a.type!=="Ephemeral"||a.contextId!==e)return;let c=a.data;if(!c?.author)return;let m=!!c.removed,p={author:c.author,state:m||c.state===void 0?void 0:n.decode(c.state),removed:m};c.ageMs!==void 0&&(p.ageMs=c.ageMs),t(p)};return this.sse.on("event",r),this.sse.connect().catch(()=>{}),this.sse.subscribe([e]).catch(()=>{}),()=>{this.sse.off("event",r)}}};var We="mero-js:token-refresh";function Je(){let e=globalThis.navigator?.locks;return e&&typeof e.request=="function"?e:null}function te(s,e){try{let t=s.split(".");if(t.length===3){let n=t[1].replace(/-/g,"+").replace(/_/g,"/");for(;n.length%4;)n+="=";let r=JSON.parse(atob(n));if(typeof r.exp=="number")return r.exp*1e3}}catch{}return e}var K=class{constructor(e){this.tokenData=null;this.refreshPromise=null;this.rpcClient=null;this.sseClient=null;this.wsClient=null;this.wsWarned=!1;this.config={timeoutMs:1e4,...e},this.tokenStore=e.tokenStore??null,this.tokenStore&&(this.tokenData=this.tokenStore.getTokens());let t=typeof window<"u"&&"__TAURI_INTERNALS__"in window;this.httpClient=S({baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||"",refreshToken:async()=>(await this.performTokenRefresh()).access_token,onTokenRefresh:async n=>{this.tokenData&&(this.tokenData.access_token=n,this.tokenStore?.setTokens(this.tokenData))},onAuthRevoked:async()=>{this.clearToken();try{await this.config.onAuthRevoked?.()}catch{}},timeoutMs:this.config.timeoutMs,credentials:this.config.requestCredentials??(t?"omit":void 0)}),this.authClient=de(this.httpClient,{baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||"",timeoutMs:this.config.timeoutMs}),this.adminClient=fe(this.httpClient,{baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||"",timeoutMs:this.config.timeoutMs})}get auth(){return this.authClient}get admin(){return this.adminClient}get rpc(){return this.rpcClient||(this.rpcClient=new N({httpClient:this.httpClient})),this.rpcClient}get events(){return this.sseClient||(this.sseClient=new E({baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||""})),this.sseClient}get ephemeral(){return this.ephemeralClient||(this.ephemeralClient=new H({httpClient:this.httpClient,sse:this.events})),this.ephemeralClient}get ws(){return this.wsWarned||(this.wsWarned=!0,console.warn("[mero-js] WsClient is experimental. Use mero.events (SSE) for production.")),this.wsClient||(this.wsClient=new I({baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||""})),this.wsClient}async authenticate(e){let t=e||this.config.credentials;if(!t)throw new Error("No credentials provided for authentication");try{let n={auth_method:"user_password",public_key:t.username,client_name:"mero-js-sdk",permissions:["admin"],timestamp:Math.floor(Date.now()/1e3),provider_data:{username:t.username,password:t.password}},r=await this.authClient.generateTokens(n),i=r.data.access_token;return this.tokenData={access_token:i,refresh_token:r.data.refresh_token,expires_at:te(i,Date.now()+36e5)},this.tokenStore?.setTokens(this.tokenData),this.tokenData}catch(n){throw new Error(`Authentication failed: ${n instanceof Error?n.message:"Unknown error"}`)}}async getValidToken(){return this.tokenData}async performTokenRefresh(){if(this.refreshPromise)return this.refreshPromise;let e=this.tokenData?.access_token,t=this.withRefreshLock(()=>this.performTokenRefreshLocked(e));this.refreshPromise=t;try{return await t}finally{this.refreshPromise===t&&(this.refreshPromise=null)}}withRefreshLock(e){let t=Je();return t?t.request(We,e):e()}async performTokenRefreshLocked(e){let t=this.tokenStore?.getTokens()??null;if(t?.refresh_token&&(this.tokenData=t,e&&t.access_token!==e))return t;if(!this.tokenData?.refresh_token)throw new Error("No refresh token available");try{let n=await this.authClient.refreshToken({access_token:this.tokenData.access_token,refresh_token:this.tokenData.refresh_token}),r=n.data.access_token;return this.tokenData={access_token:r,refresh_token:n.data.refresh_token,expires_at:te(r,Date.now()+36e5)},this.tokenStore?.setTokens(this.tokenData),this.tokenData}catch(n){throw new Error(`Token refresh failed: ${n instanceof Error?n.message:"Unknown error"}`)}}clearToken(){this.refreshPromise=null,this.tokenData=null,this.tokenStore?.clear()}isAuthenticated(){return this.tokenData!==null}setTokenData(e){let t=e.expires_at||te(e.access_token,Date.now()+36e5);this.tokenData={...e,expires_at:t},this.tokenStore?.setTokens(this.tokenData)}getTokenData(){return this.tokenData}close(){this.sseClient?.close(),this.wsClient?.close()}static parseAuthCallback(e){return Y(e)}static buildAuthLoginUrl(e,t){return Z(e,t)}};function Ke(s){return new K(s)}var ne=class{constructor(){this.tokens=null}getTokens(){return this.tokens}setTokens(e){this.tokens=e}clear(){this.tokens=null}},Ve="mero-tokens",se=class{constructor(e=Ve){this.key=e}getTokens(){try{if(typeof localStorage>"u")return null;let e=localStorage.getItem(this.key);if(!e)return null;let t=JSON.parse(e);return t&&t.access_token&&t.refresh_token?{access_token:t.access_token,refresh_token:t.refresh_token,expires_at:typeof t.expires_at=="number"?t.expires_at:Date.now()+36e5}:null}catch{return null}}setTokens(e){try{if(typeof localStorage>"u")return;localStorage.setItem(this.key,JSON.stringify(e))}catch{}}clear(){try{if(typeof localStorage>"u")return;localStorage.removeItem(this.key)}catch{}}};var re=class{constructor(e={}){this.baseUrl=(e.cloudBaseUrl||"https://cloud.calimero.network").replace(/\/+$/,"")}enableHA(e){let t=new URLSearchParams({group_id:e.groupId,context_id:e.contextId});e.redirectUrl&&t.set("redirect_url",e.redirectUrl),window.open(`${this.baseUrl}/enable-ha?${t.toString()}`)}disableHA(e){let t=new URLSearchParams({group_id:e.groupId,context_id:e.contextId});e.redirectUrl&&t.set("redirect_url",e.redirectUrl),window.open(`${this.baseUrl}/disable-ha?${t.toString()}`)}};var be=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,112,4,34,4,32]);function b(s){let e=new Uint8Array(4);return new DataView(e.buffer).setUint32(0,s,!0),e}function w(s){return Array.from(s,e=>e.toString(16).padStart(2,"0")).join("")}function u(s,e,t){let n=s.trim();if(!/^[0-9a-fA-F]*$/.test(n)||n.length!==t*2)throw new Error(`${e} must be ${t*2} hex characters, got ${n.length}`);let r=new Uint8Array(t);for(let i=0;i<t;i+=1)r[i]=Number.parseInt(n.slice(i*2,i*2+2),16);return r}function R(s){let e=new Uint8Array(8);return new DataView(e.buffer).setBigUint64(0,BigInt(s),!0),e}function g(...s){let e=new Uint8Array(s.reduce((n,r)=>n+r.length,0)),t=0;for(let n of s)e.set(n,t),t+=n.length;return e}async function k(s,e){let t=[R(s.length),s];for(let n of e)t.push(R(n.length),n);return new Uint8Array(await crypto.subtle.digest("SHA-256",g(...t)))}async function M(s){let e=u(s,"deviceSecret",32),t=g(be,e);try{return await crypto.subtle.importKey("pkcs8",t,{name:"Ed25519"},!1,["sign"])}catch(n){let r=n instanceof Error?`: ${n.message}`:"";throw new Error("this runtime has no WebCrypto Ed25519, so a warrant cannot be signed here. Node 18.4+, Safari 17+, Firefox 129+ and Chrome 137+ have it; otherwise mint the warrant with `merod account warrant`"+r)}}async function T(s){let e=u(s,"deviceSecret",32),t=g(be,e),n=await crypto.subtle.importKey("pkcs8",t,{name:"Ed25519"},!0,["sign"]),i=(await crypto.subtle.exportKey("jwk",n)).x;return Uint8Array.from(atob(i.replace(/-/g,"+").replace(/_/g,"/")),a=>a.charCodeAt(0))}var Be=new TextEncoder().encode("calimero.warrant.v1"),Fe=new TextEncoder().encode("calimero.warrant.intent.v1");async function ie(s,e){let t=new TextEncoder().encode(JSON.stringify(e));return k(Fe,[new TextEncoder().encode(s),t])}async function Ce(s){let e=u(s.context,"context",32),t=u(s.authorAccount,"authorAccount",32),n=u(s.executor,"executor",32),r=await M(s.deviceSecret),i=await T(s.deviceSecret),a=await ie(s.method,s.argsJson),c=R(s.nonce),m=R(s.notAfter),p=await k(Be,[e,t,i,n,a,c,m]),d=new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},r,p));return w(g(e,t,i,n,a,c,m,d))}var ze=new TextEncoder().encode("calimero.device.cert.v1"),Re=new TextEncoder().encode("calimero.account.genesis.v1"),Qe=new TextEncoder().encode("calimero.device.id.v1"),oe=2;async function we(s,e){if(e.length!==16)throw new Error(`nonce must be 16 bytes, got ${e.length}`);let t=u(s,"account",32);return w(await k(Qe,[t,e]))}async function ae(s){return k(ze,[u(s.account,"account",32),u(s.device,"device",32),u(s.signPublicKey,"signPublicKey",32),u(s.kemPublicKey,"kemPublicKey",32),b(s.keyEpoch),b(s.deviceEpoch)])}function Ae(s){return g(new Uint8Array([oe]),s.rootPublicKey,b(0),u(s.account,"account",32),u(s.device,"device",32),u(s.signPublicKey,"signPublicKey",32),u(s.kemPublicKey,"kemPublicKey",32),b(s.keyEpoch),b(s.deviceEpoch),s.signature)}async function ke(s){let e=await T(s.rootSecret),t=w(await k(Re,[g(new Uint8Array([oe]),e)])),n=0,r=await ae({account:t,device:s.device,signPublicKey:s.signPublicKey,kemPublicKey:s.kemPublicKey,keyEpoch:n,deviceEpoch:s.deviceEpoch}),i=await M(s.rootSecret),a=new Uint8Array(await crypto.subtle.sign("Ed25519",i,r)),c=Ae({rootPublicKey:e,account:t,device:s.device,signPublicKey:s.signPublicKey,kemPublicKey:s.kemPublicKey,keyEpoch:n,deviceEpoch:s.deviceEpoch,signature:a});return w(c)}async function ve(s){let e=await T(s);return w(await k(Re,[g(new Uint8Array([oe]),e)]))}var pe=8,Xe=new TextEncoder().encode("calimero.namespace.v1"),Ye=0,xe={GroupCreated:0,GroupReparented:1,GroupDeleted:2,AdminChanged:3,PolicyUpdated:4,MemberJoined:5,KeyDelivery:6,MemberJoinedOpen:7,MemberJoinedAt:8,NamespaceCreated:9,MemberJoinedViaTeeAttestation:10};function ce(s,e){if(s.length!==32)throw new Error(`${e} must be 32 bytes, got ${s.length}`);return new Uint8Array(s)}function Te(s,e){if(s==null)return new Uint8Array([0]);if(s.length!==32)throw new Error(`${e} must be 32 bytes, got ${s.length}`);return g(new Uint8Array([1]),new Uint8Array(s))}function Pe(s){let e=new TextEncoder().encode(s);return g(b(e.length),e)}function V(s){let e=s.invitation,t=e.admitters??[],n=s.admitter_addrs??[];return g(ce(e.inviter_identity,"inviter_identity"),ce(e.group_id,"group_id"),R(e.expiration_timestamp),ce(e.secret_salt,"secret_salt"),new Uint8Array([e.invited_role]),b(t.length),...t.map((r,i)=>u(r,`admitters[${i}]`,32)),Pe(s.inviter_signature),s.inviter_account?g(new Uint8Array([1]),u(s.inviter_account,"inviter_account",32)):new Uint8Array([0]),b(n.length),...n.map(Pe),Te(s.application_id,"application_id"),Te(s.app_key,"app_key"))}async function De(s){let e=s.parentOpHashes??[],t=u(s.credential,"credential",s.credential.length/2),n=BigInt(s.invitation.invitation.expiration_timestamp??0)!==0n,r=s.joinedAt??BigInt(Math.floor(Date.now()/1e3)),i=n?g(new Uint8Array([xe.MemberJoinedAt]),u(s.member,"member",32),V(s.invitation),R(r),t):g(new Uint8Array([xe.MemberJoined]),u(s.member,"member",32),V(s.invitation),t),a=g(new Uint8Array([Ye]),i),c=await M(s.deviceSecret),m=await T(s.deviceSecret),p=g(new Uint8Array([pe]),u(s.namespaceId,"namespaceId",32),b(e.length),...e.map((f,y)=>u(f,`parentOpHashes[${y}]`,32)),m,R(s.nonce),a),d=new Uint8Array(await crypto.subtle.sign("Ed25519",c,g(Xe,p))),h=new Uint8Array([0]);return w(g(p,d,h))}var Cn={CAN_CREATE_CONTEXT:1,CAN_INVITE_MEMBERS:2,CAN_JOIN_OPEN_SUBGROUPS:4,MANAGE_MEMBERS:8,MANAGE_APPLICATION:16,CAN_CREATE_SUBGROUP:32,CAN_DELETE_SUBGROUP:64,CAN_MANAGE_VISIBILITY:128,CAN_MANAGE_METADATA:256};function Rn(s,e){let t=e>>>0;return(s&t)>>>0===t}function wn(s,e){return(s|e)>>>0}function An(s,e){return(s&~e)>>>0}var Se=[2428,2429,2528,2529],Ze="localhost",et=2e3;function Ee(s){return`http://${Ze}:${s}`}function Ie(s,e){let t=s.endsWith("/")?s:`${s}/`;return new URL(e,t).toString()}async function Me(s,e={}){let{timeoutMs:t=et,signal:n}=e;if(n?.aborted)return!1;let r=new AbortController,i=()=>r.abort(),a=n;a&&a.addEventListener("abort",i,{once:!0});let c=setTimeout(()=>r.abort(),t);try{let m=Ie(s,"admin-api/health"),p=await fetch(m,{method:"GET",signal:r.signal});if(!p.ok)return!1;try{let d=await p.json(),h=d?.data?.status!==void 0?d?.data?.status:d?.status;return h===void 0?!0:typeof h=="string"&&h.toLowerCase()==="alive"}catch{return!0}}catch{return!1}finally{clearTimeout(c),a&&a.removeEventListener("abort",i)}}async function tt(s={}){let{ports:e=Se,timeoutMs:t,signal:n}=s;return(await Promise.all(e.map(async i=>{let a=Ee(i);return await Me(a,{timeoutMs:t,signal:n})?a:null}))).filter(i=>i!==null)}export{x as AdminApiClient,v as AuthApiClient,D as AuthRevokedError,Cn as CAPABILITIES,re as CloudClient,Se as DEFAULT_LOCAL_NODE_PORTS,H as EphemeralClient,C as HTTPError,se as LocalStorageTokenStore,ne as MemoryTokenStore,K as MeroJs,N as RpcClient,j as RpcError,pe as SIGNED_NAMESPACE_OP_SCHEMA_VERSION,E as SseClient,G as WebHttpClient,I as WsClient,ve as accountForRoot,Z as buildAuthLoginUrl,F as combineSignals,Le as compareSemver,Et as createAdminApiClient,fe as createAdminApiClientFromHttpClient,Rt as createAuthApiClient,de as createAuthApiClientFromHttpClient,Dt as createBrowserAdminApiClient,bt as createBrowserAuthApiClient,S as createBrowserHttpClient,Q as createHttpClient,Ke as createMeroJs,St as createNodeAdminApiClient,Ct as createNodeAuthApiClient,L as createNodeHttpClient,qe as createRetryableMethod,z as createTimeoutSignal,X as createUniversalHttpClient,ae as deviceCertPayload,tt as discoverLocalNodes,V as encodeSignedInvitation,Rn as hasCap,ie as intentHash,J as jsonCodec,Ee as localNodeUrl,we as mintDeviceId,Ie as nodeEndpoint,Y as parseAuthCallback,Me as probeNodeHealth,ke as signDeviceCert,De as signMemberJoinOp,Ce as signWarrant,wn as withCap,O as withRetry,An as withoutCap};
|
|
1
|
+
function F(s){let e=s.filter(Boolean);if(e.length===0)return;let t=AbortSignal;if(typeof t.any=="function")try{return t.any(e)}catch{}let n=new AbortController,r=i=>{n.abort(i.target.reason);for(let a of e)a.removeEventListener("abort",r)};for(let i of e){if(i.aborted)return AbortSignal.abort(i.reason);i.addEventListener("abort",r,{once:!0})}return n.signal}function z(s){if(typeof AbortSignal.timeout=="function")return AbortSignal.timeout(s);let e=new AbortController;return setTimeout(()=>{e.abort(new DOMException("Timeout","TimeoutError"))},s),e.signal}var Ue=new Set(["token_reuse","token_revoked"]);function _e(s){if(s)try{let e=JSON.parse(s)?.error;if(typeof e=="string"&&e.trim()!=="")return e;let t=e?.message;if(typeof t=="string"&&t.trim()!=="")return t}catch{}}var C=class extends Error{constructor(t,n,r,i,a){let c=_e(a);super(c?`HTTP ${t} ${n}: ${c}`:`HTTP ${t} ${n}`);this.status=t;this.statusText=n;this.url=r;this.headers=i;this.bodyText=a;this.name="HTTPError"}toJSON(){return{status:this.status,statusText:this.statusText,url:this.url,headers:ue(this.headers),bodyText:this.bodyText}}},P=class extends C{constructor(t,n,r,i,a,c){super(n,r,i,a,c);this.reason=t;this.name="AuthRevokedError";this.message=`Authentication revoked (${t}): HTTP ${n} ${r}`}};function ue(s){let e={};return s.forEach((t,n)=>{e[n]=t}),e}var U=class{constructor(e){this.transport=e;this.refreshTokenPromise=null;this.onTokenRefreshPromise=null}async get(e,t){return this.request(e,{...t,method:"GET"})}async post(e,t,n){return this.request(e,{...n,method:"POST",body:t?JSON.stringify(t):void 0,headers:{"Content-Type":"application/json",...n?.headers}})}async put(e,t,n){return this.request(e,{...n,method:"PUT",body:t?JSON.stringify(t):void 0,headers:{"Content-Type":"application/json",...n?.headers}})}async delete(e,t){return this.request(e,{...t,method:"DELETE"})}async patch(e,t,n){return this.request(e,{...n,method:"PATCH",body:t?JSON.stringify(t):void 0,headers:{"Content-Type":"application/json",...n?.headers}})}async head(e,t){let n=await this.makeRequest(e,{...t,method:"HEAD",parse:"response"});return{headers:ue(n.headers),status:n.status}}async request(e,t){return this.makeRequest(e,t)}async makeRequest(e,t,n=0,r){let a=this.buildUrl(e),c=r??Date.now(),f=this.createAbortSignal(t),l=await this.buildHeaders(t?.headers),h;l instanceof Headers?(h={},l.forEach((p,D)=>{h[D]=p})):h=l;let d={method:t?.method||"GET",headers:h},g=t?.body instanceof ReadableStream||typeof t?.body=="object"&&t?.body!==null&&"getReader"in t.body&&!(t.body instanceof Blob);(t?.body!==void 0&&!g||t?.body!==void 0&&g&&n===0)&&(d.body=t.body);let y;if(n>0&&r!==void 0){let p=t?.timeoutMs||this.transport.timeoutMs;if(p){let D=Date.now()-c,G=Math.max(0,p-D);y=this.createAbortSignal({...t,timeoutMs:G})}else y=this.createAbortSignal(t)}else y=f;y&&(d.signal=y),this.transport.credentials!==void 0&&(d.credentials=this.transport.credentials),t?.mode!==void 0&&(d.mode=t.mode),t?.cache!==void 0&&(d.cache=t.cache),t?.redirect!==void 0&&(d.redirect=t.redirect),t?.referrer!==void 0&&(d.referrer=t.referrer),t?.referrerPolicy!==void 0&&(d.referrerPolicy=t.referrerPolicy),t?.integrity!==void 0&&(d.integrity=t.integrity),t?.keepalive!==void 0&&(d.keepalive=t.keepalive);try{let p=await this.transport.fetch(a,d);if(!p.ok){let D=await this.getBodyText(p),G=new C(p.status,p.statusText,a,p.headers,D),$=p.headers.get("x-auth-error");if((p.status===401||p.status===403)&&$&&Ue.has($)){if(this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,this.transport.onAuthRevoked)try{await this.transport.onAuthRevoked()}catch{}throw new P($,p.status,p.statusText,a,p.headers,D)}let Me=t?.signal?.aborted===!0;if(p.status===401&&this.transport.refreshToken&&$==="token_expired"&&n<1&&!g&&!Me)try{let w=this.refreshTokenPromise;w||(w=this.transport.refreshToken(),this.refreshTokenPromise=w);let B=await w;if(!B||B.trim()==="")throw this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,new Error("Refresh token returned empty token");if(!this.transport.onTokenRefresh)throw this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,new Error("onTokenRefresh callback is required when refreshToken is provided. The callback must update the token storage so getAuthToken() returns the new token.");let q=this.onTokenRefreshPromise;q||(q=this.transport.onTokenRefresh(B),this.onTokenRefreshPromise=q),await q,this.refreshTokenPromise=null,this.onTokenRefreshPromise=null;let le=t?.timeoutMs||this.transport.timeoutMs;if(le&&r!==void 0){let Ge=Date.now()-c;if(le-Ge<=0)throw G}return this.makeRequest(e,t,n+1,c)}catch(w){throw this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,w instanceof Error&&w.message.includes("onTokenRefresh")?w:G}throw G}return this.parseResponse(p,t?.parse)}catch(p){throw p instanceof C||p instanceof Error&&p.message.includes("onTokenRefresh")?p:new C(0,"Network Error",a,new Headers,p instanceof Error?p.message:"Unknown error")}}buildUrl(e){if(e.startsWith("http://")||e.startsWith("https://"))return e;let t=this.transport.baseUrl;return e.startsWith("/")?`${t.endsWith("/")?t.slice(0,-1):t}${e}`:`${t.endsWith("/")?t:`${t}/`}${e}`}createAbortSignal(e){let t=[];this.transport.defaultAbortSignal&&t.push(this.transport.defaultAbortSignal),e?.signal&&t.push(e.signal);let n=e?.timeoutMs||this.transport.timeoutMs;return n&&t.push(z(n)),t.length>0?F(t):void 0}async buildHeaders(e){let t={...this.transport.defaultHeaders};if(this.transport.getAuthToken)try{let n=await this.transport.getAuthToken();n&&n.trim()!==""&&(t.Authorization=`Bearer ${n}`)}catch{}return e&&(e instanceof Headers?e.forEach((n,r)=>{t[r]=n}):Array.isArray(e)?e.forEach(([n,r])=>{t[n]=r}):Object.assign(t,e)),t}async parseResponse(e,t){switch(t){case"text":return await e.text();case"blob":return await e.blob();case"arrayBuffer":return await e.arrayBuffer();case"response":return e;default:{let n=await e.text();if(!n)return null;try{return JSON.parse(n)}catch{throw new Error(`Expected a JSON response (status ${e.status}) but body was not JSON: ${n.slice(0,200)}`)}}}}async getBodyText(e){try{let t=await e.text();return t.length>65536?t.slice(0,65536)+"...":t}catch{return""}}};function Q(s){return new U(s)}function S(s){let e={fetch:(t,n)=>globalThis.fetch(t,n),baseUrl:s.baseUrl,getAuthToken:s.getAuthToken,onTokenRefresh:s.onTokenRefresh,refreshToken:s.refreshToken,onAuthRevoked:s.onAuthRevoked,defaultHeaders:s.defaultHeaders,timeoutMs:s.timeoutMs,credentials:s.credentials,defaultAbortSignal:s.defaultAbortSignal};return Q(e)}function L(s){let e=s.fetch??globalThis.fetch;if(!e)throw new Error("No fetch implementation available. Please provide a fetch implementation (e.g., undici.fetch) or use Node.js 18+ which has native fetch support.");let n={fetch:e===globalThis.fetch?(r,i)=>globalThis.fetch(r,i):(r,i)=>e(r,i),baseUrl:s.baseUrl,getAuthToken:s.getAuthToken,onTokenRefresh:s.onTokenRefresh,refreshToken:s.refreshToken,onAuthRevoked:s.onAuthRevoked,defaultHeaders:s.defaultHeaders,timeoutMs:s.timeoutMs,credentials:s.credentials,defaultAbortSignal:s.defaultAbortSignal};return Q(n)}function X(s){return typeof window<"u"?S(s):L(s)}function Ne(s,e){if(e<=0)return!1;let n=s?.name;if(n==="TimeoutError")return!0;if(n==="AbortError")return!1;let r=s;if("status"in r&&typeof r.status=="number"){let i=r.status;return i>=500||i===429}return n==="TypeError"}function He(s){let t=250*Math.pow(2,s-1),n=(Math.random()-.5)*.4*t;return Math.max(0,t+n)}async function O(s,e={}){let{attempts:t=3}=e,n;for(let r=1;r<=t;r++)try{return await s(r)}catch(i){if(n=i,!Ne(n,t-r))throw n;let a=He(r),l=n.headers?.get?.("Retry-After");if(l){let h=parseInt(l,10);if(!isNaN(h))a=Math.max(a,h*1e3);else{let d=new Date(l);if(!isNaN(d.getTime())){let g=Math.max(0,d.getTime()-Date.now());a=Math.max(a,Math.min(g,6e4))}}}await new Promise(h=>setTimeout(h,a))}throw n||new Error("Retry failed without error")}function $e(s,e={}){return async(...t)=>O(()=>s(...t),e)}var k=class{constructor(e){this.httpClient=e}async getHealth(){let e=await this.httpClient.get("/auth/health");if(!e.data)throw new Error("Health response data is null");return e.data}async getIdentity(){let e=await this.httpClient.get("/admin/identity");if(!e.data)throw new Error("Identity response data is null");return e.data}async getProviders(){let e=await this.httpClient.get("/auth/providers");if(!e.data)throw new Error("Providers response data is null");return e.data}async getLoginPage(){return this.httpClient.get("/auth/login",{parse:"text"})}async generateTokens(e){return this.httpClient.post("/auth/token",e)}async refreshToken(e){return this.httpClient.post("/auth/refresh",e)}async generateMockTokens(e){return this.httpClient.post("/auth/mock-token",e)}async validateToken(e){try{let t=await this.validateTokenGet(e);return{valid:t.status===200,headers:t.headers,status:t.status}}catch{return{valid:!1,headers:{},status:401}}}async validateTokenGet(e){let t=await this.httpClient.head("/auth/validate",{headers:{Authorization:`Bearer ${e}`}});return{status:t.status,headers:t.headers}}async revokeTokens(e){let t=await this.httpClient.post("/admin/revoke",e);if(!t.data)throw new Error("Revoke tokens response data is null");return t.data}async listRootKeys(){let e=await this.httpClient.get("/admin/keys");if(!e.data)throw new Error("Root keys response data is null");return e.data}async createRootKey(e){let t=await this.httpClient.post("/admin/keys",e);if(!t.data)throw new Error("Create root key response data is null");return t.data}async deleteRootKey(e){return this.httpClient.delete(`/admin/keys/${e}`)}async listClientKeys(){let e=await this.httpClient.get("/admin/keys/clients");if(!e.data)throw new Error("Client keys response data is null");return e.data}async generateClientKey(e){return this.httpClient.post("/admin/client-key",e)}async deleteClientKey(e,t){return this.httpClient.delete(`/admin/keys/${e}/clients/${t}`)}async getKeyPermissions(e){return this.httpClient.get(`/admin/keys/${e}/permissions`)}async updateKeyPermissions(e,t){return this.httpClient.put(`/admin/keys/${e}/permissions`,{add:t.add,remove:t.remove})}};var _=class{async get(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async post(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async put(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async delete(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async patch(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async head(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async request(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}};function bt(s){let e=new _;return new k(e)}function Ct(s){let e=new _;return new k(e)}function Rt(s){let e=new _;return new k(e)}function de(s,e){return new k(s)}function o(s){return s?.data}function qe(s,e){let[t,n]=he(s),[r,i]=he(e),a=t.split("."),c=r.split("."),f=Math.max(a.length,c.length);for(let g=0;g<f;g++){let y=me(a[g]??"0",c[g]??"0");if(y!==0)return y}if(n===void 0&&i===void 0)return 0;if(n===void 0)return 1;if(i===void 0)return-1;let l=n.split("."),h=i.split("."),d=Math.max(l.length,h.length);for(let g=0;g<d;g++){if(g>=l.length)return-1;if(g>=h.length)return 1;let y=me(l[g],h[g]);if(y!==0)return y}return 0}function he(s){let e=s.split("+",1)[0],t=e.indexOf("-");return t===-1?[e,void 0]:[e.slice(0,t),e.slice(t+1)]}function me(s,e){let t=/^\d+$/.test(s),n=/^\d+$/.test(e);if(t&&n){let r=Number(s)-Number(e);return r<0?-1:r>0?1:0}return t?-1:n?1:s<e?-1:s>e?1:0}async function Le(s,e,t){return O(async()=>{let n=await fetch(s,{signal:AbortSignal.timeout(1e4)});if(!n.ok){let r=new Error(`registry ${e} fetch failed (${n.status}) for ${t}`);throw r.status=n.status,r}return n},{attempts:3})}var x=class{constructor(e){this.httpClient=e}async healthCheck(){return o(await this.httpClient.get("/admin-api/health"))}async isAuthed(){return this.httpClient.get("/admin-api/is-authed")}async installApplication(e){return o(await this.httpClient.post("/admin-api/install-application",e))}async getRegistryVersions(e,t){let n=new URL("/api/v2/bundles",new URL(e).origin);n.searchParams.set("package",t);let i=await(await Le(n.toString(),"versions",t)).json();return(Array.isArray(i)?i:[]).map(a=>a.appVersion).filter(a=>typeof a=="string").sort((a,c)=>qe(c,a))}async installDevApplication(e){return o(await this.httpClient.post("/admin-api/install-dev-application",e))}async uninstallApplication(e){return o(await this.httpClient.delete(`/admin-api/applications/${e}`))}async listApplications(){return o(await this.httpClient.get("/admin-api/applications"))}async getApplication(e){return o(await this.httpClient.get(`/admin-api/applications/${e}`))}async listApplicationVersions(e){return o(await this.httpClient.get(`/admin-api/applications/${e}/versions`))}async getApplicationAbi(e,t){let n=t?`?service_name=${encodeURIComponent(t)}`:"";return o(await this.httpClient.get(`/admin-api/applications/${e}/abi${n}`))}async listPackages(){let e=await this.httpClient.get("/admin-api/packages");return e?.data??e}async listPackageVersions(e){let t=await this.httpClient.get(`/admin-api/packages/${encodeURIComponent(e)}/versions`);return t?.data??t}async getLatestPackageVersion(e){return this.httpClient.get(`/admin-api/packages/${encodeURIComponent(e)}/latest`)}async createContext(e){let t={...e,initializationParams:e.initializationParams??[]};return o(await this.httpClient.post("/admin-api/contexts",t))}async deleteContext(e,t){return o(t?await this.httpClient.request(`/admin-api/contexts/${e}`,{method:"DELETE",body:JSON.stringify(t),headers:{"Content-Type":"application/json"}}):await this.httpClient.delete(`/admin-api/contexts/${e}`))}async getContexts(){return o(await this.httpClient.get("/admin-api/contexts"))}async getContext(e){return o(await this.httpClient.get(`/admin-api/contexts/${e}`))}async getContextsForApplication(e){return o(await this.httpClient.get(`/admin-api/contexts/for-application/${e}`))}async generateContextIdentity(){return o(await this.httpClient.post("/admin-api/identity/context",{}))}async getContextIdentities(e){return o(await this.httpClient.get(`/admin-api/contexts/${e}/identities`))}async getContextIdentitiesOwned(e){return o(await this.httpClient.get(`/admin-api/contexts/${e}/identities-owned`))}async joinContext(e){return o(await this.httpClient.post(`/admin-api/contexts/${e}/join`,{}))}async getContextGroup(e){return o(await this.httpClient.get(`/admin-api/contexts/${e}/group`))}async getContextStorage(e){return o(await this.httpClient.get(`/admin-api/contexts/${e}/storage`))}async syncContext(e){await this.httpClient.post(`/admin-api/contexts/sync/${e??""}`,{})}async resyncContext(e,t={}){return await this.httpClient.post(`/admin-api/contexts/${e}/resync`,t)??{contextId:e,resyncStarted:!0}}async inviteSpecializedNode(e){return o(await this.httpClient.post("/admin-api/contexts/invite-specialized-node",e))}async updateContextApplication(e,t){await this.httpClient.post(`/admin-api/contexts/${e}/application`,t)}async getContextsWithExecutorsForApplication(e){let t=await this.httpClient.get(`/admin-api/contexts/with-executors/for-application/${e}`);return Array.isArray(t)?t:t?.contexts??t?.data??[]}async uploadBlob(e){let t=new URLSearchParams;e.hash&&t.set("hash",e.hash),e.contextId&&t.set("context_id",e.contextId);let n=t.toString(),r=n?`/admin-api/blobs?${n}`:"/admin-api/blobs",i=o(await this.httpClient.request(r,{method:"PUT",body:e.data,headers:{"Content-Type":"application/octet-stream"}}));return{blobId:i.blob_id,size:i.size}}async deleteBlob(e){let t=await this.httpClient.delete(`/admin-api/blobs/${e}`);return{blobId:t.blob_id,deleted:t.deleted}}async listBlobs(){return{blobs:o(await this.httpClient.get("/admin-api/blobs")).blobs.map(t=>({blobId:t.blob_id,size:t.size}))}}async getBlob(e){return this.httpClient.get(`/admin-api/blobs/${e}`,{parse:"arrayBuffer"})}async getBlobInfo(e){let{headers:t}=await this.httpClient.head(`/admin-api/blobs/${e}`),n=Number(t["content-length"]);return{blobId:t["x-blob-id"]??e,size:Number.isFinite(n)?n:0,hash:t["x-blob-hash"],mimeType:t["x-blob-mime-type"]}}async createContextAlias(e){return o(await this.httpClient.post("/admin-api/alias/create/context",{alias:e.alias,contextId:e.contextId}))}async createApplicationAlias(e){return o(await this.httpClient.post("/admin-api/alias/create/application",{alias:e.alias,applicationId:e.applicationId}))}async lookupContextAlias(e){return o(await this.httpClient.post(`/admin-api/alias/lookup/context/${encodeURIComponent(e)}`,{}))}async lookupApplicationAlias(e){return o(await this.httpClient.post(`/admin-api/alias/lookup/application/${encodeURIComponent(e)}`,{}))}async deleteContextAlias(e){return o(await this.httpClient.post(`/admin-api/alias/delete/context/${encodeURIComponent(e)}`,{}))}async deleteApplicationAlias(e){return o(await this.httpClient.post(`/admin-api/alias/delete/application/${encodeURIComponent(e)}`,{}))}async listContextAliases(){return o(await this.httpClient.get("/admin-api/alias/list/context"))}async listApplicationAliases(){return o(await this.httpClient.get("/admin-api/alias/list/application"))}async listNamespaces(){return o(await this.httpClient.get("/admin-api/namespaces"))}async getNamespace(e){return o(await this.httpClient.get(`/admin-api/namespaces/${e}`))}async getNodeIdentity(){return o(await this.httpClient.get("/admin-api/identity"))}async getNamespaceIdentity(e){let t=await this.getNodeIdentity();return{namespaceId:e,publicKey:t.publicKey,account:t.accountId}}async performIntent(e,t){return o(await this.httpClient.post(`/admin-api/contexts/${e}/intents`,t))}async listNamespacesForApplication(e){return o(await this.httpClient.get(`/admin-api/namespaces/for-application/${e}`))}async createNamespace(e){return o(await this.httpClient.post("/admin-api/namespaces",{upgradePolicy:"LazyOnAccess",...e}))}async deleteNamespace(e,t){return o(await this.httpClient.request(`/admin-api/namespaces/${e}`,{method:"DELETE",body:JSON.stringify(t??{}),headers:{"Content-Type":"application/json"}}))}async createNamespaceInvitation(e,t){return o(await this.httpClient.post(`/admin-api/namespaces/${e}/invite`,t??{}))}async admitJoin(e,t){return o(await this.httpClient.post(`/admin-api/namespaces/${e}/admit`,t,{timeoutMs:65e3}))}async joinNamespace(e,t){let n=o(await this.httpClient.post(`/admin-api/namespaces/${e}/join`,t,{timeoutMs:65e3}));return n&&n.namespaceId===void 0&&n.groupId!==void 0?{...n,namespaceId:n.groupId}:n}async createGroupInNamespace(e,t){return o(await this.httpClient.post(`/admin-api/namespaces/${e}/groups`,t??{}))}async listNamespaceGroups(e){return o(await this.httpClient.get(`/admin-api/namespaces/${e}/groups`))}async initAccountPairing(e){return o(await this.httpClient.post("/admin-api/account/pair-init",e))}async completeAccountPairing(e){return o(await this.httpClient.post("/admin-api/account/pair-complete",e))}async relinkAccountDevice(e,t){return o(await this.httpClient.post(`/admin-api/account/devices/${e}/relink`,t??{}))}async listAccountDevices(){return(await this.httpClient.get("/admin-api/account/devices")).devices}async listAccountApplications(){return(await this.httpClient.get("/admin-api/account/applications")).applications}async revokeAccountDevice(e,t){return o(await this.httpClient.post(`/admin-api/namespaces/${e}/account/revoke`,t))}async getGroupInfo(e){return o(await this.httpClient.get(`/admin-api/groups/${e}`))}async getDefaultCapabilities(e){return(await this.getGroupInfo(e)).defaultCapabilities}async getSubgroupVisibility(e){return(await this.getGroupInfo(e)).subgroupVisibility}async deleteGroup(e,t){return o(await this.httpClient.request(`/admin-api/groups/${e}`,{method:"DELETE",body:JSON.stringify(t??{}),headers:{"Content-Type":"application/json"}}))}async listGroupMembers(e){let t=await this.httpClient.get(`/admin-api/groups/${e}/members`);if(!Array.isArray(t?.members)){let n=String(e).replace(/[\r\n\t\s]/g,"").slice(0,64);throw new Error(`Invalid listGroupMembers response for group ${n}: missing or non-array \`members\` field`)}return t}async listGroupContexts(e){return o(await this.httpClient.get(`/admin-api/groups/${e}/contexts`))}async addGroupMembers(e,t){await this.httpClient.post(`/admin-api/groups/${e}/members`,t)}async removeGroupMembers(e,t){await this.httpClient.post(`/admin-api/groups/${e}/members/remove`,t)}async updateMemberRole(e,t,n){await this.httpClient.put(`/admin-api/groups/${e}/members/${t}/role`,n)}async getMemberCapabilities(e,t){return o(await this.httpClient.get(`/admin-api/groups/${e}/members/${t}/capabilities`))}async setMemberCapabilities(e,t,n){await this.httpClient.put(`/admin-api/groups/${e}/members/${t}/capabilities`,n)}async setDefaultCapabilities(e,t){await this.httpClient.put(`/admin-api/groups/${e}/settings/default-capabilities`,t)}async setSubgroupVisibility(e,t){await this.httpClient.put(`/admin-api/groups/${e}/settings/subgroup-visibility`,t)}async setTeeAdmissionPolicy(e,t){await this.httpClient.put(`/admin-api/groups/${e}/settings/tee-admission-policy`,t)}async getTeeAdmissionPolicy(e){let t=await this.httpClient.get(`/admin-api/groups/${e}/settings/tee-admission-policy`);return t.data??t}async setGroupMetadata(e,t){await this.httpClient.put(`/admin-api/groups/${e}/metadata`,t)}async getGroupMetadata(e){return(await this.httpClient.get(`/admin-api/groups/${e}/metadata`))?.data??null}async setMemberMetadata(e,t,n){await this.httpClient.put(`/admin-api/groups/${e}/members/${t}/metadata`,n)}async getMemberMetadata(e,t){return(await this.httpClient.get(`/admin-api/groups/${e}/members/${t}/metadata`))?.data??null}async setContextMetadata(e,t,n){await this.httpClient.put(`/admin-api/groups/${e}/contexts/${t}/metadata`,n)}async getContextMetadata(e,t){return(await this.httpClient.get(`/admin-api/groups/${e}/contexts/${t}/metadata`))?.data??null}async syncGroup(e,t){return o(await this.httpClient.post(`/admin-api/groups/${e}/sync`,t??{}))}async upgradeGroup(e,t){return o(await this.httpClient.post(`/admin-api/groups/${e}/upgrade`,t))}async getGroupUpgradeStatus(e){return o(await this.httpClient.get(`/admin-api/groups/${e}/upgrade/status`))}async getMigrationStatus(e){let t=encodeURIComponent(e);return this.httpClient.get(`/admin-api/groups/${t}/migration-status`)}async getCascadeStatus(e){let t=encodeURIComponent(e);return o(await this.httpClient.get(`/admin-api/groups/${t}/cascade-status`))}async retryGroupUpgrade(e,t){return o(await this.httpClient.post(`/admin-api/groups/${e}/upgrade/retry`,t??{}))}async reparentGroup(e,t){let n=await this.httpClient.post(`/admin-api/groups/${e}/reparent`,t);return n?.data??n}async listSubgroups(e){let t=await this.httpClient.get(`/admin-api/groups/${e}/subgroups`);return t.subgroups??t.data??[]}async detachContextFromGroup(e,t,n){await this.httpClient.post(`/admin-api/groups/${e}/contexts/${t}/remove`,n??{})}async createGroupInvitation(e,t){return o(await this.httpClient.post(`/admin-api/groups/${e}/invite`,t??{}))}async joinGroup(e){return o(await this.httpClient.post("/admin-api/groups/join",e))}async joinSubgroupInheritance(e){return o(await this.httpClient.post(`/admin-api/groups/${e}/join-via-inheritance`,{}))}async getTeeInfo(){return o(await this.httpClient.get("/admin-api/tee/info"))}async teeAttest(e){return o(await this.httpClient.post("/admin-api/tee/attest",e))}async teeVerifyQuote(e){return o(await this.httpClient.post("/admin-api/tee/verify-quote",e))}async getPeersCount(){return this.httpClient.get("/admin-api/peers")}async getNetworkStatus(){return this.httpClient.get("/admin-api/network/status")}async getUsage(){return this.httpClient.get("/admin-api/usage")}async getCertificate(){return this.httpClient.get("/admin-api/certificate",{parse:"text"})}async createGroup(e){return o(await this.httpClient.post("/admin-api/groups",{upgradePolicy:"LazyOnAccess",...e}))}async leaveGroup(e,t){await this.httpClient.post(`/admin-api/groups/${e}/leave`,t??{})}async leaveContext(e,t){await this.httpClient.post(`/admin-api/contexts/${e}/leave`,t??{})}async leaveNamespace(e,t){await this.httpClient.post(`/admin-api/namespaces/${e}/leave`,t??{})}async issueOwnershipProof(e,t){return this.httpClient.post(`/admin-api/groups/${e}/issue-ownership-proof`,t??{})}async issueNamespaceOwnershipProof(e,t){return this.httpClient.post(`/admin-api/groups/${e}/issue-namespace-ownership-proof`,t??{})}async setMemberAutoFollow(e,t,n){await this.httpClient.put(`/admin-api/groups/${e}/members/${t}/auto-follow`,n)}async abortMigration(e,t){return this.httpClient.post(`/admin-api/groups/${e}/migration/abort`,t??{})}};function Pt(s){return new x(S(s))}function St(s){return new x(L(s))}function Et(s){return new x(X(s))}function ge(s,e){return new x(s)}function Y(s){try{let e=s.indexOf("#");if(e===-1)return null;let t=s.substring(e+1),n=new URLSearchParams(t),r=n.get("access_token");return r?{accessToken:r,refreshToken:n.get("refresh_token")??"",applicationId:n.get("application_id")??"",contextId:n.get("context_id")??"",contextIdentity:n.get("context_identity")??"",nodeUrl:n.get("node_url")??""}:null}catch{return null}}function Z(s,e){let t=new URLSearchParams;return t.set("callback-url",e.callbackUrl),e.permissions&&e.permissions.length>0&&t.set("permissions",e.permissions.join(",")),t.set("mode",e.mode),e.packageName&&(t.set("package-name",e.packageName),e.packageVersion&&t.set("package-version",e.packageVersion),e.registryUrl&&t.set("registry-url",e.registryUrl)),`${s.replace(/\/+$/,"")}/auth/login?${t.toString()}`}var j=class extends Error{constructor(e,t,n,r){super(t),this.name="RpcError",this.code=e,this.data=n,this.type=r}};async function ee(s,e,t){let n=await s.post("/jsonrpc",{jsonrpc:"2.0",id:1,method:e,params:t});if(n.error){let r=n.error;throw new j(r.code??-1,r.message??r.type??"RPC error",r.data,r.type)}return n.result}var N=class{constructor(e){this.httpClient=e.httpClient}async execute(e){let t=await ee(this.httpClient,"execute",{contextId:e.contextId,method:e.method,argsJson:e.argsJson??{}});return t&&"output"in t?t.output:t}async migrateMyEntries(e){return this.execute({contextId:e,method:"migrate_my_entries"})}async countMyPending(e){return this.execute({contextId:e,method:"count_my_pending"})}};var Oe=new Set(["MigrationStarted","MigrationProgress","CascadeProgress","MigrationCompleted"]);function fe(s){return s.type!==void 0&&Oe.has(s.type)}var je=new Set(["token_reuse","token_revoked"]),E=class{constructor(e){this.sessionId=null;this.abortController=null;this.reconnectTimer=null;this.subscribedContextIds=new Set;this.subscribedGroupIds=new Set;this.closed=!1;this.listeners={connect:[],event:[],error:[]};this.baseUrl=e.baseUrl.replace(/\/+$/,""),this.getAuthToken=e.getAuthToken,this.reconnectDelayMs=e.reconnectDelayMs??3e3}on(e,t){let n=e;if(n in this.listeners){let r=this.listeners[n];r.includes(t)||r.push(t)}}off(e,t){let n=e;if(n in this.listeners){let r=this.listeners[n],i=r.indexOf(t);i!==-1&&r.splice(i,1)}}onAppVersionChanged(e){let t=n=>{if(n.type!=="AppVersionChanged")return;let r=n.data;e({contextId:n.contextId,fromVersion:r?.fromVersion,toVersion:r?.toVersion})};return this.on("event",t),()=>this.off("event",t)}onMigrationEvent(e){let t=n=>{fe(n)&&e(n)};return this.on("event",t),()=>this.off("event",t)}emit(e,t){let n=e;if(n in this.listeners)for(let r of this.listeners[n])try{r(t)}catch{}}async connect(){if(!(this.abortController&&!this.closed)){this.closed=!1,this.abortController=new AbortController;try{let e=await this.getAuthToken(),t=`${this.baseUrl}/sse`,n=await fetch(t,{headers:{Authorization:`Bearer ${e}`,Accept:"text/event-stream"},signal:this.abortController.signal});if(!n.ok){let r=n.headers.get("x-auth-error"),i=await n.text().catch(()=>{});throw n.status===401&&r&&je.has(r)?new P(r,n.status,n.statusText,t,n.headers,i):new C(n.status,n.statusText,t,n.headers,i)}if(!n.body)throw new Error("SSE response has no body");this.readStream(n.body).catch(r=>{if(this.closed)return;let i=r instanceof Error?r:new Error(String(r));this.emit("error",i),this.scheduleReconnect()})}catch(e){if(this.closed)return;let t=e instanceof Error?e:new Error(String(e));this.emit("error",t),this.scheduleReconnect()}}}async readStream(e){let t=e.getReader(),n=new TextDecoder,r="";try{for(;;){let{done:i,value:a}=await t.read();if(i)break;r+=n.decode(a,{stream:!0});let c=r.split(`
|
|
2
|
+
`);r=c.pop()??"";for(let f of c)if(f.startsWith("data:")){let l=f.slice(5).trim();l&&this.handleMessage(l)}}if(r+=n.decode(),r.startsWith("data:")){let i=r.slice(5).trim();i&&this.handleMessage(i)}}catch(i){if(this.closed)return;let a=i instanceof Error?i:new Error(String(i));this.emit("error",a)}this.closed||this.scheduleReconnect()}handleMessage(e){try{let t=JSON.parse(e);if(t.type==="connect"&&t.session_id){this.sessionId=t.session_id,this.emit("connect",t.session_id),(this.subscribedContextIds.size>0||this.subscribedGroupIds.size>0)&&this.sendSubscription("subscribe",{contextIds:[...this.subscribedContextIds],groupIds:[...this.subscribedGroupIds]});return}if(!t.result)return;let n=t.result.data;if(Array.isArray(n))try{let r=new Uint8Array(n),i=new TextDecoder().decode(r);n=JSON.parse(i)}catch{}if(t.result.contextId){this.emit("event",{contextId:t.result.contextId,type:t.result.type,data:n});return}t.result.groupId&&this.emit("event",{groupId:t.result.groupId,type:t.result.type,data:n})}catch{}}async subscribe(e){let t=Array.isArray(e)?{contextIds:e}:e,n=(t.contextIds??[]).filter(i=>!this.subscribedContextIds.has(i)),r=(t.groupIds??[]).filter(i=>!this.subscribedGroupIds.has(i));for(let i of t.contextIds??[])this.subscribedContextIds.add(i);for(let i of t.groupIds??[])this.subscribedGroupIds.add(i);(n.length>0||r.length>0)&&this.sessionId&&await this.sendSubscription("subscribe",{contextIds:n,groupIds:r})}async unsubscribe(e){let t=Array.isArray(e)?{contextIds:e}:e,n=(t.contextIds??[]).filter(i=>this.subscribedContextIds.has(i)),r=(t.groupIds??[]).filter(i=>this.subscribedGroupIds.has(i));for(let i of t.contextIds??[])this.subscribedContextIds.delete(i);for(let i of t.groupIds??[])this.subscribedGroupIds.delete(i);(n.length>0||r.length>0)&&this.sessionId&&await this.sendSubscription("unsubscribe",{contextIds:n,groupIds:r})}async sendSubscription(e,t){try{let n=await this.getAuthToken(),r={};t.contextIds&&t.contextIds.length>0&&(r.contextIds=t.contextIds),t.groupIds&&t.groupIds.length>0&&(r.groupIds=t.groupIds);let i=await fetch(`${this.baseUrl}/sse/subscription`,{method:"POST",headers:{Authorization:`Bearer ${n}`,"Content-Type":"application/json"},body:JSON.stringify({id:this.sessionId,method:e,params:r})});i.ok||this.emit("error",new Error(`SSE ${e} failed: ${i.status}`))}catch(n){this.emit("error",n instanceof Error?n:new Error(`SSE ${e} failed`))}}forceReconnect(){this.abortController&&(this.abortController.abort(),this.abortController=null),this.sessionId=null,this.connect()}scheduleReconnect(){this.closed||(this.reconnectTimer&&clearTimeout(this.reconnectTimer),this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.forceReconnect()},this.reconnectDelayMs))}close(){this.closed=!0,this.abortController&&(this.abortController.abort(),this.abortController=null),this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.sessionId=null,this.subscribedContextIds.clear(),this.subscribedGroupIds.clear()}};var W=class W{constructor(e){this.ws=null;this.closed=!1;this.reconnectAttempt=0;this.reconnectTimer=null;this.subscribedContextIds=new Set;this.subscribedGroupIds=new Set;this.listeners={connect:[],event:[],error:[]};this.baseUrl=e.baseUrl.replace(/\/+$/,""),this.getAuthToken=e.getAuthToken}on(e,t){let n=e;if(n in this.listeners){let r=this.listeners[n];r.includes(t)||r.push(t)}}off(e,t){let n=e;if(n in this.listeners){let r=this.listeners[n],i=r.indexOf(t);i!==-1&&r.splice(i,1)}}emit(e,t){let n=e;if(n in this.listeners)for(let r of this.listeners[n])try{r(t)}catch{}}async connect(){if(!(this.ws&&(this.ws.readyState===0||this.ws.readyState===1))){this.closed=!1;try{let e=await this.getAuthToken();if(!e)throw new Error("No authentication token available for WebSocket connection");let t=this.baseUrl.replace(/^http/,"ws");this.ws=new WebSocket(`${t}/ws?token=${encodeURIComponent(e)}`),this.ws.onopen=()=>{this.reconnectAttempt=0,this.emit("connect"),this.resubscribeAfterReconnect()},this.ws.onmessage=n=>{this.handleMessage(n.data)},this.ws.onerror=()=>{this.emit("error",new Error("WebSocket error"))},this.ws.onclose=()=>{this.closed||this.scheduleReconnect()}}catch(e){if(this.closed)return;let t=e instanceof Error?e:new Error(String(e));this.emit("error",t),this.scheduleReconnect()}}}handleMessage(e){if(typeof e=="string")try{let t=JSON.parse(e);if(!t.result)return;let n=t.result.data;if(Array.isArray(n))try{let r=new Uint8Array(n),i=new TextDecoder().decode(r);n=JSON.parse(i)}catch{}if(t.result.contextId){this.emit("event",{contextId:t.result.contextId,type:t.result.type,data:n});return}t.result.groupId&&this.emit("event",{groupId:t.result.groupId,type:t.result.type,data:n})}catch{}}subscribe(e){let t=Array.isArray(e)?{contextIds:e}:e;for(let n of t.contextIds??[])this.subscribedContextIds.add(n);for(let n of t.groupIds??[])this.subscribedGroupIds.add(n);this.ws&&this.ws.readyState===1&&this.sendMessage({id:null,method:"subscribe",params:this.buildSubscriptionParams(t.contextIds??[],t.groupIds??[])})}unsubscribe(e){let t=Array.isArray(e)?{contextIds:e}:e;for(let n of t.contextIds??[])this.subscribedContextIds.delete(n);for(let n of t.groupIds??[])this.subscribedGroupIds.delete(n);this.ws&&this.ws.readyState===1&&this.sendMessage({id:null,method:"unsubscribe",params:this.buildSubscriptionParams(t.contextIds??[],t.groupIds??[])})}resubscribeAfterReconnect(){this.subscribedContextIds.size===0&&this.subscribedGroupIds.size===0||this.sendMessage({id:null,method:"subscribe",params:this.buildSubscriptionParams([...this.subscribedContextIds],[...this.subscribedGroupIds])})}buildSubscriptionParams(e,t){let n={};return e.length>0&&(n.contextIds=e),t.length>0&&(n.groupIds=t),n}sendMessage(e){this.ws&&this.ws.readyState===1&&this.ws.send(JSON.stringify(e))}scheduleReconnect(){if(this.closed)return;this.reconnectTimer&&clearTimeout(this.reconnectTimer);let e=Math.min(1e3*Math.pow(2,this.reconnectAttempt),W.MAX_BACKOFF_MS);this.reconnectAttempt++,this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.connect()},e)}close(){this.closed=!0,this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.ws&&(this.ws.onclose=null,this.ws.close(),this.ws=null),this.subscribedContextIds.clear(),this.subscribedGroupIds.clear()}};W.MAX_BACKOFF_MS=3e4;var I=W;function J(){return{encode(s){return Array.from(new TextEncoder().encode(JSON.stringify(s)))},decode(s){return JSON.parse(new TextDecoder().decode(new Uint8Array(s)))}}}var H=class{constructor(e){this.httpClient=e.httpClient,this.sse=e.sse}async set(e,t,n=J()){await ee(this.httpClient,"set_ephemeral",{contextId:e,state:n.encode(t)})}subscribe(e,t,n=J()){let r=i=>{let a=i;if(a.type!=="Ephemeral"||a.contextId!==e)return;let c=a.data;if(!c?.author)return;let f=!!c.removed,l={author:c.author,state:f||c.state===void 0?void 0:n.decode(c.state),removed:f};c.ageMs!==void 0&&(l.ageMs=c.ageMs),t(l)};return this.sse.on("event",r),this.sse.connect().catch(()=>{}),this.sse.subscribe([e]).catch(()=>{}),()=>{this.sse.off("event",r)}}};var We="mero-js:token-refresh";function Je(){let e=globalThis.navigator?.locks;return e&&typeof e.request=="function"?e:null}function te(s,e){try{let t=s.split(".");if(t.length===3){let n=t[1].replace(/-/g,"+").replace(/_/g,"/");for(;n.length%4;)n+="=";let r=JSON.parse(atob(n));if(typeof r.exp=="number")return r.exp*1e3}}catch{}return e}var K=class{constructor(e){this.tokenData=null;this.refreshPromise=null;this.rpcClient=null;this.sseClient=null;this.wsClient=null;this.wsWarned=!1;this.config={timeoutMs:1e4,...e},this.tokenStore=e.tokenStore??null,this.tokenStore&&(this.tokenData=this.tokenStore.getTokens());let t=typeof window<"u"&&"__TAURI_INTERNALS__"in window;this.httpClient=S({baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||"",refreshToken:async()=>(await this.performTokenRefresh()).access_token,onTokenRefresh:async n=>{this.tokenData&&(this.tokenData.access_token=n,this.tokenStore?.setTokens(this.tokenData))},onAuthRevoked:async()=>{this.clearToken();try{await this.config.onAuthRevoked?.()}catch{}},timeoutMs:this.config.timeoutMs,credentials:this.config.requestCredentials??(t?"omit":void 0)}),this.authClient=de(this.httpClient,{baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||"",timeoutMs:this.config.timeoutMs}),this.adminClient=ge(this.httpClient,{baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||"",timeoutMs:this.config.timeoutMs})}get auth(){return this.authClient}get admin(){return this.adminClient}get rpc(){return this.rpcClient||(this.rpcClient=new N({httpClient:this.httpClient})),this.rpcClient}get events(){return this.sseClient||(this.sseClient=new E({baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||""})),this.sseClient}get ephemeral(){return this.ephemeralClient||(this.ephemeralClient=new H({httpClient:this.httpClient,sse:this.events})),this.ephemeralClient}get ws(){return this.wsWarned||(this.wsWarned=!0,console.warn("[mero-js] WsClient is experimental. Use mero.events (SSE) for production.")),this.wsClient||(this.wsClient=new I({baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||""})),this.wsClient}async authenticate(e){let t=e||this.config.credentials;if(!t)throw new Error("No credentials provided for authentication");try{let n={auth_method:"user_password",public_key:t.username,client_name:"mero-js-sdk",permissions:["admin"],timestamp:Math.floor(Date.now()/1e3),provider_data:{username:t.username,password:t.password}},r=await this.authClient.generateTokens(n),i=r.data.access_token;return this.tokenData={access_token:i,refresh_token:r.data.refresh_token,expires_at:te(i,Date.now()+36e5)},this.tokenStore?.setTokens(this.tokenData),this.tokenData}catch(n){throw new Error(`Authentication failed: ${n instanceof Error?n.message:"Unknown error"}`)}}async getValidToken(){return this.tokenData}async performTokenRefresh(){if(this.refreshPromise)return this.refreshPromise;let e=this.tokenData?.access_token,t=this.withRefreshLock(()=>this.performTokenRefreshLocked(e));this.refreshPromise=t;try{return await t}finally{this.refreshPromise===t&&(this.refreshPromise=null)}}withRefreshLock(e){let t=Je();return t?t.request(We,e):e()}async performTokenRefreshLocked(e){let t=this.tokenStore?.getTokens()??null;if(t?.refresh_token&&(this.tokenData=t,e&&t.access_token!==e))return t;if(!this.tokenData?.refresh_token)throw new Error("No refresh token available");try{let n=await this.authClient.refreshToken({access_token:this.tokenData.access_token,refresh_token:this.tokenData.refresh_token}),r=n.data.access_token;return this.tokenData={access_token:r,refresh_token:n.data.refresh_token,expires_at:te(r,Date.now()+36e5)},this.tokenStore?.setTokens(this.tokenData),this.tokenData}catch(n){throw new Error(`Token refresh failed: ${n instanceof Error?n.message:"Unknown error"}`)}}clearToken(){this.refreshPromise=null,this.tokenData=null,this.tokenStore?.clear()}isAuthenticated(){return this.tokenData!==null}setTokenData(e){let t=e.expires_at||te(e.access_token,Date.now()+36e5);this.tokenData={...e,expires_at:t},this.tokenStore?.setTokens(this.tokenData)}getTokenData(){return this.tokenData}close(){this.sseClient?.close(),this.wsClient?.close()}static parseAuthCallback(e){return Y(e)}static buildAuthLoginUrl(e,t){return Z(e,t)}};function Ke(s){return new K(s)}var ne=class{constructor(){this.tokens=null}getTokens(){return this.tokens}setTokens(e){this.tokens=e}clear(){this.tokens=null}},Ve="mero-tokens",se=class{constructor(e=Ve){this.key=e}getTokens(){try{if(typeof localStorage>"u")return null;let e=localStorage.getItem(this.key);if(!e)return null;let t=JSON.parse(e);return t&&t.access_token&&t.refresh_token?{access_token:t.access_token,refresh_token:t.refresh_token,expires_at:typeof t.expires_at=="number"?t.expires_at:Date.now()+36e5}:null}catch{return null}}setTokens(e){try{if(typeof localStorage>"u")return;localStorage.setItem(this.key,JSON.stringify(e))}catch{}}clear(){try{if(typeof localStorage>"u")return;localStorage.removeItem(this.key)}catch{}}};var re=class{constructor(e={}){this.baseUrl=(e.cloudBaseUrl||"https://cloud.calimero.network").replace(/\/+$/,"")}enableHA(e){let t=new URLSearchParams({group_id:e.groupId,context_id:e.contextId});e.redirectUrl&&t.set("redirect_url",e.redirectUrl),window.open(`${this.baseUrl}/enable-ha?${t.toString()}`)}disableHA(e){let t=new URLSearchParams({group_id:e.groupId,context_id:e.contextId});e.redirectUrl&&t.set("redirect_url",e.redirectUrl),window.open(`${this.baseUrl}/disable-ha?${t.toString()}`)}};var ye=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,112,4,34,4,32]);function b(s){let e=new Uint8Array(4);return new DataView(e.buffer).setUint32(0,s,!0),e}function A(s){return Array.from(s,e=>e.toString(16).padStart(2,"0")).join("")}function u(s,e,t){let n=s.trim();if(!/^[0-9a-fA-F]*$/.test(n)||n.length!==t*2)throw new Error(`${e} must be ${t*2} hex characters, got ${n.length}`);let r=new Uint8Array(t);for(let i=0;i<t;i+=1)r[i]=Number.parseInt(n.slice(i*2,i*2+2),16);return r}function R(s){let e=new Uint8Array(8);return new DataView(e.buffer).setBigUint64(0,BigInt(s),!0),e}function m(...s){let e=new Uint8Array(s.reduce((n,r)=>n+r.length,0)),t=0;for(let n of s)e.set(n,t),t+=n.length;return e}async function v(s,e){let t=[R(s.length),s];for(let n of e)t.push(R(n.length),n);return new Uint8Array(await crypto.subtle.digest("SHA-256",m(...t)))}async function M(s){let e=u(s,"deviceSecret",32),t=m(ye,e);try{return await crypto.subtle.importKey("pkcs8",t,{name:"Ed25519"},!1,["sign"])}catch(n){let r=n instanceof Error?`: ${n.message}`:"";throw new Error("this runtime has no WebCrypto Ed25519, so a warrant cannot be signed here. Node 18.4+, Safari 17+, Firefox 129+ and Chrome 137+ have it; otherwise mint the warrant with `merod account warrant`"+r)}}async function T(s){let e=u(s,"deviceSecret",32),t=m(ye,e),n=await crypto.subtle.importKey("pkcs8",t,{name:"Ed25519"},!0,["sign"]),i=(await crypto.subtle.exportKey("jwk",n)).x;return Uint8Array.from(atob(i.replace(/-/g,"+").replace(/_/g,"/")),a=>a.charCodeAt(0))}var Be=new TextEncoder().encode("calimero.warrant.v1"),Fe=new TextEncoder().encode("calimero.warrant.intent.v1");async function ie(s,e){let t=new TextEncoder().encode(JSON.stringify(e));return v(Fe,[new TextEncoder().encode(s),t])}async function be(s){let e=u(s.context,"context",32),t=u(s.authorAccount,"authorAccount",32),n=u(s.executor,"executor",32),r=await M(s.deviceSecret),i=await T(s.deviceSecret),a=await ie(s.method,s.argsJson),c=R(s.nonce),f=R(s.notAfter),l=await v(Be,[e,t,i,n,a,c,f]),h=new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},r,l));return A(m(e,t,i,n,a,c,f,h))}var ze=new TextEncoder().encode("calimero.device.cert.v1"),Ce=new TextEncoder().encode("calimero.account.genesis.v1"),Qe=new TextEncoder().encode("calimero.device.id.v1"),oe=2;async function Re(s,e){if(e.length!==16)throw new Error(`nonce must be 16 bytes, got ${e.length}`);let t=u(s,"account",32);return A(await v(Qe,[t,e]))}async function ae(s){return v(ze,[u(s.account,"account",32),u(s.device,"device",32),u(s.signPublicKey,"signPublicKey",32),u(s.kemPublicKey,"kemPublicKey",32),b(s.keyEpoch),b(s.deviceEpoch)])}function Ae(s){return m(new Uint8Array([oe]),s.rootPublicKey,b(0),u(s.account,"account",32),u(s.device,"device",32),u(s.signPublicKey,"signPublicKey",32),u(s.kemPublicKey,"kemPublicKey",32),b(s.keyEpoch),b(s.deviceEpoch),s.signature)}async function we(s){let e=await T(s.rootSecret),t=A(await v(Ce,[m(new Uint8Array([oe]),e)])),n=0,r=await ae({account:t,device:s.device,signPublicKey:s.signPublicKey,kemPublicKey:s.kemPublicKey,keyEpoch:n,deviceEpoch:s.deviceEpoch}),i=await M(s.rootSecret),a=new Uint8Array(await crypto.subtle.sign("Ed25519",i,r)),c=Ae({rootPublicKey:e,account:t,device:s.device,signPublicKey:s.signPublicKey,kemPublicKey:s.kemPublicKey,keyEpoch:n,deviceEpoch:s.deviceEpoch,signature:a});return A(c)}async function ve(s){let e=await T(s);return A(await v(Ce,[m(new Uint8Array([oe]),e)]))}var pe=8,Xe=new TextEncoder().encode("calimero.namespace.v1"),Ye=0,ke={GroupCreated:0,GroupReparented:1,GroupDeleted:2,AdminChanged:3,PolicyUpdated:4,MemberJoined:5,KeyDelivery:6,MemberJoinedOpen:7,MemberJoinedAt:8,NamespaceCreated:9,MemberJoinedViaTeeAttestation:10};function ce(s,e){if(s.length!==32)throw new Error(`${e} must be 32 bytes, got ${s.length}`);return new Uint8Array(s)}function xe(s,e){if(s==null)return new Uint8Array([0]);if(s.length!==32)throw new Error(`${e} must be 32 bytes, got ${s.length}`);return m(new Uint8Array([1]),new Uint8Array(s))}function Te(s){let e=new TextEncoder().encode(s);return m(b(e.length),e)}function V(s){let e=s.invitation,t=e.admitters??[],n=s.admitter_addrs??[];return m(ce(e.inviter_identity,"inviter_identity"),ce(e.group_id,"group_id"),R(e.expiration_timestamp),ce(e.secret_salt,"secret_salt"),new Uint8Array([e.invited_role]),b(t.length),...t.map((r,i)=>u(r,`admitters[${i}]`,32)),Te(s.inviter_signature),s.inviter_account?m(new Uint8Array([1]),u(s.inviter_account,"inviter_account",32)):new Uint8Array([0]),b(n.length),...n.map(Te),xe(s.application_id,"application_id"),xe(s.app_key,"app_key"))}async function De(s){let e=s.parentOpHashes??[],t=u(s.credential,"credential",s.credential.length/2),n=BigInt(s.invitation.invitation.expiration_timestamp??0)!==0n,r=s.joinedAt??BigInt(Math.floor(Date.now()/1e3)),i=n?m(new Uint8Array([ke.MemberJoinedAt]),u(s.member,"member",32),V(s.invitation),R(r),t):m(new Uint8Array([ke.MemberJoined]),u(s.member,"member",32),V(s.invitation),t),a=m(new Uint8Array([Ye]),i),c=await M(s.deviceSecret),f=await T(s.deviceSecret),l=m(new Uint8Array([pe]),u(s.namespaceId,"namespaceId",32),b(e.length),...e.map((g,y)=>u(g,`parentOpHashes[${y}]`,32)),f,R(s.nonce),a),h=new Uint8Array(await crypto.subtle.sign("Ed25519",c,m(Xe,l))),d=new Uint8Array([0]);return A(m(l,h,d))}var Cn={CAN_CREATE_CONTEXT:1,CAN_INVITE_MEMBERS:2,CAN_JOIN_OPEN_SUBGROUPS:4,MANAGE_MEMBERS:8,MANAGE_APPLICATION:16,CAN_CREATE_SUBGROUP:32,CAN_DELETE_SUBGROUP:64,CAN_MANAGE_VISIBILITY:128,CAN_MANAGE_METADATA:256};function Rn(s,e){let t=e>>>0;return(s&t)>>>0===t}function An(s,e){return(s|e)>>>0}function wn(s,e){return(s&~e)>>>0}var Pe=[2428,2429,2528,2529],Ze="localhost",et=2e3;function Se(s){return`http://${Ze}:${s}`}function Ee(s,e){let t=s.endsWith("/")?s:`${s}/`;return new URL(e,t).toString()}async function Ie(s,e={}){let{timeoutMs:t=et,signal:n}=e;if(n?.aborted)return!1;let r=new AbortController,i=()=>r.abort(),a=n;a&&a.addEventListener("abort",i,{once:!0});let c=setTimeout(()=>r.abort(),t);try{let f=Ee(s,"admin-api/health"),l=await fetch(f,{method:"GET",signal:r.signal});if(!l.ok)return!1;try{let h=await l.json(),d=h?.data?.status!==void 0?h?.data?.status:h?.status;return d===void 0?!0:typeof d=="string"&&d.toLowerCase()==="alive"}catch{return!0}}catch{return!1}finally{clearTimeout(c),a&&a.removeEventListener("abort",i)}}async function tt(s={}){let{ports:e=Pe,timeoutMs:t,signal:n}=s;return(await Promise.all(e.map(async i=>{let a=Se(i);return await Ie(a,{timeoutMs:t,signal:n})?a:null}))).filter(i=>i!==null)}export{x as AdminApiClient,k as AuthApiClient,P as AuthRevokedError,Cn as CAPABILITIES,re as CloudClient,Pe as DEFAULT_LOCAL_NODE_PORTS,H as EphemeralClient,C as HTTPError,se as LocalStorageTokenStore,ne as MemoryTokenStore,K as MeroJs,N as RpcClient,j as RpcError,pe as SIGNED_NAMESPACE_OP_SCHEMA_VERSION,E as SseClient,U as WebHttpClient,I as WsClient,ve as accountForRoot,Z as buildAuthLoginUrl,F as combineSignals,qe as compareSemver,Et as createAdminApiClient,ge as createAdminApiClientFromHttpClient,Rt as createAuthApiClient,de as createAuthApiClientFromHttpClient,Pt as createBrowserAdminApiClient,bt as createBrowserAuthApiClient,S as createBrowserHttpClient,Q as createHttpClient,Ke as createMeroJs,St as createNodeAdminApiClient,Ct as createNodeAuthApiClient,L as createNodeHttpClient,$e as createRetryableMethod,z as createTimeoutSignal,X as createUniversalHttpClient,ae as deviceCertPayload,tt as discoverLocalNodes,V as encodeSignedInvitation,Rn as hasCap,ie as intentHash,J as jsonCodec,Se as localNodeUrl,Re as mintDeviceId,Ee as nodeEndpoint,Y as parseAuthCallback,Ie as probeNodeHealth,we as signDeviceCert,De as signMemberJoinOp,be as signWarrant,An as withCap,O as withRetry,wn as withoutCap};
|
|
3
3
|
//# sourceMappingURL=index.browser.mjs.map
|