@aithos/sdk 0.1.0-alpha.5 → 0.1.0-alpha.51

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 (67) hide show
  1. package/README.md +245 -7
  2. package/dist/src/apps.d.ts +224 -0
  3. package/dist/src/apps.js +432 -0
  4. package/dist/src/assets.d.ts +209 -0
  5. package/dist/src/assets.js +534 -0
  6. package/dist/src/auth-api.d.ts +219 -0
  7. package/dist/src/auth-api.js +248 -0
  8. package/dist/src/auth.d.ts +543 -0
  9. package/dist/src/auth.js +937 -31
  10. package/dist/src/compute.d.ts +464 -6
  11. package/dist/src/compute.js +746 -20
  12. package/dist/src/data-schema-contacts-v1.d.ts +14 -0
  13. package/dist/src/data-schema-contacts-v1.js +28 -0
  14. package/dist/src/data.d.ts +342 -0
  15. package/dist/src/data.js +1002 -0
  16. package/dist/src/endpoints.d.ts +25 -0
  17. package/dist/src/endpoints.js +7 -0
  18. package/dist/src/ethos.d.ts +85 -0
  19. package/dist/src/ethos.js +463 -7
  20. package/dist/src/index.d.ts +17 -6
  21. package/dist/src/index.js +25 -3
  22. package/dist/src/internal/delegate-bundle.js +7 -2
  23. package/dist/src/internal/envelope.d.ts +93 -0
  24. package/dist/src/internal/envelope.js +59 -0
  25. package/dist/src/mandates.d.ts +111 -2
  26. package/dist/src/mandates.js +150 -7
  27. package/dist/src/react/AithosAsset.d.ts +66 -0
  28. package/dist/src/react/AithosAsset.js +67 -0
  29. package/dist/src/react/context.d.ts +29 -0
  30. package/dist/src/react/context.js +31 -0
  31. package/dist/src/react/index.d.ts +29 -0
  32. package/dist/src/react/index.js +31 -0
  33. package/dist/src/react/use-aithos-asset.d.ts +39 -0
  34. package/dist/src/react/use-aithos-asset.js +118 -0
  35. package/dist/src/react/use-transcribe-pending.d.ts +21 -0
  36. package/dist/src/react/use-transcribe-pending.js +47 -0
  37. package/dist/src/sdk.d.ts +10 -0
  38. package/dist/src/sdk.js +22 -0
  39. package/dist/src/transcribe-resilience.d.ts +57 -0
  40. package/dist/src/transcribe-resilience.js +203 -0
  41. package/dist/src/web.d.ts +279 -0
  42. package/dist/src/web.js +186 -0
  43. package/dist/test/auth-j3.test.js +32 -1
  44. package/dist/test/canonical-conformance.test.d.ts +2 -0
  45. package/dist/test/canonical-conformance.test.js +86 -0
  46. package/dist/test/compute-delegate-path.test.d.ts +2 -0
  47. package/dist/test/compute-delegate-path.test.js +183 -0
  48. package/dist/test/compute.test.js +4 -0
  49. package/dist/test/endpoints.test.js +30 -1
  50. package/dist/test/envelope-core-conformance.test.d.ts +2 -0
  51. package/dist/test/envelope-core-conformance.test.js +75 -0
  52. package/dist/test/envelope.test.d.ts +2 -0
  53. package/dist/test/envelope.test.js +318 -0
  54. package/dist/test/ethos-first-edition.test.d.ts +2 -0
  55. package/dist/test/ethos-first-edition.test.js +371 -0
  56. package/dist/test/mandates-compute.test.d.ts +2 -0
  57. package/dist/test/mandates-compute.test.js +256 -0
  58. package/dist/test/sdk.test.js +11 -2
  59. package/dist/test/signup-bootstrap.test.d.ts +2 -0
  60. package/dist/test/signup-bootstrap.test.js +311 -0
  61. package/dist/test/transcribe-invoke.test.d.ts +2 -0
  62. package/dist/test/transcribe-invoke.test.js +204 -0
  63. package/dist/test/transcribe.test.d.ts +2 -0
  64. package/dist/test/transcribe.test.js +186 -0
  65. package/dist/test/web.test.d.ts +2 -0
  66. package/dist/test/web.test.js +270 -0
  67. package/package.json +20 -3
@@ -21,6 +21,15 @@ export interface RegisterApiResponse {
21
21
  readonly exp: number;
22
22
  }
23
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
+ }>;
24
33
  export interface LoginChallengeResponse {
25
34
  readonly authSalt: Uint8Array;
26
35
  readonly encSalt: Uint8Array;
@@ -37,5 +46,215 @@ export interface LoginVerifyResponse {
37
46
  readonly blobVersion: number;
38
47
  }
39
48
  export declare function loginVerify(http: HttpClient, email: string, authKey: Uint8Array): Promise<LoginVerifyResponse>;
49
+ /**
50
+ * Input for {@link custodialSignUp}. Caller authenticates the app via ONE
51
+ * of `apiKey` (server-only secret) or `publicKey` (browser-safe). The
52
+ * user's `password` is always required — sign-up no longer auto-generates
53
+ * one server-side. The created account starts in a *pending* state and
54
+ * the user must click the link sent to their inbox before they can
55
+ * sign in.
56
+ */
57
+ export interface CustodialSignUpApiInput {
58
+ /** Server-only Bearer secret: `aithos_<env>_<…>`. Mutually exclusive
59
+ * with `publicKey`. Use this from your backend. */
60
+ readonly apiKey?: string;
61
+ /** Browser-safe public client key: `pk_<env>_<…>`. Mutually exclusive
62
+ * with `apiKey`. The browser sends its `Origin` header alongside; the
63
+ * Aithos backend matches it against the app's allowed_origins list. */
64
+ readonly publicKey?: string;
65
+ readonly email: string;
66
+ /** Raw password the user chose. Must be ≥ 10 chars and mix letters
67
+ * with at least one digit or symbol (server-side rule). */
68
+ readonly password: string;
69
+ readonly displayName?: string;
70
+ readonly handleHint?: string;
71
+ }
72
+ export interface CustodialSignUpApiResponse {
73
+ /** Always "pending_verification" — sign-in is blocked until the
74
+ * user clicks the confirmation link. */
75
+ readonly status: "pending_verification";
76
+ readonly email: string;
77
+ readonly mailSent: boolean;
78
+ readonly mailMessageId?: string;
79
+ }
80
+ /**
81
+ * Provision a custodial-mode account on behalf of a registered app.
82
+ *
83
+ * Two integration paths:
84
+ * - **Backend** caller passes `apiKey` (server-only secret).
85
+ * - **Browser** caller passes `publicKey` (safe to ship in the bundle).
86
+ * The browser also sends its `Origin` header automatically and the
87
+ * auth backend validates it against the app's allowed_origins list.
88
+ *
89
+ * On success the account exists in DDB with `email_verified: false` and
90
+ * the response carries `status: "pending_verification"` — call
91
+ * {@link custodialVerifyEmail} after the user clicks the confirmation
92
+ * link before attempting sign-in.
93
+ */
94
+ export declare function custodialSignUp(http: HttpClient, input: CustodialSignUpApiInput): Promise<CustodialSignUpApiResponse>;
95
+ export interface CustodialVerifyEmailApiInput {
96
+ readonly email: string;
97
+ readonly token: string;
98
+ }
99
+ /**
100
+ * Result of consuming the verification link. Magic-link mode: a
101
+ * successful first-time consumption returns a full session payload
102
+ * (JWT + seeds) so the caller can sign the user in without prompting
103
+ * for the password. Replays of the same link (after first consumption)
104
+ * land on `status: "already_verified"` — the user is already verified
105
+ * and must use the regular sign-in flow from now on.
106
+ *
107
+ * The discriminator is the `status` field. Callers should pattern-match.
108
+ */
109
+ export type CustodialVerifyEmailApiResponse = {
110
+ readonly status: "signed_in";
111
+ readonly session: string;
112
+ readonly exp: number;
113
+ readonly did: string;
114
+ readonly handle: string;
115
+ readonly displayName: string;
116
+ readonly seed: Uint8Array;
117
+ readonly encKey: Uint8Array;
118
+ readonly blob: Uint8Array;
119
+ readonly blobNonce: Uint8Array;
120
+ readonly blobVersion: number;
121
+ } | {
122
+ readonly status: "already_verified";
123
+ readonly email: string;
124
+ };
125
+ /**
126
+ * Consume the verification token from the confirmation link. On a fresh
127
+ * click: returns a full session payload (magic-link auto-signin). On a
128
+ * replayed click of an already-consumed link: returns
129
+ * `{ status: "already_verified" }`.
130
+ *
131
+ * Throws `auth_token_invalid_or_expired` if the token is wrong, consumed,
132
+ * or past its TTL.
133
+ */
134
+ export declare function custodialVerifyEmail(http: HttpClient, input: CustodialVerifyEmailApiInput): Promise<CustodialVerifyEmailApiResponse>;
135
+ /**
136
+ * Input for {@link custodialInvite}. The app authenticates via `apiKey`
137
+ * (server-only secret) or `publicKey` (browser-safe, Origin-gated). The
138
+ * `invitePayload` is an OPAQUE app string delivered verbatim to the invitee
139
+ * on {@link custodialAccept}. For Aithos invitations it's a delegate bundle
140
+ * (mandate + seed) serialized as JSON — but the auth backend never parses it;
141
+ * it stores it bound to a single-use token and returns it at accept time.
142
+ */
143
+ export interface CustodialInviteApiInput {
144
+ readonly apiKey?: string;
145
+ readonly publicKey?: string;
146
+ readonly email: string;
147
+ /** Opaque payload delivered to the invitee on accept (e.g. a mandate bundle JSON). */
148
+ readonly invitePayload: string;
149
+ /** Token TTL in seconds. Backend clamps to its own min/max. Default backend-side. */
150
+ readonly ttlSeconds?: number;
151
+ /** Optional display name pre-filled on the pending account. */
152
+ readonly displayName?: string;
153
+ }
154
+ export interface CustodialInviteApiResponse {
155
+ readonly status: "invited";
156
+ readonly email: string;
157
+ readonly mailSent: boolean;
158
+ readonly mailMessageId?: string;
159
+ }
160
+ /**
161
+ * Send an invitation magic link carrying an opaque payload. The backend
162
+ * mints a single-use token, stores `{ token, email, invite_payload, ttl }`,
163
+ * and emails the magic link (same SES path as the verification mail). The
164
+ * payload (e.g. a mandate bundle) stays server-side — it never rides the
165
+ * email URL. The invitee redeems it via {@link custodialAccept}.
166
+ *
167
+ * No password here: this is an invitation, not an account creation. The
168
+ * invitee chooses their password when they accept.
169
+ */
170
+ export declare function custodialInvite(http: HttpClient, input: CustodialInviteApiInput): Promise<CustodialInviteApiResponse>;
171
+ export interface CustodialAcceptApiInput {
172
+ readonly email: string;
173
+ readonly token: string;
174
+ /**
175
+ * Password. For a brand-new account the invitee SETS it here; for an
176
+ * existing account they AUTHENTICATE with it. Required unless the backend
177
+ * accepts a session-bound redemption (not in v1).
178
+ */
179
+ readonly password?: string;
180
+ }
181
+ /**
182
+ * Result of redeeming an invitation. Always `signed_in` on success — the
183
+ * token is consumed, the account is created (or the existing one is
184
+ * authenticated), and a full session payload is returned alongside the
185
+ * `invitePayload` the inviter attached. `accountCreated` distinguishes the
186
+ * two cases for UX.
187
+ */
188
+ export interface CustodialAcceptApiResponse {
189
+ readonly status: "signed_in";
190
+ readonly session: string;
191
+ readonly exp: number;
192
+ readonly did: string;
193
+ readonly handle: string;
194
+ readonly displayName: string;
195
+ readonly seed: Uint8Array;
196
+ readonly encKey: Uint8Array;
197
+ readonly blob: Uint8Array;
198
+ readonly blobNonce: Uint8Array;
199
+ readonly blobVersion: number;
200
+ /** The opaque payload the inviter attached (e.g. a mandate bundle JSON). */
201
+ readonly invitePayload: string;
202
+ /** True when a new account was provisioned; false when an existing one signed in. */
203
+ readonly accountCreated: boolean;
204
+ }
205
+ /**
206
+ * Redeem an invitation token from the magic link. Consumes the token
207
+ * (single-use), creates the account with the supplied password (or
208
+ * authenticates an existing account), and returns a session + the inviter's
209
+ * `invitePayload`.
210
+ *
211
+ * Throws `auth_token_invalid_or_expired` (bad/consumed/expired token) or an
212
+ * auth error if an existing account's password is wrong / a new password is
213
+ * too weak.
214
+ */
215
+ export declare function custodialAccept(http: HttpClient, input: CustodialAcceptApiInput): Promise<CustodialAcceptApiResponse>;
216
+ /** Re-send the verification mail for a pending account. The backend
217
+ * is anti-enum (always 200) and rate-limited 1/h/account, so this is
218
+ * safe to call even when the user state is unknown. Accepts the same
219
+ * credential families as {@link custodialSignUp}. */
220
+ export declare function custodialResendVerify(http: HttpClient, args: {
221
+ readonly email: string;
222
+ readonly apiKey?: string;
223
+ readonly publicKey?: string;
224
+ }): Promise<void>;
225
+ export interface CustodialSignInApiInput {
226
+ readonly email: string;
227
+ readonly password: string;
228
+ }
229
+ export interface CustodialSignInApiResponse {
230
+ readonly session: string;
231
+ readonly exp: number;
232
+ readonly did: string;
233
+ readonly handle: string;
234
+ readonly displayName: string;
235
+ /** Raw 32-byte Ed25519 seed — caller MUST hydrate its keystore and
236
+ * zeroize this buffer. */
237
+ readonly seed: Uint8Array;
238
+ /** Raw 32-byte vault encryption key — same lifecycle. */
239
+ readonly encKey: Uint8Array;
240
+ readonly blob: Uint8Array;
241
+ readonly blobNonce: Uint8Array;
242
+ readonly blobVersion: number;
243
+ readonly passwordMustChange: boolean;
244
+ }
245
+ export declare function custodialSignIn(http: HttpClient, input: CustodialSignInApiInput): Promise<CustodialSignInApiResponse>;
246
+ export declare function custodialResetRequest(http: HttpClient, email: string): Promise<void>;
247
+ export interface CustodialResetFinalizeApiInput {
248
+ readonly email: string;
249
+ readonly token: string;
250
+ readonly newPassword: string;
251
+ }
252
+ export interface CustodialResetFinalizeApiResponse {
253
+ readonly session: string;
254
+ readonly exp: number;
255
+ readonly did: string;
256
+ readonly handle: string;
257
+ }
258
+ export declare function custodialResetFinalize(http: HttpClient, input: CustodialResetFinalizeApiInput): Promise<CustodialResetFinalizeApiResponse>;
40
259
  export {};
41
260
  //# sourceMappingURL=auth-api.d.ts.map
@@ -41,6 +41,19 @@ async function postJson(http, path, body, jwt) {
41
41
  throw await readError(res, "request_failed");
42
42
  return (await res.json());
43
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
+ }
44
57
  export async function registerAccount(http, input) {
45
58
  return postJson(http, "/auth/register", {
46
59
  email: input.email,
@@ -56,6 +69,13 @@ export async function registerAccount(http, input) {
56
69
  blob_version: input.blobVersion,
57
70
  });
58
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
+ }
59
79
  export async function loginChallenge(http, email) {
60
80
  const wire = await postJson(http, "/auth/login/challenge", { email });
61
81
  return {
@@ -79,4 +99,232 @@ export async function loginVerify(http, email, authKey) {
79
99
  blobVersion: wire.blob_version,
80
100
  };
81
101
  }
102
+ /**
103
+ * Provision a custodial-mode account on behalf of a registered app.
104
+ *
105
+ * Two integration paths:
106
+ * - **Backend** caller passes `apiKey` (server-only secret).
107
+ * - **Browser** caller passes `publicKey` (safe to ship in the bundle).
108
+ * The browser also sends its `Origin` header automatically and the
109
+ * auth backend validates it against the app's allowed_origins list.
110
+ *
111
+ * On success the account exists in DDB with `email_verified: false` and
112
+ * the response carries `status: "pending_verification"` — call
113
+ * {@link custodialVerifyEmail} after the user clicks the confirmation
114
+ * link before attempting sign-in.
115
+ */
116
+ export async function custodialSignUp(http, input) {
117
+ if (!input.apiKey && !input.publicKey) {
118
+ throw new AithosSDKError("auth_missing_api_key", "signUpCustodial requires either apiKey or publicKey");
119
+ }
120
+ if (input.apiKey && input.publicKey) {
121
+ throw new AithosSDKError("auth_invalid_input", "signUpCustodial: pass exactly one of apiKey or publicKey, not both");
122
+ }
123
+ const bearer = (input.apiKey ?? input.publicKey);
124
+ const res = await http.fetchImpl(`${http.authBaseUrl}/auth/custodial/sign-up`, {
125
+ method: "POST",
126
+ headers: {
127
+ "content-type": "application/json",
128
+ authorization: `Bearer ${bearer}`,
129
+ },
130
+ body: JSON.stringify({
131
+ email: input.email,
132
+ password: input.password,
133
+ ...(input.displayName ? { display_name: input.displayName } : {}),
134
+ ...(input.handleHint ? { handle_hint: input.handleHint } : {}),
135
+ }),
136
+ });
137
+ if (!res.ok)
138
+ throw await readError(res, "custodial_signup_failed");
139
+ const wire = (await res.json());
140
+ return {
141
+ status: "pending_verification",
142
+ email: wire.email,
143
+ mailSent: wire.mail_sent,
144
+ ...(wire.mail_message_id !== undefined
145
+ ? { mailMessageId: wire.mail_message_id }
146
+ : {}),
147
+ };
148
+ }
149
+ /**
150
+ * Consume the verification token from the confirmation link. On a fresh
151
+ * click: returns a full session payload (magic-link auto-signin). On a
152
+ * replayed click of an already-consumed link: returns
153
+ * `{ status: "already_verified" }`.
154
+ *
155
+ * Throws `auth_token_invalid_or_expired` if the token is wrong, consumed,
156
+ * or past its TTL.
157
+ */
158
+ export async function custodialVerifyEmail(http, input) {
159
+ const res = await http.fetchImpl(`${http.authBaseUrl}/auth/custodial/verify`, {
160
+ method: "POST",
161
+ headers: { "content-type": "application/json" },
162
+ body: JSON.stringify({ email: input.email, token: input.token }),
163
+ });
164
+ if (!res.ok)
165
+ throw await readError(res, "custodial_verify_failed");
166
+ const wire = (await res.json());
167
+ if (wire.status === "already_verified") {
168
+ return { status: "already_verified", email: wire.email };
169
+ }
170
+ return {
171
+ status: "signed_in",
172
+ session: wire.session,
173
+ exp: wire.exp,
174
+ did: wire.did,
175
+ handle: wire.handle,
176
+ displayName: wire.display_name,
177
+ seed: b64ToBytes(wire.seed_b64),
178
+ encKey: b64ToBytes(wire.enc_key_b64),
179
+ blob: wire.blob_b64 ? b64ToBytes(wire.blob_b64) : new Uint8Array(0),
180
+ blobNonce: wire.blob_nonce_b64
181
+ ? b64ToBytes(wire.blob_nonce_b64)
182
+ : new Uint8Array(0),
183
+ blobVersion: wire.blob_version,
184
+ };
185
+ }
186
+ /**
187
+ * Send an invitation magic link carrying an opaque payload. The backend
188
+ * mints a single-use token, stores `{ token, email, invite_payload, ttl }`,
189
+ * and emails the magic link (same SES path as the verification mail). The
190
+ * payload (e.g. a mandate bundle) stays server-side — it never rides the
191
+ * email URL. The invitee redeems it via {@link custodialAccept}.
192
+ *
193
+ * No password here: this is an invitation, not an account creation. The
194
+ * invitee chooses their password when they accept.
195
+ */
196
+ export async function custodialInvite(http, input) {
197
+ if (!input.apiKey && !input.publicKey) {
198
+ throw new AithosSDKError("auth_missing_api_key", "inviteCustodial requires either apiKey or publicKey");
199
+ }
200
+ if (input.apiKey && input.publicKey) {
201
+ throw new AithosSDKError("auth_invalid_input", "inviteCustodial: pass exactly one of apiKey or publicKey, not both");
202
+ }
203
+ const bearer = (input.apiKey ?? input.publicKey);
204
+ const res = await http.fetchImpl(`${http.authBaseUrl}/auth/custodial/invite`, {
205
+ method: "POST",
206
+ headers: {
207
+ "content-type": "application/json",
208
+ authorization: `Bearer ${bearer}`,
209
+ },
210
+ body: JSON.stringify({
211
+ email: input.email,
212
+ invite_payload: input.invitePayload,
213
+ ...(input.ttlSeconds !== undefined ? { ttl_seconds: input.ttlSeconds } : {}),
214
+ ...(input.displayName ? { display_name: input.displayName } : {}),
215
+ }),
216
+ });
217
+ if (!res.ok)
218
+ throw await readError(res, "custodial_invite_failed");
219
+ const wire = (await res.json());
220
+ return {
221
+ status: "invited",
222
+ email: wire.email,
223
+ mailSent: wire.mail_sent,
224
+ ...(wire.mail_message_id !== undefined ? { mailMessageId: wire.mail_message_id } : {}),
225
+ };
226
+ }
227
+ /**
228
+ * Redeem an invitation token from the magic link. Consumes the token
229
+ * (single-use), creates the account with the supplied password (or
230
+ * authenticates an existing account), and returns a session + the inviter's
231
+ * `invitePayload`.
232
+ *
233
+ * Throws `auth_token_invalid_or_expired` (bad/consumed/expired token) or an
234
+ * auth error if an existing account's password is wrong / a new password is
235
+ * too weak.
236
+ */
237
+ export async function custodialAccept(http, input) {
238
+ const res = await http.fetchImpl(`${http.authBaseUrl}/auth/custodial/accept`, {
239
+ method: "POST",
240
+ headers: { "content-type": "application/json" },
241
+ body: JSON.stringify({
242
+ email: input.email,
243
+ token: input.token,
244
+ ...(input.password ? { password: input.password } : {}),
245
+ }),
246
+ });
247
+ if (!res.ok)
248
+ throw await readError(res, "custodial_accept_failed");
249
+ const wire = (await res.json());
250
+ return {
251
+ status: "signed_in",
252
+ session: wire.session,
253
+ exp: wire.exp,
254
+ did: wire.did,
255
+ handle: wire.handle,
256
+ displayName: wire.display_name,
257
+ seed: b64ToBytes(wire.seed_b64),
258
+ encKey: b64ToBytes(wire.enc_key_b64),
259
+ blob: wire.blob_b64 ? b64ToBytes(wire.blob_b64) : new Uint8Array(0),
260
+ blobNonce: wire.blob_nonce_b64 ? b64ToBytes(wire.blob_nonce_b64) : new Uint8Array(0),
261
+ blobVersion: wire.blob_version,
262
+ invitePayload: wire.invite_payload,
263
+ accountCreated: wire.account_created,
264
+ };
265
+ }
266
+ /* ---- POST /auth/custodial/verify/resend -------------------------------- */
267
+ /** Re-send the verification mail for a pending account. The backend
268
+ * is anti-enum (always 200) and rate-limited 1/h/account, so this is
269
+ * safe to call even when the user state is unknown. Accepts the same
270
+ * credential families as {@link custodialSignUp}. */
271
+ export async function custodialResendVerify(http, args) {
272
+ if (!args.apiKey && !args.publicKey) {
273
+ throw new AithosSDKError("auth_missing_api_key", "resendVerificationEmail requires either apiKey or publicKey");
274
+ }
275
+ const bearer = (args.apiKey ?? args.publicKey);
276
+ const res = await http.fetchImpl(`${http.authBaseUrl}/auth/custodial/verify/resend`, {
277
+ method: "POST",
278
+ headers: {
279
+ "content-type": "application/json",
280
+ authorization: `Bearer ${bearer}`,
281
+ },
282
+ body: JSON.stringify({ email: args.email }),
283
+ });
284
+ if (!res.ok)
285
+ throw await readError(res, "custodial_resend_failed");
286
+ }
287
+ export async function custodialSignIn(http, input) {
288
+ const wire = await postJson(http, "/auth/custodial/sign-in", { email: input.email, password: input.password });
289
+ return {
290
+ session: wire.session,
291
+ exp: wire.exp,
292
+ did: wire.did,
293
+ handle: wire.handle,
294
+ displayName: wire.display_name,
295
+ seed: b64ToBytes(wire.seed_b64),
296
+ encKey: b64ToBytes(wire.enc_key_b64),
297
+ blob: wire.blob_b64 ? b64ToBytes(wire.blob_b64) : new Uint8Array(0),
298
+ blobNonce: wire.blob_nonce_b64
299
+ ? b64ToBytes(wire.blob_nonce_b64)
300
+ : new Uint8Array(0),
301
+ blobVersion: wire.blob_version,
302
+ passwordMustChange: wire.password_must_change,
303
+ };
304
+ }
305
+ /* ---- POST /auth/custodial/reset/request --------------------------------- */
306
+ export async function custodialResetRequest(http, email) {
307
+ // Backend always returns 200 { ok: true } regardless. We accept any
308
+ // 2xx body, even non-JSON, to be defensive.
309
+ const res = await http.fetchImpl(`${http.authBaseUrl}/auth/custodial/reset/request`, {
310
+ method: "POST",
311
+ headers: { "content-type": "application/json" },
312
+ body: JSON.stringify({ email }),
313
+ });
314
+ if (!res.ok)
315
+ throw await readError(res, "custodial_reset_request_failed");
316
+ }
317
+ export async function custodialResetFinalize(http, input) {
318
+ const wire = await postJson(http, "/auth/custodial/reset/finalize", {
319
+ email: input.email,
320
+ token: input.token,
321
+ new_password: input.newPassword,
322
+ });
323
+ return {
324
+ session: wire.session,
325
+ exp: wire.exp,
326
+ did: wire.did,
327
+ handle: wire.handle,
328
+ };
329
+ }
82
330
  //# sourceMappingURL=auth-api.js.map