@waaskey/react 0.3.2 → 0.4.1

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/index.d.cts CHANGED
@@ -1,8 +1,46 @@
1
- import { Waaskey, WaaskeyOptions, Chain, Balance, CreateWalletParams, CreateWalletOptions, Wallet, SendParams, SendResult, Signature, EmbeddedSession } from '@waaskey/sdk';
2
- export * from '@waaskey/sdk';
1
+ import { EmbeddedSession, EndUser, Waaskey, WaaskeyOptions, Wallet, Chain, Balance, CreateWalletParams, CreateWalletOptions, SendParams, SendResult, Signature, PageQuery, WalletData, PasskeyCeremony } from '@waaskey/sdk';
2
+ export { Analytics, AnalyticsEvent, AnalyticsEventType, AnalyticsSink, Auth, Balance, Balances, BroadcastOptions, BroadcastResult, CLIENT_WASM_VERSION, CeremonyParams, Chain, ChainConfig, ChainProvider, ClientWasmLoader, ClientWasmModule, CreateMemberWalletParams, CreateWalletOptions, CreateWalletParams, CreateWalletResponse, CustodyKind, CustodyType, DeviceCompleteReshareParams, DeviceCompleteReshareResult, DeviceKeygenParams, DeviceKeygenResult, DeviceReshareAssembleParams, DeviceReshareAssembleResult, DeviceReshareMaterial, DeviceSignParams, DeviceSignResult, EddsaAssembleRequest, EddsaCeremonyParams, EddsaKeygenParams, EddsaKeygenResult, EddsaSendSession, EddsaSignParams, EddsaSignResult, EmailStartResult, EmbeddedSession, EncryptedShareStore, EndUser, EvmRpcProvider, FactorEnrollment, FactorVerification, FirebaseAuthRequest, HttpAnalyticsSink, IndexedDbKeyValueStore, JoinCeremonyOptions, JoinSignCeremonyOptions, KeyValueStore, Member, MemberCeremony, MemberCeremonyJoinResponse, MemberCeremonyParams, MemberKeygenParams, MemberRole, MemberSession, MemberSignCeremony, MemberSignParams, Members, MembershipScope, MemoryKeyValueStore, MemoryPrimeStore, MpcCore, MpcCurve, Onramp, OnrampWidgetParams, OnrampWidgetUrl, Page, PageQuery, PasskeyAssertionJSON, PasskeyCeremony, PasskeyPrfEnrollOptions, PasskeyPrfResult, PasskeyPrfSecretProvider, PrfCeremony, PrimePool, PrimePoolOptions, PrimePoolStore, RecoverParams, RecoverSignParams, RecoverWalletResponse, Recovery, RecoveryChallengeResponse, RecoveryFactor, RecoveryRetrieveResponse, RecoveryShareInfo, RegisterRecoveryParams, Reshare, ReshareCompletionCeremony, ReshareCompletionParams, ReshareCompletionResult, ReshareWalletResponse, SendOptions, SendParams, SendResult, ShareStore, SignMessageResponse, SignOptions, SignRequestsQuery, SignSessionResponse, Signature, SignatureKind, SigningAssertionCeremony, SigningAssertionOptions, SigningRequestResponse, SigningRequestStatus, StepUpChallengeResponse, StepUpOperation, TokenBalanceOptions, TxStatus, VerifiedWasmLoaderOptions, Waaskey, WaaskeyError, WaaskeyErrorCode, WaaskeyErrorOptions, WaaskeyOptions, Wallet, WalletActionType, WalletBackupParams, WalletCeremony, WalletCurve, WalletData, WalletShareholder, WalletStatus, Wallets, WasmMpcCore, broadcast, createVerifiedClientWasmLoader, epochShareKey, formatUnits, generateRecoveryCode, getSigningAssertion, isNonCustodial, isPasskeyAssertionSupported, isPasskeySupported, isPrfSupported, loadClientWasm, memberShareKey, userBackupPendingKey, validateCustodyPolicy, verifyWasmIntegrity } from '@waaskey/sdk';
3
3
  import * as react from 'react';
4
4
  import { ReactNode, ReactElement } from 'react';
5
5
 
6
+ /**
7
+ * Where the end-user session is kept so a reload doesn't sign the user out. The SDK holds the
8
+ * session **in memory only** (`auth.restore` / `auth.logout`), so without one of these a refresh
9
+ * logs the user out.
10
+ *
11
+ * Persisting a bearer token in web storage means any XSS or malicious extension can read it —
12
+ * which is why the default is `'none'`. Opt in deliberately: `'session'` (tab-scoped, cleared when
13
+ * the tab closes) is the safer built-in; `'local'` survives restarts; or pass your own store to
14
+ * keep the token somewhere you control (e.g. an httpOnly cookie set by your backend).
15
+ */
16
+ type SessionPersistence = 'none' | 'session' | 'local' | AuthSessionStore;
17
+ /** A custom place to keep the session (see {@link SessionPersistence}). */
18
+ interface AuthSessionStore {
19
+ load(): EmbeddedSession | undefined | Promise<EmbeddedSession | undefined>;
20
+ save(session: EmbeddedSession): void | Promise<void>;
21
+ clear(): void | Promise<void>;
22
+ }
23
+ /** Shared end-user auth state — one per provider, so a login anywhere is visible everywhere. */
24
+ interface AuthStore {
25
+ /** The live session, or `undefined` when signed out. */
26
+ session?: EmbeddedSession;
27
+ /** The signed-in end-user (carried by the session; re-fetched by {@link refreshUser}). */
28
+ user?: EndUser;
29
+ /** The initial restore has settled — until then a persisted session may still arrive. */
30
+ ready: boolean;
31
+ /** A `me()` round-trip is in flight. */
32
+ loading: boolean;
33
+ error?: Error;
34
+ /** Adopt a session (or `undefined` to sign out) — restores it on the client and persists it. */
35
+ setSession: (session: EmbeddedSession | undefined) => void;
36
+ /** Re-fetch the end-user from the session token; clears the session if it is no longer valid. */
37
+ refreshUser: () => Promise<void>;
38
+ /** Sign out: clears the SDK session and the persisted copy. */
39
+ logout: () => void;
40
+ }
41
+ /** Context holding the shared {@link AuthStore}. Provided by `WaaskeyProvider`. */
42
+ declare const AuthContext: react.Context<AuthStore | null>;
43
+
6
44
  /**
7
45
  * Design tokens for the Waaskey widget kit (#17). One source for colours, radius and
8
46
  * typography so every component (ConnectModal, WalletWidget, SignPrompt, FundWidget) and the
@@ -43,13 +81,22 @@ type WaaskeyProviderProps = ({
43
81
  }) & {
44
82
  /** Partial theme override (white-label) merged onto the default light theme. */
45
83
  theme?: Partial<WaasTheme>;
84
+ /** Where to keep the end-user session across reloads. Defaults to `'none'` (memory only). */
85
+ persistSession?: SessionPersistence;
46
86
  children?: ReactNode;
47
87
  };
48
88
  /**
49
- * Makes a {@link Waaskey} client (and the kit {@link WaasTheme}) available to the hooks and
50
- * components (`useWaaskey`/`useWaas`, `useTheme`, `<ConnectModal>`, `<WalletWidget>`, …).
51
- * Pass a `client` you built, or `options` to construct one (memoized). SSR-safe (no browser
52
- * APIs at construction). Written with `createElement` so the package needs no JSX build step.
89
+ * Makes a {@link Waaskey} client (and the kit {@link WaasTheme} + shared auth state) available to
90
+ * the hooks and components (`useWaaskey`/`useWaas`, `useAuth`, `useTheme`, `<ConnectModal>`,
91
+ * `<WalletWidget>`, …). Pass a `client` you built, or `options` to construct one. SSR-safe (no
92
+ * browser APIs at construction). Written with `createElement` so the package needs no JSX build step.
93
+ *
94
+ * The client is constructed **once** and kept as long as the options keep the same identity — the
95
+ * SDK holds the end-user session and the MPC/share state on the instance, so rebuilding it on every
96
+ * render would abandon a running ceremony. An inline `options={{ … }}` literal is therefore compared
97
+ * by the identity of its values, not by the identity of the object. When the options genuinely do
98
+ * change (the usual case: wiring the MPC core + share store once a session exists) the live session
99
+ * is re-adopted on the new client.
53
100
  */
54
101
  declare function WaaskeyProvider(props: WaaskeyProviderProps): ReactElement;
55
102
  /** Ergonomic alias of {@link WaaskeyProvider} — the documented kit entry point (`<WaasProvider>`). */
@@ -70,6 +117,9 @@ interface AsyncState<T> {
70
117
  error?: Error;
71
118
  loading: boolean;
72
119
  }
120
+
121
+ /** Either a wallet id or an already-loaded {@link Wallet} — passing the object skips a `wallets.get`. */
122
+ type WalletRef = string | Wallet;
73
123
  /** The {@link Waaskey} client from context. Throws if used outside {@link WaaskeyProvider}. */
74
124
  declare function useWaaskey(): Waaskey;
75
125
  /**
@@ -92,6 +142,11 @@ declare function useCreateWallet(): {
92
142
  declare function useWallet(id: string | undefined): AsyncState<Wallet> & {
93
143
  refresh: () => Promise<void>;
94
144
  };
145
+ /** List the tenant's wallets, newest first (paginated); exposes `total` and `refresh`. */
146
+ declare function useWallets(query?: PageQuery): AsyncState<WalletData[]> & {
147
+ total?: number;
148
+ refresh: () => Promise<void>;
149
+ };
95
150
  /** Read an address's native balance on a chain, client-side (no backend); exposes `refresh`. */
96
151
  declare function useBalance(chain: Chain | undefined, address: string | undefined): AsyncState<Balance> & {
97
152
  refresh: () => Promise<void>;
@@ -108,7 +163,7 @@ type SendStatus = 'idle' | 'pending' | 'sent' | 'error';
108
163
  * the **signed raw tx** (`result.signedTx`) — WaaS never broadcasts; the client submits it
109
164
  * (e.g. `waaskey.broadcast(result.signedTx, { rpcUrl })` or your own node).
110
165
  */
111
- declare function useSend(walletId: string | undefined): {
166
+ declare function useSend(wallet: WalletRef | undefined): {
112
167
  send: (params: SendParams) => Promise<SendResult>;
113
168
  status: SendStatus;
114
169
  result?: SendResult;
@@ -116,31 +171,83 @@ declare function useSend(walletId: string | undefined): {
116
171
  reset: () => void;
117
172
  };
118
173
  /** Load a wallet's signing activity (newest first) — raw signs and send/sweep signed txs; exposes `refresh`. */
119
- declare function useSignatures(walletId: string | undefined): AsyncState<Signature[]> & {
174
+ declare function useSignatures(wallet: WalletRef | undefined): AsyncState<Signature[]> & {
120
175
  refresh: () => Promise<void>;
121
176
  };
122
177
 
123
- /** Step of the email-OTP login flow. */
178
+ /** What {@link useAuth} exposes — the shared end-user auth state of the provider. */
179
+ interface UseAuth {
180
+ /** The live session, or `undefined` when signed out. */
181
+ session?: EmbeddedSession;
182
+ /** The signed-in end-user. */
183
+ user?: EndUser;
184
+ isAuthenticated: boolean;
185
+ /**
186
+ * The initial session restore has settled. Gate your "signed out" UI on this — otherwise a
187
+ * persisted session makes the app flash the login screen on every reload.
188
+ */
189
+ ready: boolean;
190
+ /** A `me()` round-trip is in flight. */
191
+ loading: boolean;
192
+ error?: Error;
193
+ /** Adopt a session established elsewhere (e.g. from `<ConnectModal onConnect>`). */
194
+ setSession: (session: EmbeddedSession | undefined) => void;
195
+ /** Re-fetch the end-user; signs out if the session token is no longer accepted. */
196
+ refreshUser: () => Promise<void>;
197
+ /** Sign out — clears the SDK session and any persisted copy. */
198
+ logout: () => void;
199
+ }
200
+ /**
201
+ * The signed-in end-user, shared across the whole provider: a login through `useLogin` or
202
+ * `<ConnectModal>` updates every consumer of this hook, and (with `persistSession`) survives a
203
+ * reload. The SDK itself keeps the session in memory only, which is why this state lives here.
204
+ */
205
+ declare function useAuth(): UseAuth;
206
+ /** The signed-in end-user, or `undefined`. Sugar over {@link useAuth}. */
207
+ declare function useUser(): EndUser | undefined;
208
+
209
+ /**
210
+ * Step of the login flow. `'email'` is the identifier step — it collects an email **or** a phone
211
+ * number depending on the method the UI offers; `'code'` collects the one-time code.
212
+ */
124
213
  type LoginStep = 'email' | 'code' | 'done';
214
+ /** How the end-user is signing in. */
215
+ type LoginMethod = 'email' | 'phone' | 'google' | 'passkey';
125
216
  interface UseLogin {
126
217
  step: LoginStep;
127
- /** The email entered at the first step. */
218
+ /** The method in progress (set by whichever `start*`/`loginWith*` was called). */
219
+ method: LoginMethod;
220
+ /** The email entered at the first step (empty for phone/social/passkey). */
128
221
  email: string;
222
+ /** The phone entered at the first step (empty for email/social/passkey). */
223
+ phone: string;
129
224
  /** The session once login completes. */
130
225
  session?: EmbeddedSession;
131
226
  loading: boolean;
132
227
  error?: Error;
133
228
  /** Send a one-time code to `email` (→ `code` step). */
134
229
  start: (email: string) => Promise<void>;
135
- /** Verify the code (→ `done` step on success). */
230
+ /** Send a one-time code to `phone` (E.164) (→ `code` step). */
231
+ startPhone: (phone: string) => Promise<void>;
232
+ /** Verify the code for whichever identifier was started (→ `done` step on success). */
136
233
  verify: (code: string) => Promise<void>;
137
- /** Back to the email step (clears error). */
234
+ /**
235
+ * Sign in with a Google ID token. Your app owns the Google button (Google Identity Services or
236
+ * `@react-oauth/google`) and hands the resulting `idToken` here — the kit ships no Google SDK.
237
+ */
238
+ loginWithGoogle: (idToken: string) => Promise<void>;
239
+ /** Sign in with a Firebase ID token (any Firebase provider). */
240
+ loginWithFirebase: (idToken: string) => Promise<void>;
241
+ /** Usernameless passkey (WebAuthn) sign-in. Needs `@simplewebauthn/browser`, or pass a `ceremony`. */
242
+ loginWithPasskey: (ceremony?: PasskeyCeremony) => Promise<void>;
243
+ /** Back to the identifier step (clears the entered values, the error and the session). */
138
244
  reset: () => void;
139
245
  }
140
246
  /**
141
- * Headless email-OTP login (#6/#13): drives `waaskey.auth.email.start` `.verify`,
142
- * tracking `step`/`loading`/`error` so a UI (e.g. `<ConnectModal>`) or a custom one —
143
- * can render all states. The established session is also held on `waaskey.auth`.
247
+ * Headless login (#6/#13) for every method the API supports — email OTP, phone OTP, Google,
248
+ * Firebase and passkey — tracking `step`/`loading`/`error` so a UI (e.g. `<ConnectModal>`) or a
249
+ * custom one can render all states. On success the session is published to the provider's shared
250
+ * auth state, so `useAuth()` sees it everywhere and `persistSession` stores it.
144
251
  */
145
252
  declare function useLogin(): UseLogin;
146
253
 
@@ -158,19 +265,30 @@ interface ConnectModalProps {
158
265
  open: boolean;
159
266
  /** Close requested (backdrop / ✕ / after connect). */
160
267
  onClose: () => void;
161
- /** Called with the session once login completes. */
268
+ /** Called **once** with the session when login completes. */
162
269
  onConnect?: (session: EmbeddedSession) => void;
163
270
  /** Heading copy. */
164
271
  title?: string;
272
+ /**
273
+ * Sign-in methods to offer, in order. Defaults to `['email']`. The first identifier method
274
+ * (`'email'`/`'phone'`) is the default form; the rest render as alternatives.
275
+ */
276
+ methods?: LoginMethod[];
277
+ /**
278
+ * Required to offer `'google'`: resolve a Google ID token. Your app owns the Google button
279
+ * (Google Identity Services / `@react-oauth/google`) — the kit ships no Google SDK.
280
+ */
281
+ googleIdToken?: () => Promise<string>;
165
282
  theme?: ConnectModalTheme;
166
283
  }
167
284
  /**
168
- * Drop-in email-OTP login modal (#13). Runs `useLogin` (→ `waaskey.auth`), rendering the
169
- * email code → done steps with loading/error states; calls `onConnect` with the session.
170
- * Themeable via inline tokens, accessible (labelled dialog, focus, Esc to close); written
171
- * with `createElement` so the package needs no JSX build step.
285
+ * Drop-in login modal (#13). Runs `useLogin` (→ `waaskey.auth`), rendering the identifier → code
286
+ * → done steps with loading/error states; calls `onConnect` with the session (which is also
287
+ * published to the provider's shared auth state, so `useAuth()` sees it). Supports email OTP,
288
+ * phone OTP, passkey and Google. Themeable via inline tokens, accessible (labelled dialog, focus,
289
+ * Esc to close); written with `createElement` so the package needs no JSX build step.
172
290
  */
173
- declare function ConnectModal({ open, onClose, onConnect, title, theme }: ConnectModalProps): ReactElement | null;
291
+ declare function ConnectModal({ open, onClose, onConnect, title, methods, googleIdToken, theme }: ConnectModalProps): ReactElement | null;
174
292
 
175
293
  /** Per-instance theme override for {@link WalletWidget} (merged onto the provider theme). */
176
294
  type WalletWidgetTheme = Partial<WaasTheme>;
@@ -255,4 +373,4 @@ interface FundWidgetProps {
255
373
  */
256
374
  declare function FundWidget({ walletAddress, chainId, cryptoCurrency, fiatCurrency, fiatAmount, label, onComplete }: FundWidgetProps): ReactElement;
257
375
 
258
- export { type AsyncState, ConnectModal, type ConnectModalProps, type ConnectModalTheme, FundWidget, type FundWidgetProps, type LoginStep, type SendStatus, type SignOutcome, SignPrompt, type SignPromptProps, type SignRequest, ThemeContext, type UseLogin, WaasProvider, type WaasProviderProps, type WaasTheme, WaaskeyContext, WaaskeyProvider, type WaaskeyProviderProps, WalletWidget, type WalletWidgetProps, type WalletWidgetTheme, darkTheme, defaultTheme, lightTheme, resolveTheme, useBalance, useBalances, useCreateWallet, useLogin, useQrCode, useSend, useSignPrompt, useSignatures, useTheme, useWaas, useWaaskey, useWallet };
376
+ export { type AsyncState, AuthContext, type AuthSessionStore, type AuthStore, ConnectModal, type ConnectModalProps, type ConnectModalTheme, FundWidget, type FundWidgetProps, type LoginMethod, type LoginStep, type SendStatus, type SessionPersistence, type SignOutcome, SignPrompt, type SignPromptProps, type SignRequest, ThemeContext, type UseAuth, type UseLogin, WaasProvider, type WaasProviderProps, type WaasTheme, WaaskeyContext, WaaskeyProvider, type WaaskeyProviderProps, type WalletRef, WalletWidget, type WalletWidgetProps, type WalletWidgetTheme, darkTheme, defaultTheme, lightTheme, resolveTheme, useAuth, useBalance, useBalances, useCreateWallet, useLogin, useQrCode, useSend, useSignPrompt, useSignatures, useTheme, useUser, useWaas, useWaaskey, useWallet, useWallets };
package/dist/index.d.ts CHANGED
@@ -1,8 +1,46 @@
1
- import { Waaskey, WaaskeyOptions, Chain, Balance, CreateWalletParams, CreateWalletOptions, Wallet, SendParams, SendResult, Signature, EmbeddedSession } from '@waaskey/sdk';
2
- export * from '@waaskey/sdk';
1
+ import { EmbeddedSession, EndUser, Waaskey, WaaskeyOptions, Wallet, Chain, Balance, CreateWalletParams, CreateWalletOptions, SendParams, SendResult, Signature, PageQuery, WalletData, PasskeyCeremony } from '@waaskey/sdk';
2
+ export { Analytics, AnalyticsEvent, AnalyticsEventType, AnalyticsSink, Auth, Balance, Balances, BroadcastOptions, BroadcastResult, CLIENT_WASM_VERSION, CeremonyParams, Chain, ChainConfig, ChainProvider, ClientWasmLoader, ClientWasmModule, CreateMemberWalletParams, CreateWalletOptions, CreateWalletParams, CreateWalletResponse, CustodyKind, CustodyType, DeviceCompleteReshareParams, DeviceCompleteReshareResult, DeviceKeygenParams, DeviceKeygenResult, DeviceReshareAssembleParams, DeviceReshareAssembleResult, DeviceReshareMaterial, DeviceSignParams, DeviceSignResult, EddsaAssembleRequest, EddsaCeremonyParams, EddsaKeygenParams, EddsaKeygenResult, EddsaSendSession, EddsaSignParams, EddsaSignResult, EmailStartResult, EmbeddedSession, EncryptedShareStore, EndUser, EvmRpcProvider, FactorEnrollment, FactorVerification, FirebaseAuthRequest, HttpAnalyticsSink, IndexedDbKeyValueStore, JoinCeremonyOptions, JoinSignCeremonyOptions, KeyValueStore, Member, MemberCeremony, MemberCeremonyJoinResponse, MemberCeremonyParams, MemberKeygenParams, MemberRole, MemberSession, MemberSignCeremony, MemberSignParams, Members, MembershipScope, MemoryKeyValueStore, MemoryPrimeStore, MpcCore, MpcCurve, Onramp, OnrampWidgetParams, OnrampWidgetUrl, Page, PageQuery, PasskeyAssertionJSON, PasskeyCeremony, PasskeyPrfEnrollOptions, PasskeyPrfResult, PasskeyPrfSecretProvider, PrfCeremony, PrimePool, PrimePoolOptions, PrimePoolStore, RecoverParams, RecoverSignParams, RecoverWalletResponse, Recovery, RecoveryChallengeResponse, RecoveryFactor, RecoveryRetrieveResponse, RecoveryShareInfo, RegisterRecoveryParams, Reshare, ReshareCompletionCeremony, ReshareCompletionParams, ReshareCompletionResult, ReshareWalletResponse, SendOptions, SendParams, SendResult, ShareStore, SignMessageResponse, SignOptions, SignRequestsQuery, SignSessionResponse, Signature, SignatureKind, SigningAssertionCeremony, SigningAssertionOptions, SigningRequestResponse, SigningRequestStatus, StepUpChallengeResponse, StepUpOperation, TokenBalanceOptions, TxStatus, VerifiedWasmLoaderOptions, Waaskey, WaaskeyError, WaaskeyErrorCode, WaaskeyErrorOptions, WaaskeyOptions, Wallet, WalletActionType, WalletBackupParams, WalletCeremony, WalletCurve, WalletData, WalletShareholder, WalletStatus, Wallets, WasmMpcCore, broadcast, createVerifiedClientWasmLoader, epochShareKey, formatUnits, generateRecoveryCode, getSigningAssertion, isNonCustodial, isPasskeyAssertionSupported, isPasskeySupported, isPrfSupported, loadClientWasm, memberShareKey, userBackupPendingKey, validateCustodyPolicy, verifyWasmIntegrity } from '@waaskey/sdk';
3
3
  import * as react from 'react';
4
4
  import { ReactNode, ReactElement } from 'react';
5
5
 
6
+ /**
7
+ * Where the end-user session is kept so a reload doesn't sign the user out. The SDK holds the
8
+ * session **in memory only** (`auth.restore` / `auth.logout`), so without one of these a refresh
9
+ * logs the user out.
10
+ *
11
+ * Persisting a bearer token in web storage means any XSS or malicious extension can read it —
12
+ * which is why the default is `'none'`. Opt in deliberately: `'session'` (tab-scoped, cleared when
13
+ * the tab closes) is the safer built-in; `'local'` survives restarts; or pass your own store to
14
+ * keep the token somewhere you control (e.g. an httpOnly cookie set by your backend).
15
+ */
16
+ type SessionPersistence = 'none' | 'session' | 'local' | AuthSessionStore;
17
+ /** A custom place to keep the session (see {@link SessionPersistence}). */
18
+ interface AuthSessionStore {
19
+ load(): EmbeddedSession | undefined | Promise<EmbeddedSession | undefined>;
20
+ save(session: EmbeddedSession): void | Promise<void>;
21
+ clear(): void | Promise<void>;
22
+ }
23
+ /** Shared end-user auth state — one per provider, so a login anywhere is visible everywhere. */
24
+ interface AuthStore {
25
+ /** The live session, or `undefined` when signed out. */
26
+ session?: EmbeddedSession;
27
+ /** The signed-in end-user (carried by the session; re-fetched by {@link refreshUser}). */
28
+ user?: EndUser;
29
+ /** The initial restore has settled — until then a persisted session may still arrive. */
30
+ ready: boolean;
31
+ /** A `me()` round-trip is in flight. */
32
+ loading: boolean;
33
+ error?: Error;
34
+ /** Adopt a session (or `undefined` to sign out) — restores it on the client and persists it. */
35
+ setSession: (session: EmbeddedSession | undefined) => void;
36
+ /** Re-fetch the end-user from the session token; clears the session if it is no longer valid. */
37
+ refreshUser: () => Promise<void>;
38
+ /** Sign out: clears the SDK session and the persisted copy. */
39
+ logout: () => void;
40
+ }
41
+ /** Context holding the shared {@link AuthStore}. Provided by `WaaskeyProvider`. */
42
+ declare const AuthContext: react.Context<AuthStore | null>;
43
+
6
44
  /**
7
45
  * Design tokens for the Waaskey widget kit (#17). One source for colours, radius and
8
46
  * typography so every component (ConnectModal, WalletWidget, SignPrompt, FundWidget) and the
@@ -43,13 +81,22 @@ type WaaskeyProviderProps = ({
43
81
  }) & {
44
82
  /** Partial theme override (white-label) merged onto the default light theme. */
45
83
  theme?: Partial<WaasTheme>;
84
+ /** Where to keep the end-user session across reloads. Defaults to `'none'` (memory only). */
85
+ persistSession?: SessionPersistence;
46
86
  children?: ReactNode;
47
87
  };
48
88
  /**
49
- * Makes a {@link Waaskey} client (and the kit {@link WaasTheme}) available to the hooks and
50
- * components (`useWaaskey`/`useWaas`, `useTheme`, `<ConnectModal>`, `<WalletWidget>`, …).
51
- * Pass a `client` you built, or `options` to construct one (memoized). SSR-safe (no browser
52
- * APIs at construction). Written with `createElement` so the package needs no JSX build step.
89
+ * Makes a {@link Waaskey} client (and the kit {@link WaasTheme} + shared auth state) available to
90
+ * the hooks and components (`useWaaskey`/`useWaas`, `useAuth`, `useTheme`, `<ConnectModal>`,
91
+ * `<WalletWidget>`, …). Pass a `client` you built, or `options` to construct one. SSR-safe (no
92
+ * browser APIs at construction). Written with `createElement` so the package needs no JSX build step.
93
+ *
94
+ * The client is constructed **once** and kept as long as the options keep the same identity — the
95
+ * SDK holds the end-user session and the MPC/share state on the instance, so rebuilding it on every
96
+ * render would abandon a running ceremony. An inline `options={{ … }}` literal is therefore compared
97
+ * by the identity of its values, not by the identity of the object. When the options genuinely do
98
+ * change (the usual case: wiring the MPC core + share store once a session exists) the live session
99
+ * is re-adopted on the new client.
53
100
  */
54
101
  declare function WaaskeyProvider(props: WaaskeyProviderProps): ReactElement;
55
102
  /** Ergonomic alias of {@link WaaskeyProvider} — the documented kit entry point (`<WaasProvider>`). */
@@ -70,6 +117,9 @@ interface AsyncState<T> {
70
117
  error?: Error;
71
118
  loading: boolean;
72
119
  }
120
+
121
+ /** Either a wallet id or an already-loaded {@link Wallet} — passing the object skips a `wallets.get`. */
122
+ type WalletRef = string | Wallet;
73
123
  /** The {@link Waaskey} client from context. Throws if used outside {@link WaaskeyProvider}. */
74
124
  declare function useWaaskey(): Waaskey;
75
125
  /**
@@ -92,6 +142,11 @@ declare function useCreateWallet(): {
92
142
  declare function useWallet(id: string | undefined): AsyncState<Wallet> & {
93
143
  refresh: () => Promise<void>;
94
144
  };
145
+ /** List the tenant's wallets, newest first (paginated); exposes `total` and `refresh`. */
146
+ declare function useWallets(query?: PageQuery): AsyncState<WalletData[]> & {
147
+ total?: number;
148
+ refresh: () => Promise<void>;
149
+ };
95
150
  /** Read an address's native balance on a chain, client-side (no backend); exposes `refresh`. */
96
151
  declare function useBalance(chain: Chain | undefined, address: string | undefined): AsyncState<Balance> & {
97
152
  refresh: () => Promise<void>;
@@ -108,7 +163,7 @@ type SendStatus = 'idle' | 'pending' | 'sent' | 'error';
108
163
  * the **signed raw tx** (`result.signedTx`) — WaaS never broadcasts; the client submits it
109
164
  * (e.g. `waaskey.broadcast(result.signedTx, { rpcUrl })` or your own node).
110
165
  */
111
- declare function useSend(walletId: string | undefined): {
166
+ declare function useSend(wallet: WalletRef | undefined): {
112
167
  send: (params: SendParams) => Promise<SendResult>;
113
168
  status: SendStatus;
114
169
  result?: SendResult;
@@ -116,31 +171,83 @@ declare function useSend(walletId: string | undefined): {
116
171
  reset: () => void;
117
172
  };
118
173
  /** Load a wallet's signing activity (newest first) — raw signs and send/sweep signed txs; exposes `refresh`. */
119
- declare function useSignatures(walletId: string | undefined): AsyncState<Signature[]> & {
174
+ declare function useSignatures(wallet: WalletRef | undefined): AsyncState<Signature[]> & {
120
175
  refresh: () => Promise<void>;
121
176
  };
122
177
 
123
- /** Step of the email-OTP login flow. */
178
+ /** What {@link useAuth} exposes — the shared end-user auth state of the provider. */
179
+ interface UseAuth {
180
+ /** The live session, or `undefined` when signed out. */
181
+ session?: EmbeddedSession;
182
+ /** The signed-in end-user. */
183
+ user?: EndUser;
184
+ isAuthenticated: boolean;
185
+ /**
186
+ * The initial session restore has settled. Gate your "signed out" UI on this — otherwise a
187
+ * persisted session makes the app flash the login screen on every reload.
188
+ */
189
+ ready: boolean;
190
+ /** A `me()` round-trip is in flight. */
191
+ loading: boolean;
192
+ error?: Error;
193
+ /** Adopt a session established elsewhere (e.g. from `<ConnectModal onConnect>`). */
194
+ setSession: (session: EmbeddedSession | undefined) => void;
195
+ /** Re-fetch the end-user; signs out if the session token is no longer accepted. */
196
+ refreshUser: () => Promise<void>;
197
+ /** Sign out — clears the SDK session and any persisted copy. */
198
+ logout: () => void;
199
+ }
200
+ /**
201
+ * The signed-in end-user, shared across the whole provider: a login through `useLogin` or
202
+ * `<ConnectModal>` updates every consumer of this hook, and (with `persistSession`) survives a
203
+ * reload. The SDK itself keeps the session in memory only, which is why this state lives here.
204
+ */
205
+ declare function useAuth(): UseAuth;
206
+ /** The signed-in end-user, or `undefined`. Sugar over {@link useAuth}. */
207
+ declare function useUser(): EndUser | undefined;
208
+
209
+ /**
210
+ * Step of the login flow. `'email'` is the identifier step — it collects an email **or** a phone
211
+ * number depending on the method the UI offers; `'code'` collects the one-time code.
212
+ */
124
213
  type LoginStep = 'email' | 'code' | 'done';
214
+ /** How the end-user is signing in. */
215
+ type LoginMethod = 'email' | 'phone' | 'google' | 'passkey';
125
216
  interface UseLogin {
126
217
  step: LoginStep;
127
- /** The email entered at the first step. */
218
+ /** The method in progress (set by whichever `start*`/`loginWith*` was called). */
219
+ method: LoginMethod;
220
+ /** The email entered at the first step (empty for phone/social/passkey). */
128
221
  email: string;
222
+ /** The phone entered at the first step (empty for email/social/passkey). */
223
+ phone: string;
129
224
  /** The session once login completes. */
130
225
  session?: EmbeddedSession;
131
226
  loading: boolean;
132
227
  error?: Error;
133
228
  /** Send a one-time code to `email` (→ `code` step). */
134
229
  start: (email: string) => Promise<void>;
135
- /** Verify the code (→ `done` step on success). */
230
+ /** Send a one-time code to `phone` (E.164) (→ `code` step). */
231
+ startPhone: (phone: string) => Promise<void>;
232
+ /** Verify the code for whichever identifier was started (→ `done` step on success). */
136
233
  verify: (code: string) => Promise<void>;
137
- /** Back to the email step (clears error). */
234
+ /**
235
+ * Sign in with a Google ID token. Your app owns the Google button (Google Identity Services or
236
+ * `@react-oauth/google`) and hands the resulting `idToken` here — the kit ships no Google SDK.
237
+ */
238
+ loginWithGoogle: (idToken: string) => Promise<void>;
239
+ /** Sign in with a Firebase ID token (any Firebase provider). */
240
+ loginWithFirebase: (idToken: string) => Promise<void>;
241
+ /** Usernameless passkey (WebAuthn) sign-in. Needs `@simplewebauthn/browser`, or pass a `ceremony`. */
242
+ loginWithPasskey: (ceremony?: PasskeyCeremony) => Promise<void>;
243
+ /** Back to the identifier step (clears the entered values, the error and the session). */
138
244
  reset: () => void;
139
245
  }
140
246
  /**
141
- * Headless email-OTP login (#6/#13): drives `waaskey.auth.email.start` `.verify`,
142
- * tracking `step`/`loading`/`error` so a UI (e.g. `<ConnectModal>`) or a custom one —
143
- * can render all states. The established session is also held on `waaskey.auth`.
247
+ * Headless login (#6/#13) for every method the API supports — email OTP, phone OTP, Google,
248
+ * Firebase and passkey — tracking `step`/`loading`/`error` so a UI (e.g. `<ConnectModal>`) or a
249
+ * custom one can render all states. On success the session is published to the provider's shared
250
+ * auth state, so `useAuth()` sees it everywhere and `persistSession` stores it.
144
251
  */
145
252
  declare function useLogin(): UseLogin;
146
253
 
@@ -158,19 +265,30 @@ interface ConnectModalProps {
158
265
  open: boolean;
159
266
  /** Close requested (backdrop / ✕ / after connect). */
160
267
  onClose: () => void;
161
- /** Called with the session once login completes. */
268
+ /** Called **once** with the session when login completes. */
162
269
  onConnect?: (session: EmbeddedSession) => void;
163
270
  /** Heading copy. */
164
271
  title?: string;
272
+ /**
273
+ * Sign-in methods to offer, in order. Defaults to `['email']`. The first identifier method
274
+ * (`'email'`/`'phone'`) is the default form; the rest render as alternatives.
275
+ */
276
+ methods?: LoginMethod[];
277
+ /**
278
+ * Required to offer `'google'`: resolve a Google ID token. Your app owns the Google button
279
+ * (Google Identity Services / `@react-oauth/google`) — the kit ships no Google SDK.
280
+ */
281
+ googleIdToken?: () => Promise<string>;
165
282
  theme?: ConnectModalTheme;
166
283
  }
167
284
  /**
168
- * Drop-in email-OTP login modal (#13). Runs `useLogin` (→ `waaskey.auth`), rendering the
169
- * email code → done steps with loading/error states; calls `onConnect` with the session.
170
- * Themeable via inline tokens, accessible (labelled dialog, focus, Esc to close); written
171
- * with `createElement` so the package needs no JSX build step.
285
+ * Drop-in login modal (#13). Runs `useLogin` (→ `waaskey.auth`), rendering the identifier → code
286
+ * → done steps with loading/error states; calls `onConnect` with the session (which is also
287
+ * published to the provider's shared auth state, so `useAuth()` sees it). Supports email OTP,
288
+ * phone OTP, passkey and Google. Themeable via inline tokens, accessible (labelled dialog, focus,
289
+ * Esc to close); written with `createElement` so the package needs no JSX build step.
172
290
  */
173
- declare function ConnectModal({ open, onClose, onConnect, title, theme }: ConnectModalProps): ReactElement | null;
291
+ declare function ConnectModal({ open, onClose, onConnect, title, methods, googleIdToken, theme }: ConnectModalProps): ReactElement | null;
174
292
 
175
293
  /** Per-instance theme override for {@link WalletWidget} (merged onto the provider theme). */
176
294
  type WalletWidgetTheme = Partial<WaasTheme>;
@@ -255,4 +373,4 @@ interface FundWidgetProps {
255
373
  */
256
374
  declare function FundWidget({ walletAddress, chainId, cryptoCurrency, fiatCurrency, fiatAmount, label, onComplete }: FundWidgetProps): ReactElement;
257
375
 
258
- export { type AsyncState, ConnectModal, type ConnectModalProps, type ConnectModalTheme, FundWidget, type FundWidgetProps, type LoginStep, type SendStatus, type SignOutcome, SignPrompt, type SignPromptProps, type SignRequest, ThemeContext, type UseLogin, WaasProvider, type WaasProviderProps, type WaasTheme, WaaskeyContext, WaaskeyProvider, type WaaskeyProviderProps, WalletWidget, type WalletWidgetProps, type WalletWidgetTheme, darkTheme, defaultTheme, lightTheme, resolveTheme, useBalance, useBalances, useCreateWallet, useLogin, useQrCode, useSend, useSignPrompt, useSignatures, useTheme, useWaas, useWaaskey, useWallet };
376
+ export { type AsyncState, AuthContext, type AuthSessionStore, type AuthStore, ConnectModal, type ConnectModalProps, type ConnectModalTheme, FundWidget, type FundWidgetProps, type LoginMethod, type LoginStep, type SendStatus, type SessionPersistence, type SignOutcome, SignPrompt, type SignPromptProps, type SignRequest, ThemeContext, type UseAuth, type UseLogin, WaasProvider, type WaasProviderProps, type WaasTheme, WaaskeyContext, WaaskeyProvider, type WaaskeyProviderProps, type WalletRef, WalletWidget, type WalletWidgetProps, type WalletWidgetTheme, darkTheme, defaultTheme, lightTheme, resolveTheme, useAuth, useBalance, useBalances, useCreateWallet, useLogin, useQrCode, useSend, useSignPrompt, useSignatures, useTheme, useUser, useWaas, useWaaskey, useWallet, useWallets };