@aithos/sdk 0.1.0-alpha.3 → 0.1.0-alpha.30

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.
Files changed (66) hide show
  1. package/README.md +159 -0
  2. package/dist/src/auth-api.d.ts +105 -0
  3. package/dist/src/auth-api.js +178 -0
  4. package/dist/src/auth.d.ts +359 -68
  5. package/dist/src/auth.js +1035 -69
  6. package/dist/src/compute.d.ts +221 -9
  7. package/dist/src/compute.js +293 -16
  8. package/dist/src/data-schema-contacts-v1.d.ts +14 -0
  9. package/dist/src/data-schema-contacts-v1.js +28 -0
  10. package/dist/src/data.d.ts +97 -0
  11. package/dist/src/data.js +634 -0
  12. package/dist/src/endpoints.d.ts +9 -0
  13. package/dist/src/endpoints.js +5 -0
  14. package/dist/src/ethos.d.ts +202 -1
  15. package/dist/src/ethos.js +821 -16
  16. package/dist/src/index.d.ts +15 -6
  17. package/dist/src/index.js +36 -9
  18. package/dist/src/internal/delegate-bundle.d.ts +18 -0
  19. package/dist/src/internal/delegate-bundle.js +94 -0
  20. package/dist/src/internal/delegate-state.d.ts +45 -0
  21. package/dist/src/internal/delegate-state.js +120 -0
  22. package/dist/src/internal/owner-signers.d.ts +78 -0
  23. package/dist/src/internal/owner-signers.js +179 -0
  24. package/dist/src/internal/protocol-client-bridge.d.ts +8 -0
  25. package/dist/src/internal/protocol-client-bridge.js +20 -0
  26. package/dist/src/internal/recovery-file.d.ts +29 -0
  27. package/dist/src/internal/recovery-file.js +98 -0
  28. package/dist/src/internal/signer.d.ts +59 -0
  29. package/dist/src/internal/signer.js +86 -0
  30. package/dist/src/key-store.d.ts +128 -0
  31. package/dist/src/key-store.js +244 -0
  32. package/dist/src/mandates.d.ts +163 -1
  33. package/dist/src/mandates.js +286 -8
  34. package/dist/src/sdk.d.ts +39 -3
  35. package/dist/src/sdk.js +36 -23
  36. package/dist/src/session-store.d.ts +58 -0
  37. package/dist/src/session-store.js +158 -0
  38. package/dist/src/wallet.d.ts +4 -6
  39. package/dist/src/wallet.js +18 -8
  40. package/dist/src/web.d.ts +279 -0
  41. package/dist/src/web.js +186 -0
  42. package/dist/test/auth-j3.test.d.ts +2 -0
  43. package/dist/test/auth-j3.test.js +391 -0
  44. package/dist/test/compute-delegate-path.test.d.ts +2 -0
  45. package/dist/test/compute-delegate-path.test.js +183 -0
  46. package/dist/test/compute.test.js +26 -11
  47. package/dist/test/endpoints.test.js +20 -1
  48. package/dist/test/ethos-first-edition.test.d.ts +2 -0
  49. package/dist/test/ethos-first-edition.test.js +248 -0
  50. package/dist/test/ethos.test.d.ts +2 -0
  51. package/dist/test/ethos.test.js +219 -0
  52. package/dist/test/key-store.test.d.ts +2 -0
  53. package/dist/test/key-store.test.js +161 -0
  54. package/dist/test/mandates-compute.test.d.ts +2 -0
  55. package/dist/test/mandates-compute.test.js +256 -0
  56. package/dist/test/mandates.test.d.ts +2 -0
  57. package/dist/test/mandates.test.js +93 -0
  58. package/dist/test/sdk.test.js +70 -30
  59. package/dist/test/signer.test.d.ts +2 -0
  60. package/dist/test/signer.test.js +117 -0
  61. package/dist/test/signup-bootstrap.test.d.ts +2 -0
  62. package/dist/test/signup-bootstrap.test.js +222 -0
  63. package/dist/test/wallet.test.js +20 -9
  64. package/dist/test/web.test.d.ts +2 -0
  65. package/dist/test/web.test.js +270 -0
  66. package/package.json +5 -4
package/README.md CHANGED
@@ -55,11 +55,170 @@ const reply = await sdk.compute.invokeBedrock({
55
55
  console.log(reply.content);
56
56
  ```
57
57
 
58
+ ## Delegating compute to an agent — opt-in token spending
59
+
60
+ To let an agent (or another user, or a third-party app) invoke Bedrock
61
+ **in your name**, with **your credits**, you mint a mandate. Token
62
+ spending is its own opt-in capability — passing it is a separate,
63
+ named, validated input that a consent UI can review. It is NEVER an
64
+ implicit side-effect of an ethos read/write scope.
65
+
66
+ ```ts
67
+ // Mint a mandate that lets agent Bob read your public ethos AND
68
+ // spend up to 5 000 microcredits/day on Haiku, capped at 100 000
69
+ // microcredits over the whole mandate lifetime.
70
+ const mandate = await sdk.mandates.create({
71
+ granteeId: "urn:agent:bob",
72
+ scopes: ["ethos.read.public"],
73
+ ttlSeconds: 86_400,
74
+ compute: {
75
+ dailyCapMicrocredits: 5_000,
76
+ totalCapMicrocredits: 100_000,
77
+ maxCreditsPerCall: 500,
78
+ allowedModels: ["claude-haiku-4-5"],
79
+ },
80
+ });
81
+
82
+ // Hand `mandate.bundle` (a `.aithos-delegate.json` Blob) to Bob.
83
+ // He imports it, then signs his own envelopes and calls
84
+ // sdk.compute.invokeBedrock({ mandateId: mandate.mandateId, … })
85
+ // — every invocation debits *your* wallet, capped per the budget
86
+ // you set.
87
+ ```
88
+
89
+ Three invariants the SDK enforces synchronously, before reaching the
90
+ network — they fail fast with a precise `AithosSDKError`:
91
+
92
+ - **No smuggling.** Adding `"compute.invoke"` directly to `scopes[]`
93
+ throws `mandates_invalid_scopes`. The `compute` namespace is the
94
+ only path, so a UI reviewing `compute` can never be bypassed.
95
+ - **No bearer compute.** A `compute` namespace without at least one
96
+ of `dailyCapMicrocredits` or `totalCapMicrocredits` throws
97
+ `mandates_invalid_compute`. Unbounded compute mandates are forbidden
98
+ by construction.
99
+ - **Compute-only is fine.** `scopes: []` is allowed when `compute` is
100
+ set — useful for agents that only consume tokens (e.g. creative
101
+ assistants) without seeing any of your data.
102
+
103
+ ## Custodial auth — onboarding users without a recovery file
104
+
105
+ Three new methods on `AithosAuth` let an app create and authenticate
106
+ its end-users via a server-managed custody flow — the user only needs
107
+ an email address and a password sent by mail. No recovery file, no
108
+ Google account, no client-side cryptography to handle.
109
+
110
+ The model is honest custody: Aithos KMS-wraps the user's Ed25519
111
+ identity seeds, and unwraps them on every sign-in after password
112
+ verification. Equivalent to how Coinbase or any hosted SaaS keeps your
113
+ private key. Annunciated to the user in the welcome email.
114
+
115
+ ```ts
116
+ import { AithosSDK } from "@aithos/sdk";
117
+
118
+ // ─── Server-side: sign-up ───────────────────────────────────────────
119
+ // MUST run on your backend. The API key is a server secret —
120
+ // provisioned by Aithos via the operator runbook.
121
+ const sdk = new AithosSDK({ identity });
122
+ const result = await sdk.auth.signUpCustodial({
123
+ apiKey: process.env.AITHOS_API_KEY!,
124
+ email: "alice@example.com",
125
+ displayName: "Alice",
126
+ });
127
+ // → { userId, did, handle, email, mailSent }
128
+ // The user receives an email with their password and a sign-in link.
129
+
130
+ // ─── Browser-side: sign-in ──────────────────────────────────────────
131
+ // User pastes the password from their mail into your sign-in form,
132
+ // then your frontend calls this. No API key needed — the password
133
+ // is the credential.
134
+ const { session, passwordMustChange } = await sdk.auth.signInCustodial({
135
+ email: "alice@example.com",
136
+ password: "MyTempPass32chars",
137
+ });
138
+ // Local KeyStore is now hydrated with the 4 Ed25519 sphere seeds —
139
+ // the user can publish ethos editions, mint mandates, invoke compute,
140
+ // exactly as if they had signed in via a recovery file or Google SSO.
141
+ if (passwordMustChange) {
142
+ // Optional: nudge the user to set their own password via the
143
+ // standard reset flow.
144
+ }
145
+
146
+ // ─── Browser-side: request password reset ───────────────────────────
147
+ // The backend always returns silently (anti-enumeration). If the email
148
+ // is registered AND in custodial mode AND not in cooldown AND under the
149
+ // daily cap, a magic-link email is sent to the address.
150
+ await sdk.auth.requestPasswordReset({ email: "alice@example.com" });
151
+ ```
152
+
153
+ The reset finalization (collecting the new password from the user) is
154
+ done on a small web page hosted by Aithos at `https://app.aithos.be/reset`
155
+ (or your app's own `reset_base_url` if you've registered one — see the
156
+ operator runbook). The page POSTs to `/auth/custodial/reset/finalize`
157
+ and returns the user to your sign-in page on success.
158
+
159
+ ### Getting an API key
160
+
161
+ API keys are provisioned out-of-band by Aithos. Contact the maintainer
162
+ (or use the self-service console at `aithos.be/console` when it ships
163
+ in V2). The pattern is `aithos_<env>_<32 chars b58>`. Keep it in your
164
+ backend's secrets manager — never in browser code.
165
+
166
+ ### Trade-offs vs. the zk and Google SSO flows
167
+
168
+ | | zk (recovery file) | Google SSO (KMS) | **Custodial** |
169
+ |----------------|----------------------------|----------------------|---------------|
170
+ | User burden | downloads `recovery.json` | Google consent | email only |
171
+ | Password reset | requires recovery file | re-auth via Google | magic-link mail |
172
+ | Trust model | zero-knowledge (you only) | Aithos + Google | Aithos only |
173
+ | Multi-device | re-import recovery | re-Google | email + password |
174
+ | SDK signing capability | full | full | full |
175
+
176
+ Custodial is the right default for SDK-integrated apps that want
177
+ SaaS-grade UX. zk is the right default for power users who want
178
+ sovereign custody. SSO is the right default for users already invested
179
+ in the Google ecosystem.
180
+
181
+ ## Extracting webpages without an LLM
182
+
183
+ `sdk.web` is a token-priced primitive that lets your agent read a
184
+ public webpage and get back cleaned HTML, purged CSS and a
185
+ deterministic visual signature — all computed server-side without an
186
+ LLM in the loop. Pricing is a flat **1 microcredit** per successful
187
+ extraction (refunded on failure), versus ~30 mc for a comparable
188
+ LLM-based extraction.
189
+
190
+ ```ts
191
+ import { AithosSDK } from "@aithos/sdk";
192
+
193
+ const sdk = new AithosSDK({ auth, appDid });
194
+
195
+ const { data, creditsCharged } = await sdk.web.extract({
196
+ url: "https://example.com",
197
+ });
198
+
199
+ console.log(data.meta.title); // "Example Domain"
200
+ console.log(data.visual_signature.colors.primary); // "#0078d4"
201
+ console.log(data.styles.css.length); // purged + minified CSS
202
+ ```
203
+
204
+ Owners can mint a mandate for delegate-only extraction:
205
+
206
+ ```ts
207
+ import { WEB_EXTRACT_SCOPE } from "@aithos/sdk";
208
+
209
+ await sdk.mandates.create({
210
+ appDid: "did:aithos:app:my-agent",
211
+ scopes: [WEB_EXTRACT_SCOPE],
212
+ // ...
213
+ });
214
+ ```
215
+
58
216
  ## What lives where
59
217
 
60
218
  | Namespace | Purpose |
61
219
  | ---------------- | ------------------------------------------------------------------------------------------ |
62
220
  | `sdk.compute` | Bedrock invocation through the Aithos compute proxy (signed envelope, wallet enforcement). |
221
+ | `sdk.web` | Webpage extraction without an LLM through the web extractor proxy (1 mc / call). |
63
222
  | `sdk.wallet` | Stripe Checkout sessions for credit-pack top-ups, balance helpers. |
64
223
  | `sdk.ethos` | Ethos-zone composition / parsing — re-exported from `@aithos/protocol-client`. |
65
224
  | `sdk.onboarding` | First-run identity / DID flows — re-exported. |
@@ -0,0 +1,105 @@
1
+ import { type KdfParams } from "@aithos/protocol-client";
2
+ interface HttpClient {
3
+ readonly fetchImpl: typeof fetch;
4
+ readonly authBaseUrl: string;
5
+ }
6
+ export interface RegisterApiInput {
7
+ readonly email: string;
8
+ readonly handle: string;
9
+ readonly displayName: string;
10
+ readonly did: string;
11
+ readonly authKey: Uint8Array;
12
+ readonly authSalt: Uint8Array;
13
+ readonly encSalt: Uint8Array;
14
+ readonly kdf: KdfParams;
15
+ readonly blob: Uint8Array;
16
+ readonly blobNonce: Uint8Array;
17
+ readonly blobVersion: number;
18
+ }
19
+ export interface RegisterApiResponse {
20
+ readonly session: string;
21
+ readonly exp: number;
22
+ }
23
+ export declare function registerAccount(http: HttpClient, input: RegisterApiInput): Promise<RegisterApiResponse>;
24
+ export interface PutBlobApiInput {
25
+ readonly jwt: string;
26
+ readonly blob: Uint8Array;
27
+ readonly blobNonce: Uint8Array;
28
+ readonly blobVersion: number;
29
+ }
30
+ export declare function putBlob(http: HttpClient, input: PutBlobApiInput): Promise<{
31
+ ok: true;
32
+ }>;
33
+ export interface LoginChallengeResponse {
34
+ readonly authSalt: Uint8Array;
35
+ readonly encSalt: Uint8Array;
36
+ readonly kdf: KdfParams;
37
+ }
38
+ export declare function loginChallenge(http: HttpClient, email: string): Promise<LoginChallengeResponse>;
39
+ export interface LoginVerifyResponse {
40
+ readonly session: string;
41
+ readonly exp: number;
42
+ readonly did: string;
43
+ readonly handle: string;
44
+ readonly blob: Uint8Array;
45
+ readonly blobNonce: Uint8Array;
46
+ readonly blobVersion: number;
47
+ }
48
+ export declare function loginVerify(http: HttpClient, email: string, authKey: Uint8Array): Promise<LoginVerifyResponse>;
49
+ export interface CustodialSignUpApiInput {
50
+ readonly apiKey: string;
51
+ readonly email: string;
52
+ readonly displayName?: string;
53
+ readonly handleHint?: string;
54
+ }
55
+ export interface CustodialSignUpApiResponse {
56
+ readonly userId: string;
57
+ readonly did: string;
58
+ readonly handle: string;
59
+ readonly email: string;
60
+ readonly mailSent: boolean;
61
+ readonly mailMessageId?: string;
62
+ }
63
+ /**
64
+ * Provision a custodial-mode account on behalf of a registered app.
65
+ * Server-only — the API key MUST be kept off the browser (it grants the
66
+ * ability to create accounts under your app's name). Typical use site is
67
+ * the app's backend in response to a sign-up form submission.
68
+ */
69
+ export declare function custodialSignUp(http: HttpClient, input: CustodialSignUpApiInput): Promise<CustodialSignUpApiResponse>;
70
+ export interface CustodialSignInApiInput {
71
+ readonly email: string;
72
+ readonly password: string;
73
+ }
74
+ export interface CustodialSignInApiResponse {
75
+ readonly session: string;
76
+ readonly exp: number;
77
+ readonly did: string;
78
+ readonly handle: string;
79
+ readonly displayName: string;
80
+ /** Raw 32-byte Ed25519 seed — caller MUST hydrate its keystore and
81
+ * zeroize this buffer. */
82
+ readonly seed: Uint8Array;
83
+ /** Raw 32-byte vault encryption key — same lifecycle. */
84
+ readonly encKey: Uint8Array;
85
+ readonly blob: Uint8Array;
86
+ readonly blobNonce: Uint8Array;
87
+ readonly blobVersion: number;
88
+ readonly passwordMustChange: boolean;
89
+ }
90
+ export declare function custodialSignIn(http: HttpClient, input: CustodialSignInApiInput): Promise<CustodialSignInApiResponse>;
91
+ export declare function custodialResetRequest(http: HttpClient, email: string): Promise<void>;
92
+ export interface CustodialResetFinalizeApiInput {
93
+ readonly email: string;
94
+ readonly token: string;
95
+ readonly newPassword: string;
96
+ }
97
+ export interface CustodialResetFinalizeApiResponse {
98
+ readonly session: string;
99
+ readonly exp: number;
100
+ readonly did: string;
101
+ readonly handle: string;
102
+ }
103
+ export declare function custodialResetFinalize(http: HttpClient, input: CustodialResetFinalizeApiInput): Promise<CustodialResetFinalizeApiResponse>;
104
+ export {};
105
+ //# sourceMappingURL=auth-api.d.ts.map
@@ -0,0 +1,178 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright 2026 Mathieu Colla
3
+ // Thin HTTP client over the Aithos auth Lambda.
4
+ //
5
+ // Internal — not exported from the package's public surface. The
6
+ // {@link AithosAuth} class composes these calls with the crypto
7
+ // primitives in `@aithos/protocol-client` and the session store in
8
+ // {@link ./session-store.ts} to expose a high-level
9
+ // signIn / signUp / signInWithGoogle API.
10
+ //
11
+ // Wire format mirrors `aithos/auth/API.md` exactly. All `*_b64` fields
12
+ // are standard-base64 (not URL-safe), padding stripped — see
13
+ // `bytesToB64` / `b64ToBytes` in `@aithos/protocol-client`.
14
+ import { bytesToB64, b64ToBytes, } from "@aithos/protocol-client";
15
+ import { AithosSDKError } from "./types.js";
16
+ async function readError(res, defaultCode) {
17
+ let body = null;
18
+ try {
19
+ body = (await res.json());
20
+ }
21
+ catch {
22
+ /* body not JSON */
23
+ }
24
+ const code = typeof body?.code === "string" ? `auth_${body.code}` : `auth_${defaultCode}`;
25
+ const message = body?.error ?? `${res.status} ${res.statusText || "request failed"}`;
26
+ return new AithosSDKError(code, message, {
27
+ status: res.status,
28
+ ...(body !== null ? { data: body } : {}),
29
+ });
30
+ }
31
+ async function postJson(http, path, body, jwt) {
32
+ const res = await http.fetchImpl(`${http.authBaseUrl}${path}`, {
33
+ method: "POST",
34
+ headers: {
35
+ "content-type": "application/json",
36
+ ...(jwt ? { authorization: `Bearer ${jwt}` } : {}),
37
+ },
38
+ body: JSON.stringify(body),
39
+ });
40
+ if (!res.ok)
41
+ throw await readError(res, "request_failed");
42
+ return (await res.json());
43
+ }
44
+ async function putJson(http, path, body, jwt) {
45
+ const res = await http.fetchImpl(`${http.authBaseUrl}${path}`, {
46
+ method: "PUT",
47
+ headers: {
48
+ "content-type": "application/json",
49
+ authorization: `Bearer ${jwt}`,
50
+ },
51
+ body: JSON.stringify(body),
52
+ });
53
+ if (!res.ok)
54
+ throw await readError(res, "request_failed");
55
+ return (await res.json());
56
+ }
57
+ export async function registerAccount(http, input) {
58
+ return postJson(http, "/auth/register", {
59
+ email: input.email,
60
+ handle: input.handle,
61
+ display_name: input.displayName,
62
+ did: input.did,
63
+ auth_key_b64: bytesToB64(input.authKey),
64
+ auth_salt_b64: bytesToB64(input.authSalt),
65
+ enc_salt_b64: bytesToB64(input.encSalt),
66
+ kdf: input.kdf,
67
+ blob_b64: bytesToB64(input.blob),
68
+ blob_nonce_b64: bytesToB64(input.blobNonce),
69
+ blob_version: input.blobVersion,
70
+ });
71
+ }
72
+ export async function putBlob(http, input) {
73
+ return putJson(http, "/auth/blob", {
74
+ blob_b64: bytesToB64(input.blob),
75
+ blob_nonce_b64: bytesToB64(input.blobNonce),
76
+ blob_version: input.blobVersion,
77
+ }, input.jwt);
78
+ }
79
+ export async function loginChallenge(http, email) {
80
+ const wire = await postJson(http, "/auth/login/challenge", { email });
81
+ return {
82
+ authSalt: b64ToBytes(wire.auth_salt_b64),
83
+ encSalt: b64ToBytes(wire.enc_salt_b64),
84
+ kdf: wire.kdf,
85
+ };
86
+ }
87
+ export async function loginVerify(http, email, authKey) {
88
+ const wire = await postJson(http, "/auth/login/verify", {
89
+ email,
90
+ auth_key_b64: bytesToB64(authKey),
91
+ });
92
+ return {
93
+ session: wire.session,
94
+ exp: wire.exp,
95
+ did: wire.did,
96
+ handle: wire.handle,
97
+ blob: b64ToBytes(wire.blob_b64),
98
+ blobNonce: b64ToBytes(wire.blob_nonce_b64),
99
+ blobVersion: wire.blob_version,
100
+ };
101
+ }
102
+ /**
103
+ * Provision a custodial-mode account on behalf of a registered app.
104
+ * Server-only — the API key MUST be kept off the browser (it grants the
105
+ * ability to create accounts under your app's name). Typical use site is
106
+ * the app's backend in response to a sign-up form submission.
107
+ */
108
+ export async function custodialSignUp(http, input) {
109
+ const res = await http.fetchImpl(`${http.authBaseUrl}/auth/custodial/sign-up`, {
110
+ method: "POST",
111
+ headers: {
112
+ "content-type": "application/json",
113
+ authorization: `Bearer ${input.apiKey}`,
114
+ },
115
+ body: JSON.stringify({
116
+ email: input.email,
117
+ ...(input.displayName ? { display_name: input.displayName } : {}),
118
+ ...(input.handleHint ? { handle_hint: input.handleHint } : {}),
119
+ }),
120
+ });
121
+ if (!res.ok)
122
+ throw await readError(res, "custodial_signup_failed");
123
+ const wire = (await res.json());
124
+ return {
125
+ userId: wire.user_id,
126
+ did: wire.did,
127
+ handle: wire.handle,
128
+ email: wire.email,
129
+ mailSent: wire.mail_sent,
130
+ ...(wire.mail_message_id !== undefined
131
+ ? { mailMessageId: wire.mail_message_id }
132
+ : {}),
133
+ };
134
+ }
135
+ export async function custodialSignIn(http, input) {
136
+ const wire = await postJson(http, "/auth/custodial/sign-in", { email: input.email, password: input.password });
137
+ return {
138
+ session: wire.session,
139
+ exp: wire.exp,
140
+ did: wire.did,
141
+ handle: wire.handle,
142
+ displayName: wire.display_name,
143
+ seed: b64ToBytes(wire.seed_b64),
144
+ encKey: b64ToBytes(wire.enc_key_b64),
145
+ blob: wire.blob_b64 ? b64ToBytes(wire.blob_b64) : new Uint8Array(0),
146
+ blobNonce: wire.blob_nonce_b64
147
+ ? b64ToBytes(wire.blob_nonce_b64)
148
+ : new Uint8Array(0),
149
+ blobVersion: wire.blob_version,
150
+ passwordMustChange: wire.password_must_change,
151
+ };
152
+ }
153
+ /* ---- POST /auth/custodial/reset/request --------------------------------- */
154
+ export async function custodialResetRequest(http, email) {
155
+ // Backend always returns 200 { ok: true } regardless. We accept any
156
+ // 2xx body, even non-JSON, to be defensive.
157
+ const res = await http.fetchImpl(`${http.authBaseUrl}/auth/custodial/reset/request`, {
158
+ method: "POST",
159
+ headers: { "content-type": "application/json" },
160
+ body: JSON.stringify({ email }),
161
+ });
162
+ if (!res.ok)
163
+ throw await readError(res, "custodial_reset_request_failed");
164
+ }
165
+ export async function custodialResetFinalize(http, input) {
166
+ const wire = await postJson(http, "/auth/custodial/reset/finalize", {
167
+ email: input.email,
168
+ token: input.token,
169
+ new_password: input.newPassword,
170
+ });
171
+ return {
172
+ session: wire.session,
173
+ exp: wire.exp,
174
+ did: wire.did,
175
+ handle: wire.handle,
176
+ };
177
+ }
178
+ //# sourceMappingURL=auth-api.js.map