From 0ce10a7cf5f91472c40c8c41a861e183ff917dac Mon Sep 17 00:00:00 2001 From: Sahil Vasava Date: Wed, 25 Feb 2026 19:15:20 -0300 Subject: [PATCH 1/3] Add wallet docs, remove from top nav, rename to /wallets - Add wallet SDK documentation pages with auth guides (passkeys, email OTP, magic links, Google OAuth), hook references, session management, and wallet export docs - Add IMPORTANT danger callout on all wallet pages warning this is for internal testing only - Remove "Wallet" link from top navigation to prevent public discovery - Remove Wagmi Connector dedicated page - Add otpCodeCustomization parameter docs for useSendOTP and useSendMagicLink to match current SDK - Rename route from /wallet to /wallets --- docs/pages/wallets/auth/email-otp.mdx | 90 ++++++++++++ docs/pages/wallets/auth/google-oauth.mdx | 85 ++++++++++++ docs/pages/wallets/auth/magic-link.mdx | 107 +++++++++++++++ docs/pages/wallets/auth/passkeys.mdx | 75 ++++++++++ docs/pages/wallets/export.mdx | 112 +++++++++++++++ .../wallets/hooks/use-authenticate-oauth.mdx | 79 +++++++++++ .../wallets/hooks/use-export-private-key.mdx | 105 ++++++++++++++ .../pages/wallets/hooks/use-export-wallet.mdx | 89 ++++++++++++ .../wallets/hooks/use-get-user-email.mdx | 56 ++++++++ .../pages/wallets/hooks/use-login-passkey.mdx | 66 +++++++++ .../wallets/hooks/use-refresh-session.mdx | 66 +++++++++ .../wallets/hooks/use-register-passkey.mdx | 66 +++++++++ .../wallets/hooks/use-send-magic-link.mdx | 114 ++++++++++++++++ docs/pages/wallets/hooks/use-send-otp.mdx | 115 ++++++++++++++++ .../wallets/hooks/use-verify-magic-link.mdx | 81 +++++++++++ docs/pages/wallets/hooks/use-verify-otp.mdx | 87 ++++++++++++ docs/pages/wallets/index.mdx | 53 ++++++++ docs/pages/wallets/quickstart.mdx | 128 ++++++++++++++++++ docs/pages/wallets/session-management.mdx | 101 ++++++++++++++ docs/pages/wallets/shared/mutation-result.mdx | 33 +++++ docs/pages/wallets/shared/query-result.mdx | 46 +++++++ vocs.config.tsx | 102 ++++++++++++++ 22 files changed, 1856 insertions(+) create mode 100644 docs/pages/wallets/auth/email-otp.mdx create mode 100644 docs/pages/wallets/auth/google-oauth.mdx create mode 100644 docs/pages/wallets/auth/magic-link.mdx create mode 100644 docs/pages/wallets/auth/passkeys.mdx create mode 100644 docs/pages/wallets/export.mdx create mode 100644 docs/pages/wallets/hooks/use-authenticate-oauth.mdx create mode 100644 docs/pages/wallets/hooks/use-export-private-key.mdx create mode 100644 docs/pages/wallets/hooks/use-export-wallet.mdx create mode 100644 docs/pages/wallets/hooks/use-get-user-email.mdx create mode 100644 docs/pages/wallets/hooks/use-login-passkey.mdx create mode 100644 docs/pages/wallets/hooks/use-refresh-session.mdx create mode 100644 docs/pages/wallets/hooks/use-register-passkey.mdx create mode 100644 docs/pages/wallets/hooks/use-send-magic-link.mdx create mode 100644 docs/pages/wallets/hooks/use-send-otp.mdx create mode 100644 docs/pages/wallets/hooks/use-verify-magic-link.mdx create mode 100644 docs/pages/wallets/hooks/use-verify-otp.mdx create mode 100644 docs/pages/wallets/index.mdx create mode 100644 docs/pages/wallets/quickstart.mdx create mode 100644 docs/pages/wallets/session-management.mdx create mode 100644 docs/pages/wallets/shared/mutation-result.mdx create mode 100644 docs/pages/wallets/shared/query-result.mdx diff --git a/docs/pages/wallets/auth/email-otp.mdx b/docs/pages/wallets/auth/email-otp.mdx new file mode 100644 index 0000000..c7aaf37 --- /dev/null +++ b/docs/pages/wallets/auth/email-otp.mdx @@ -0,0 +1,90 @@ +# Email OTP Authentication [Authenticate with a one-time code sent by email] + +:::danger[IMPORTANT] +**USE FOR INTERNAL TESTING PURPOSES ONLY.** You may use these features solely for internal evaluation purposes on supported testnets. DO NOT use for production use or share with your users. Wallets created during this preview ("Alpha Wallets") will be discontinued. Any tokens remaining within Alpha Wallets will be permanently lost upon discontinuance. Any mainnet tokens sent to an Alpha Wallet will not be deposited and will be permanently lost when discontinued. We are unable to help recover any lost funds from Alpha Wallets. We provide all previews on an "as is" basis without warranty of any kind, and we may terminate or suspend the availability of any preview at any time. +::: + +Email OTP is a two-step flow: send a verification code to the user's email, then verify the code they enter. + +## Hooks + +- [`useSendOTP`](/wallets/hooks/use-send-otp) — Send a one-time code to an email address +- [`useVerifyOTP`](/wallets/hooks/use-verify-otp) — Verify the code and authenticate + +## Example + +```tsx +import { useState } from 'react' +import { useAccount, useDisconnect } from 'wagmi' +import { useSendOTP, useVerifyOTP } from '@zerodev/wallet-react' + +function EmailOTPAuth() { + const [email, setEmail] = useState('') + const [code, setCode] = useState('') + const [otpId, setOtpId] = useState(null) + + const { address, isConnected } = useAccount() + const { disconnectAsync } = useDisconnect() + const sendOTP = useSendOTP() + const verifyOTP = useVerifyOTP() + + if (isConnected) { + return ( +
+

Connected: {address}

+ +
+ ) + } + + if (!otpId) { + return ( +
+ setEmail(e.target.value)} + /> + + {sendOTP.isError &&

Error: {sendOTP.error.message}

} +
+ ) + } + + return ( +
+

Code sent to {email}

+ setCode(e.target.value)} + /> + + {verifyOTP.isError &&

Error: {verifyOTP.error.message}

} +
+ ) +} +``` + +## How it works + +1. **Send code**: `useSendOTP` sends a one-time verification code to the provided email address. It returns an `otpId` that identifies this verification attempt. + +2. **Verify code**: `useVerifyOTP` takes the `otpId` and the code the user entered. If the code is valid, the SDK authenticates and creates a session. + +After verification, the Wagmi connector is connected and the user's address is available via `useAccount`. diff --git a/docs/pages/wallets/auth/google-oauth.mdx b/docs/pages/wallets/auth/google-oauth.mdx new file mode 100644 index 0000000..d3ce053 --- /dev/null +++ b/docs/pages/wallets/auth/google-oauth.mdx @@ -0,0 +1,85 @@ +# Google OAuth [Authenticate with Google sign-in] + +:::danger[IMPORTANT] +**USE FOR INTERNAL TESTING PURPOSES ONLY.** You may use these features solely for internal evaluation purposes on supported testnets. DO NOT use for production use or share with your users. Wallets created during this preview ("Alpha Wallets") will be discontinued. Any tokens remaining within Alpha Wallets will be permanently lost upon discontinuance. Any mainnet tokens sent to an Alpha Wallet will not be deposited and will be permanently lost when discontinued. We are unable to help recover any lost funds from Alpha Wallets. We provide all previews on an "as is" basis without warranty of any kind, and we may terminate or suspend the availability of any preview at any time. +::: + +Google OAuth lets users sign in with their Google account using a popup-based flow. The SDK handles the popup, redirect, and session creation automatically. + +## Hook + +- [`useAuthenticateOAuth`](/wallets/hooks/use-authenticate-oauth) — Trigger the OAuth flow + +## Example + +```tsx +import { useAccount, useDisconnect } from 'wagmi' +import { + useAuthenticateOAuth, + OAUTH_PROVIDERS, +} from '@zerodev/wallet-react' + +function GoogleAuth() { + const { address, isConnected } = useAccount() + const { disconnectAsync } = useDisconnect() + const authenticateOAuth = useAuthenticateOAuth() + + if (isConnected) { + return ( +
+

Connected: {address}

+ +
+ ) + } + + return ( +
+ + + {authenticateOAuth.isError && ( +

Error: {authenticateOAuth.error.message}

+ )} +
+ ) +} +``` + +## How it works + +1. **Open popup**: `useAuthenticateOAuth` opens a popup window to the KMS backend's OAuth endpoint. + +2. **Google sign-in**: The backend initiates the Google OAuth flow with PKCE. The user signs in with their Google account. + +3. **Backend callback**: Google redirects back to the backend, which exchanges the auth code for tokens and sets a session cookie. + +4. **Popup redirect**: The backend redirects the popup to your app with `?oauth_success=true`. + +5. **Auto-detect**: The SDK detects the success parameter. If running in a popup, it sends a `postMessage` to the opener window and closes. The main window then calls the backend's auth endpoint (reading the session cookie) to get a session. + +After the flow completes, the Wagmi connector is connected and the user's address is available via `useAccount`. + +## Backend requirements + +Google OAuth requires a KMS proxy backend that handles the OAuth flow. Set the `proxyBaseUrl` connector option to point to your backend: + +```tsx +zeroDevWallet({ + projectId: 'YOUR_PROJECT_ID', + proxyBaseUrl: 'https://your-backend.com', + chains: [sepolia], +}) +``` + +The backend must have Google OAuth credentials configured (`GOOGLE_CLIENT_ID` and `GOOGLE_CLIENT_SECRET`). diff --git a/docs/pages/wallets/auth/magic-link.mdx b/docs/pages/wallets/auth/magic-link.mdx new file mode 100644 index 0000000..8bd808c --- /dev/null +++ b/docs/pages/wallets/auth/magic-link.mdx @@ -0,0 +1,107 @@ +# Magic Link Authentication [Authenticate with a link sent by email] + +:::danger[IMPORTANT] +**USE FOR INTERNAL TESTING PURPOSES ONLY.** You may use these features solely for internal evaluation purposes on supported testnets. DO NOT use for production use or share with your users. Wallets created during this preview ("Alpha Wallets") will be discontinued. Any tokens remaining within Alpha Wallets will be permanently lost upon discontinuance. Any mainnet tokens sent to an Alpha Wallet will not be deposited and will be permanently lost when discontinued. We are unable to help recover any lost funds from Alpha Wallets. We provide all previews on an "as is" basis without warranty of any kind, and we may terminate or suspend the availability of any preview at any time. +::: + +Magic links let users authenticate by clicking a link in their email. The link redirects to your app where the SDK completes the verification. + +## Hooks + +- [`useSendMagicLink`](/wallets/hooks/use-send-magic-link) — Send a magic link to an email address +- [`useVerifyMagicLink`](/wallets/hooks/use-verify-magic-link) — Verify the magic link and authenticate + +## Example + +### Login page — send the magic link + +```tsx +import { useState } from 'react' +import { useSendMagicLink } from '@zerodev/wallet-react' + +function MagicLinkLogin() { + const [email, setEmail] = useState('') + const sendMagicLink = useSendMagicLink() + + return ( +
+ setEmail(e.target.value)} + /> + + + {sendMagicLink.isSuccess && ( +

Check your email for the magic link!

+ )} + {sendMagicLink.isError && ( +

Error: {sendMagicLink.error.message}

+ )} +
+ ) +} +``` + +### Verify page — handle the redirect + +When the user clicks the magic link, they're redirected to your `redirectURL` with query parameters. The verify page reads these and completes authentication: + +```tsx +import { useEffect } from 'react' +import { useSearchParams } from 'next/navigation' +import { useAccount } from 'wagmi' +import { useVerifyMagicLink } from '@zerodev/wallet-react' + +function VerifyMagicLink() { + const searchParams = useSearchParams() + const { isConnected, address } = useAccount() + const verifyMagicLink = useVerifyMagicLink() + + useEffect(() => { + const code = searchParams.get('code') + const otpId = sessionStorage.getItem('magicLinkOtpId') + + if (code && otpId && !isConnected) { + verifyMagicLink.mutateAsync({ otpId, code }) + } + }, [searchParams]) + + if (isConnected) { + return

Connected: {address}

+ } + + if (verifyMagicLink.isPending) { + return

Verifying...

+ } + + if (verifyMagicLink.isError) { + return

Error: {verifyMagicLink.error.message}

+ } + + return

Waiting for verification...

+} +``` + +## How it works + +1. **Send link**: `useSendMagicLink` sends an email with a magic link pointing to your `redirectURL`. It returns an `otpId` that you need for verification. + +2. **User clicks link**: The user clicks the link in their email, which redirects them to your app with a `code` query parameter. + +3. **Verify**: Your verify page calls `useVerifyMagicLink` with the `otpId` and `code`. If valid, the SDK authenticates and creates a session. + +After verification, the Wagmi connector is connected and the user's address is available via `useAccount`. diff --git a/docs/pages/wallets/auth/passkeys.mdx b/docs/pages/wallets/auth/passkeys.mdx new file mode 100644 index 0000000..84cbc69 --- /dev/null +++ b/docs/pages/wallets/auth/passkeys.mdx @@ -0,0 +1,75 @@ +# Passkey Authentication [Register and login with WebAuthn passkeys] + +:::danger[IMPORTANT] +**USE FOR INTERNAL TESTING PURPOSES ONLY.** You may use these features solely for internal evaluation purposes on supported testnets. DO NOT use for production use or share with your users. Wallets created during this preview ("Alpha Wallets") will be discontinued. Any tokens remaining within Alpha Wallets will be permanently lost upon discontinuance. Any mainnet tokens sent to an Alpha Wallet will not be deposited and will be permanently lost when discontinued. We are unable to help recover any lost funds from Alpha Wallets. We provide all previews on an "as is" basis without warranty of any kind, and we may terminate or suspend the availability of any preview at any time. +::: + +Passkeys use the [WebAuthn](https://webauthn.guide/) standard for passwordless authentication. Users authenticate with biometrics (Face ID, Touch ID, fingerprint) or a hardware security key. + +## Hooks + +- [`useRegisterPasskey`](/wallets/hooks/use-register-passkey) — Create a new wallet with a passkey +- [`useLoginPasskey`](/wallets/hooks/use-login-passkey) — Sign in to an existing wallet + +## Example + +```tsx +import { useAccount, useDisconnect } from 'wagmi' +import { useRegisterPasskey, useLoginPasskey } from '@zerodev/wallet-react' + +function PasskeyAuth() { + const { address, isConnected } = useAccount() + const { disconnectAsync } = useDisconnect() + const registerPasskey = useRegisterPasskey() + const loginPasskey = useLoginPasskey() + + if (isConnected) { + return ( +
+

Connected: {address}

+ +
+ ) + } + + return ( +
+ + + + + {registerPasskey.isError && ( +

Registration error: {registerPasskey.error.message}

+ )} + {loginPasskey.isError && ( +

Login error: {loginPasskey.error.message}

+ )} +
+ ) +} +``` + +## How it works + +1. **Register**: `useRegisterPasskey` triggers the browser's WebAuthn prompt. The user creates a passkey stored on their device. A new wallet is created and linked to the passkey. + +2. **Login**: `useLoginPasskey` triggers the WebAuthn prompt. The user selects their existing passkey. The SDK authenticates and creates a session. + +After either flow, the Wagmi connector is connected and the user's address is available via `useAccount`. + +## Notes + +- No email is required for passkey auth — the passkey itself is the credential +- Passkeys are supported in all major browsers (Chrome, Safari, Firefox, Edge) +- Passkeys can sync across devices via iCloud Keychain, Google Password Manager, etc. +- The `rpId` connector option controls the WebAuthn relying party ID (defaults to the current hostname) diff --git a/docs/pages/wallets/export.mdx b/docs/pages/wallets/export.mdx new file mode 100644 index 0000000..256f62f --- /dev/null +++ b/docs/pages/wallets/export.mdx @@ -0,0 +1,112 @@ +# Export Wallet [Let users export their seed phrase or private key] + +:::danger[IMPORTANT] +**USE FOR INTERNAL TESTING PURPOSES ONLY.** You may use these features solely for internal evaluation purposes on supported testnets. DO NOT use for production use or share with your users. Wallets created during this preview ("Alpha Wallets") will be discontinued. Any tokens remaining within Alpha Wallets will be permanently lost upon discontinuance. Any mainnet tokens sent to an Alpha Wallet will not be deposited and will be permanently lost when discontinued. We are unable to help recover any lost funds from Alpha Wallets. We provide all previews on an "as is" basis without warranty of any kind, and we may terminate or suspend the availability of any preview at any time. +::: + +The SDK supports exporting the user's wallet as a seed phrase or private key. The key material is displayed inside a secure iframe and never touches your application code. + +## Hooks + +- [`useExportWallet`](/wallets/hooks/use-export-wallet) — Export the wallet seed phrase +- [`useExportPrivateKey`](/wallets/hooks/use-export-private-key) — Export a single private key + +## Example + +```tsx +import { useState } from 'react' +import { useExportWallet, useExportPrivateKey } from '@zerodev/wallet-react' + +function ExportModal() { + const [showExport, setShowExport] = useState(false) + const exportWallet = useExportWallet() + const exportPrivateKey = useExportPrivateKey() + + return ( +
+ + + {showExport && ( +
+

Export Options

+ + {/* Container where the export iframe will render */} +
+ + + + + + +
+ )} +
+ ) +} +``` + +## How it works + +1. You provide a container element ID where the secure iframe will be rendered. +2. The SDK initiates a secure export session. +3. The seed phrase or private key is rendered inside a secure iframe. +4. The key material is displayed directly to the user — it never passes through your application. + +## Iframe styling + +Customize the iframe appearance with `iframeStyles`: + +```tsx +exportWallet.mutateAsync({ + iframeContainerId: 'export-container', + iframeStyles: { + width: '100%', + height: '250px', + border: '1px solid #ccc', + borderRadius: '8px', + padding: '16px', + }, +}) +``` + +## Private key formats + +`useExportPrivateKey` supports two key formats: + +| Format | Description | +|--------|-------------| +| `'Hexadecimal'` | Standard hex-encoded private key (default) | +| `'Solana'` | Solana-compatible key format | diff --git a/docs/pages/wallets/hooks/use-authenticate-oauth.mdx b/docs/pages/wallets/hooks/use-authenticate-oauth.mdx new file mode 100644 index 0000000..a09ccc6 --- /dev/null +++ b/docs/pages/wallets/hooks/use-authenticate-oauth.mdx @@ -0,0 +1,79 @@ +import MutationResult from '../shared/mutation-result.mdx' + +# useAuthenticateOAuth [Hook for authenticating with an OAuth provider] + +:::danger[IMPORTANT] +**USE FOR INTERNAL TESTING PURPOSES ONLY.** You may use these features solely for internal evaluation purposes on supported testnets. DO NOT use for production use or share with your users. Wallets created during this preview ("Alpha Wallets") will be discontinued. Any tokens remaining within Alpha Wallets will be permanently lost upon discontinuance. Any mainnet tokens sent to an Alpha Wallet will not be deposited and will be permanently lost when discontinued. We are unable to help recover any lost funds from Alpha Wallets. We provide all previews on an "as is" basis without warranty of any kind, and we may terminate or suspend the availability of any preview at any time. +::: + +## Import + +```tsx +import { useAuthenticateOAuth, OAUTH_PROVIDERS } from '@zerodev/wallet-react' +``` + +## Usage + +```tsx +import { + useAuthenticateOAuth, + OAUTH_PROVIDERS, +} from '@zerodev/wallet-react' +import { useAccount } from 'wagmi' + +function OAuthLogin() { + const authenticateOAuth = useAuthenticateOAuth() + const { address, isConnected } = useAccount() + + if (isConnected) { + return

Logged in: {address}

+ } + + return ( + + ) +} +``` + +## Parameters + +### provider + +`OAuthProvider` + +**Required.** The OAuth provider to authenticate with. Use the `OAUTH_PROVIDERS` constant: + +- `OAUTH_PROVIDERS.GOOGLE` — Google OAuth + +## Return Types + +[TanStack Query mutation docs](https://tanstack.com/query/v5/docs/react/reference/useMutation) + +### mutate + +`(variables: { provider: OAuthProvider }) => void` + +The mutation function to start the OAuth flow. Opens a popup window for the user to sign in. + +### mutateAsync + +`(variables: { provider: OAuthProvider }) => Promise` + +Similar to [`mutate`](#mutate) but returns a promise. Resolves when the OAuth flow completes and the wallet is connected. + +### data + +`void` + +This mutation does not return data. On success, the Wagmi connector is connected and the account is available via `useAccount`. + + diff --git a/docs/pages/wallets/hooks/use-export-private-key.mdx b/docs/pages/wallets/hooks/use-export-private-key.mdx new file mode 100644 index 0000000..d1f1d15 --- /dev/null +++ b/docs/pages/wallets/hooks/use-export-private-key.mdx @@ -0,0 +1,105 @@ +import MutationResult from '../shared/mutation-result.mdx' + +# useExportPrivateKey [Hook for exporting a private key] + +:::danger[IMPORTANT] +**USE FOR INTERNAL TESTING PURPOSES ONLY.** You may use these features solely for internal evaluation purposes on supported testnets. DO NOT use for production use or share with your users. Wallets created during this preview ("Alpha Wallets") will be discontinued. Any tokens remaining within Alpha Wallets will be permanently lost upon discontinuance. Any mainnet tokens sent to an Alpha Wallet will not be deposited and will be permanently lost when discontinued. We are unable to help recover any lost funds from Alpha Wallets. We provide all previews on an "as is" basis without warranty of any kind, and we may terminate or suspend the availability of any preview at any time. +::: + +## Import + +```tsx +import { useExportPrivateKey } from '@zerodev/wallet-react' +``` + +## Usage + +```tsx +import { useExportPrivateKey } from '@zerodev/wallet-react' + +function ExportKey() { + const exportPrivateKey = useExportPrivateKey() + + return ( +
+
+ + +
+ ) +} +``` + +## Parameters + +### iframeContainerId + +`string` + +**Required.** The `id` of the DOM element where the secure export iframe will be rendered. The private key is displayed inside this iframe. + +### iframeStyles + +`Record | undefined` + +Optional CSS styles to apply to the export iframe element. + +### address + +`string | undefined` + +The address of the account to export the private key for. If omitted, uses the currently active account. + +### keyFormat + +`'Hexadecimal' | 'Solana' | undefined` + +The format for the exported private key. + +- `'Hexadecimal'` — Standard hex-encoded private key (default) +- `'Solana'` — Solana-compatible key format + +### connector + +`Connector | undefined` + +The Wagmi connector to export the key for. If omitted, uses the currently active connector. + +## Return Types + +[TanStack Query mutation docs](https://tanstack.com/query/v5/docs/react/reference/useMutation) + +### mutate + +`(variables: { iframeContainerId: string; iframeStyles?: Record; address?: string; keyFormat?: 'Hexadecimal' | 'Solana'; connector?: Connector }) => void` + +The mutation function to initiate the private key export. Renders a secure iframe containing the private key in the specified container. + +### mutateAsync + +`(variables: { iframeContainerId: string; iframeStyles?: Record; address?: string; keyFormat?: 'Hexadecimal' | 'Solana'; connector?: Connector }) => Promise` + +Similar to [`mutate`](#mutate) but returns a promise. Resolves when the export iframe is rendered. + +### data + +`void` + +This mutation does not return data. The private key is displayed inside the secure iframe. + + diff --git a/docs/pages/wallets/hooks/use-export-wallet.mdx b/docs/pages/wallets/hooks/use-export-wallet.mdx new file mode 100644 index 0000000..60438e3 --- /dev/null +++ b/docs/pages/wallets/hooks/use-export-wallet.mdx @@ -0,0 +1,89 @@ +import MutationResult from '../shared/mutation-result.mdx' + +# useExportWallet [Hook for exporting the wallet seed phrase] + +:::danger[IMPORTANT] +**USE FOR INTERNAL TESTING PURPOSES ONLY.** You may use these features solely for internal evaluation purposes on supported testnets. DO NOT use for production use or share with your users. Wallets created during this preview ("Alpha Wallets") will be discontinued. Any tokens remaining within Alpha Wallets will be permanently lost upon discontinuance. Any mainnet tokens sent to an Alpha Wallet will not be deposited and will be permanently lost when discontinued. We are unable to help recover any lost funds from Alpha Wallets. We provide all previews on an "as is" basis without warranty of any kind, and we may terminate or suspend the availability of any preview at any time. +::: + +## Import + +```tsx +import { useExportWallet } from '@zerodev/wallet-react' +``` + +## Usage + +```tsx +import { useExportWallet } from '@zerodev/wallet-react' + +function ExportSeedPhrase() { + const exportWallet = useExportWallet() + + return ( +
+
+ + +
+ ) +} +``` + +## Parameters + +### iframeContainerId + +`string` + +**Required.** The `id` of the DOM element where the secure export iframe will be rendered. The seed phrase is displayed inside this iframe. + +### iframeStyles + +`Record | undefined` + +Optional CSS styles to apply to the export iframe element. Accepts a dictionary of CSS property names to values. + +### connector + +`Connector | undefined` + +The Wagmi connector to export the wallet for. If omitted, uses the currently active connector. + +## Return Types + +[TanStack Query mutation docs](https://tanstack.com/query/v5/docs/react/reference/useMutation) + +### mutate + +`(variables: { iframeContainerId: string; iframeStyles?: Record; connector?: Connector }) => void` + +The mutation function to initiate the wallet export. Renders a secure iframe containing the seed phrase in the specified container. + +### mutateAsync + +`(variables: { iframeContainerId: string; iframeStyles?: Record; connector?: Connector }) => Promise` + +Similar to [`mutate`](#mutate) but returns a promise. Resolves when the export iframe is rendered. + +### data + +`void` + +This mutation does not return data. The seed phrase is displayed inside the secure iframe. + + diff --git a/docs/pages/wallets/hooks/use-get-user-email.mdx b/docs/pages/wallets/hooks/use-get-user-email.mdx new file mode 100644 index 0000000..6e92cc7 --- /dev/null +++ b/docs/pages/wallets/hooks/use-get-user-email.mdx @@ -0,0 +1,56 @@ +import QueryResult from '../shared/query-result.mdx' + +# useGetUserEmail [Hook for getting the authenticated user's email] + +:::danger[IMPORTANT] +**USE FOR INTERNAL TESTING PURPOSES ONLY.** You may use these features solely for internal evaluation purposes on supported testnets. DO NOT use for production use or share with your users. Wallets created during this preview ("Alpha Wallets") will be discontinued. Any tokens remaining within Alpha Wallets will be permanently lost upon discontinuance. Any mainnet tokens sent to an Alpha Wallet will not be deposited and will be permanently lost when discontinued. We are unable to help recover any lost funds from Alpha Wallets. We provide all previews on an "as is" basis without warranty of any kind, and we may terminate or suspend the availability of any preview at any time. +::: + +## Import + +```tsx +import { useGetUserEmail } from '@zerodev/wallet-react' +``` + +## Usage + +```tsx +import { useGetUserEmail } from '@zerodev/wallet-react' +import { useAccount } from 'wagmi' + +function UserProfile() { + const { isConnected } = useAccount() + const { data: userEmail, isLoading } = useGetUserEmail({}) + + if (!isConnected) return null + + if (isLoading) return

Loading email...

+ + return

Email: {userEmail?.email ?? 'Not available'}

+} +``` + +## Parameters + +```tsx +import { type UseGetUserEmailParameters } from '@zerodev/wallet-react' +``` + +This hook takes an empty object `{}` as its argument. No additional parameters are required. + +## Return Types + +### data + +`{ email: string } | undefined` + +- Defaults to `undefined` +- The authenticated user's email address, if available. + +#### email + +`string` + +The user's email address. This is available when the user authenticated with Email OTP, Magic Link, or Google OAuth. It may not be available for passkey-only authentication. + + diff --git a/docs/pages/wallets/hooks/use-login-passkey.mdx b/docs/pages/wallets/hooks/use-login-passkey.mdx new file mode 100644 index 0000000..dfa734b --- /dev/null +++ b/docs/pages/wallets/hooks/use-login-passkey.mdx @@ -0,0 +1,66 @@ +import MutationResult from '../shared/mutation-result.mdx' + +# useLoginPasskey [Hook for logging in with an existing passkey] + +:::danger[IMPORTANT] +**USE FOR INTERNAL TESTING PURPOSES ONLY.** You may use these features solely for internal evaluation purposes on supported testnets. DO NOT use for production use or share with your users. Wallets created during this preview ("Alpha Wallets") will be discontinued. Any tokens remaining within Alpha Wallets will be permanently lost upon discontinuance. Any mainnet tokens sent to an Alpha Wallet will not be deposited and will be permanently lost when discontinued. We are unable to help recover any lost funds from Alpha Wallets. We provide all previews on an "as is" basis without warranty of any kind, and we may terminate or suspend the availability of any preview at any time. +::: + +## Import + +```tsx +import { useLoginPasskey } from '@zerodev/wallet-react' +``` + +## Usage + +```tsx +import { useLoginPasskey } from '@zerodev/wallet-react' +import { useAccount } from 'wagmi' + +function Login() { + const loginPasskey = useLoginPasskey() + const { address, isConnected } = useAccount() + + if (isConnected) { + return

Logged in: {address}

+ } + + return ( + + ) +} +``` + +## Parameters + +This hook takes no mutation variables. It triggers the browser's WebAuthn prompt to authenticate with an existing passkey. + +## Return Types + +[TanStack Query mutation docs](https://tanstack.com/query/v5/docs/react/reference/useMutation) + +### mutate + +`() => void` + +The mutation function to log in with a passkey. Triggers the WebAuthn browser prompt. + +### mutateAsync + +`() => Promise` + +Similar to [`mutate`](#mutate) but returns a promise. Resolves when the passkey is verified and the wallet is connected. + +### data + +`void` + +This mutation does not return data. On success, the Wagmi connector is connected and the account is available via `useAccount`. + + diff --git a/docs/pages/wallets/hooks/use-refresh-session.mdx b/docs/pages/wallets/hooks/use-refresh-session.mdx new file mode 100644 index 0000000..4262ea2 --- /dev/null +++ b/docs/pages/wallets/hooks/use-refresh-session.mdx @@ -0,0 +1,66 @@ +import MutationResult from '../shared/mutation-result.mdx' + +# useRefreshSession [Hook for manually refreshing the current session] + +:::danger[IMPORTANT] +**USE FOR INTERNAL TESTING PURPOSES ONLY.** You may use these features solely for internal evaluation purposes on supported testnets. DO NOT use for production use or share with your users. Wallets created during this preview ("Alpha Wallets") will be discontinued. Any tokens remaining within Alpha Wallets will be permanently lost upon discontinuance. Any mainnet tokens sent to an Alpha Wallet will not be deposited and will be permanently lost when discontinued. We are unable to help recover any lost funds from Alpha Wallets. We provide all previews on an "as is" basis without warranty of any kind, and we may terminate or suspend the availability of any preview at any time. +::: + +## Import + +```tsx +import { useRefreshSession } from '@zerodev/wallet-react' +``` + +## Usage + +```tsx +import { useRefreshSession } from '@zerodev/wallet-react' + +function SessionControls() { + const refreshSession = useRefreshSession() + + return ( + + ) +} +``` + +## Parameters + +This hook takes an empty object `{}` as its mutation variable. An optional `connector` can be provided if you have multiple connectors configured. + +### connector + +`Connector | undefined` + +The Wagmi connector to refresh the session for. If omitted, uses the currently active connector. + +## Return Types + +[TanStack Query mutation docs](https://tanstack.com/query/v5/docs/react/reference/useMutation) + +### mutate + +`(variables: { connector?: Connector }) => void` + +The mutation function to refresh the session. + +### mutateAsync + +`(variables: { connector?: Connector }) => Promise` + +Similar to [`mutate`](#mutate) but returns a promise. Resolves with the refreshed session data. + +### data + +`unknown` + +The refreshed session data. + + diff --git a/docs/pages/wallets/hooks/use-register-passkey.mdx b/docs/pages/wallets/hooks/use-register-passkey.mdx new file mode 100644 index 0000000..5414421 --- /dev/null +++ b/docs/pages/wallets/hooks/use-register-passkey.mdx @@ -0,0 +1,66 @@ +import MutationResult from '../shared/mutation-result.mdx' + +# useRegisterPasskey [Hook for registering a new passkey wallet] + +:::danger[IMPORTANT] +**USE FOR INTERNAL TESTING PURPOSES ONLY.** You may use these features solely for internal evaluation purposes on supported testnets. DO NOT use for production use or share with your users. Wallets created during this preview ("Alpha Wallets") will be discontinued. Any tokens remaining within Alpha Wallets will be permanently lost upon discontinuance. Any mainnet tokens sent to an Alpha Wallet will not be deposited and will be permanently lost when discontinued. We are unable to help recover any lost funds from Alpha Wallets. We provide all previews on an "as is" basis without warranty of any kind, and we may terminate or suspend the availability of any preview at any time. +::: + +## Import + +```tsx +import { useRegisterPasskey } from '@zerodev/wallet-react' +``` + +## Usage + +```tsx +import { useRegisterPasskey } from '@zerodev/wallet-react' +import { useAccount } from 'wagmi' + +function Register() { + const registerPasskey = useRegisterPasskey() + const { address, isConnected } = useAccount() + + if (isConnected) { + return

Wallet created: {address}

+ } + + return ( + + ) +} +``` + +## Parameters + +This hook takes no mutation variables. It triggers the browser's WebAuthn prompt to create a new passkey. + +## Return Types + +[TanStack Query mutation docs](https://tanstack.com/query/v5/docs/react/reference/useMutation) + +### mutate + +`() => void` + +The mutation function to register a passkey. Triggers the WebAuthn browser prompt. + +### mutateAsync + +`() => Promise` + +Similar to [`mutate`](#mutate) but returns a promise. Resolves when the passkey is registered and the wallet is connected. + +### data + +`void` + +This mutation does not return data. On success, the Wagmi connector is connected and the account is available via `useAccount`. + + diff --git a/docs/pages/wallets/hooks/use-send-magic-link.mdx b/docs/pages/wallets/hooks/use-send-magic-link.mdx new file mode 100644 index 0000000..1d2690b --- /dev/null +++ b/docs/pages/wallets/hooks/use-send-magic-link.mdx @@ -0,0 +1,114 @@ +import MutationResult from '../shared/mutation-result.mdx' + +# useSendMagicLink [Hook for sending a magic link email] + +:::danger[IMPORTANT] +**USE FOR INTERNAL TESTING PURPOSES ONLY.** You may use these features solely for internal evaluation purposes on supported testnets. DO NOT use for production use or share with your users. Wallets created during this preview ("Alpha Wallets") will be discontinued. Any tokens remaining within Alpha Wallets will be permanently lost upon discontinuance. Any mainnet tokens sent to an Alpha Wallet will not be deposited and will be permanently lost when discontinued. We are unable to help recover any lost funds from Alpha Wallets. We provide all previews on an "as is" basis without warranty of any kind, and we may terminate or suspend the availability of any preview at any time. +::: + +## Import + +```tsx +import { useSendMagicLink } from '@zerodev/wallet-react' +``` + +## Usage + +```tsx +import { useState } from 'react' +import { useSendMagicLink } from '@zerodev/wallet-react' + +function SendMagicLink() { + const [email, setEmail] = useState('') + const sendMagicLink = useSendMagicLink() + + return ( +
+ setEmail(e.target.value)} + placeholder="Enter your email" + /> + + + {sendMagicLink.isSuccess &&

Check your email!

} +
+ ) +} +``` + +## Parameters + +### email + +`string` + +**Required.** The email address to send the magic link to. + +### redirectURL + +`string` + +**Required.** The URL the user will be redirected to after clicking the magic link. This should be a page in your app that calls [`useVerifyMagicLink`](/wallets/hooks/use-verify-magic-link). + +### otpCodeCustomization + +`{ length?: 6 | 7 | 8 | 9; alphanumeric?: boolean } | undefined` + +Optional customization for the generated verification code. + +#### length + +`6 | 7 | 8 | 9 | undefined` + +The number of characters in the code. Defaults to `6`. + +#### alphanumeric + +`boolean | undefined` + +Whether to use alphanumeric characters instead of digits only. Defaults to `false`. + +## Return Types + +[TanStack Query mutation docs](https://tanstack.com/query/v5/docs/react/reference/useMutation) + +### mutate + +`(variables: { email: string; redirectURL: string }) => void` + +The mutation function to send the magic link. + +### mutateAsync + +`(variables: { email: string; redirectURL: string }) => Promise<{ otpId: string }>` + +Similar to [`mutate`](#mutate) but returns a promise. + +### data + +`{ otpId: string } | undefined` + +- Defaults to `undefined` +- The data returned from the mutation on success. + +#### otpId + +`string` + +The identifier for this magic link verification. Store this value and pass it to [`useVerifyMagicLink`](/wallets/hooks/use-verify-magic-link) on the redirect page. + + diff --git a/docs/pages/wallets/hooks/use-send-otp.mdx b/docs/pages/wallets/hooks/use-send-otp.mdx new file mode 100644 index 0000000..ffb2fb1 --- /dev/null +++ b/docs/pages/wallets/hooks/use-send-otp.mdx @@ -0,0 +1,115 @@ +import MutationResult from '../shared/mutation-result.mdx' + +# useSendOTP [Hook for sending a one-time verification code] + +:::danger[IMPORTANT] +**USE FOR INTERNAL TESTING PURPOSES ONLY.** You may use these features solely for internal evaluation purposes on supported testnets. DO NOT use for production use or share with your users. Wallets created during this preview ("Alpha Wallets") will be discontinued. Any tokens remaining within Alpha Wallets will be permanently lost upon discontinuance. Any mainnet tokens sent to an Alpha Wallet will not be deposited and will be permanently lost when discontinued. We are unable to help recover any lost funds from Alpha Wallets. We provide all previews on an "as is" basis without warranty of any kind, and we may terminate or suspend the availability of any preview at any time. +::: + +## Import + +```tsx +import { useSendOTP } from '@zerodev/wallet-react' +``` + +## Usage + +```tsx +import { useState } from 'react' +import { useSendOTP } from '@zerodev/wallet-react' + +function SendCode() { + const [email, setEmail] = useState('') + const sendOTP = useSendOTP() + + return ( +
+ setEmail(e.target.value)} + placeholder="Enter your email" + /> + +
+ ) +} +``` + +## Parameters + +### email + +`string` + +**Required.** The email address to send the verification code to. + +### emailCustomization + +`{ magicLinkTemplate?: string } | undefined` + +Optional email customization options. + +#### magicLinkTemplate + +`string | undefined` + +Custom template for the email content. + +### otpCodeCustomization + +`{ length?: 6 | 7 | 8 | 9; alphanumeric?: boolean } | undefined` + +Optional customization for the generated OTP code. + +#### length + +`6 | 7 | 8 | 9 | undefined` + +The number of characters in the OTP code. Defaults to `6`. + +#### alphanumeric + +`boolean | undefined` + +Whether to use alphanumeric characters instead of digits only. Defaults to `false`. + +## Return Types + +[TanStack Query mutation docs](https://tanstack.com/query/v5/docs/react/reference/useMutation) + +### mutate + +`(variables: { email: string; emailCustomization?: { magicLinkTemplate?: string } }) => void` + +The mutation function to send the OTP. + +### mutateAsync + +`(variables: { email: string; emailCustomization?: { magicLinkTemplate?: string } }) => Promise<{ otpId: string }>` + +Similar to [`mutate`](#mutate) but returns a promise. + +### data + +`{ otpId: string } | undefined` + +- Defaults to `undefined` +- The data returned from the mutation on success. + +#### otpId + +`string` + +The identifier for this OTP verification attempt. Pass this to [`useVerifyOTP`](/wallets/hooks/use-verify-otp) to complete authentication. + + diff --git a/docs/pages/wallets/hooks/use-verify-magic-link.mdx b/docs/pages/wallets/hooks/use-verify-magic-link.mdx new file mode 100644 index 0000000..5810d1b --- /dev/null +++ b/docs/pages/wallets/hooks/use-verify-magic-link.mdx @@ -0,0 +1,81 @@ +import MutationResult from '../shared/mutation-result.mdx' + +# useVerifyMagicLink [Hook for verifying a magic link and authenticating] + +:::danger[IMPORTANT] +**USE FOR INTERNAL TESTING PURPOSES ONLY.** You may use these features solely for internal evaluation purposes on supported testnets. DO NOT use for production use or share with your users. Wallets created during this preview ("Alpha Wallets") will be discontinued. Any tokens remaining within Alpha Wallets will be permanently lost upon discontinuance. Any mainnet tokens sent to an Alpha Wallet will not be deposited and will be permanently lost when discontinued. We are unable to help recover any lost funds from Alpha Wallets. We provide all previews on an "as is" basis without warranty of any kind, and we may terminate or suspend the availability of any preview at any time. +::: + +## Import + +```tsx +import { useVerifyMagicLink } from '@zerodev/wallet-react' +``` + +## Usage + +```tsx +import { useEffect } from 'react' +import { useSearchParams } from 'next/navigation' +import { useAccount } from 'wagmi' +import { useVerifyMagicLink } from '@zerodev/wallet-react' + +function VerifyPage() { + const searchParams = useSearchParams() + const verifyMagicLink = useVerifyMagicLink() + const { address, isConnected } = useAccount() + + useEffect(() => { + const code = searchParams.get('code') + const otpId = sessionStorage.getItem('magicLinkOtpId') + + if (code && otpId && !isConnected) { + verifyMagicLink.mutateAsync({ otpId, code }) + } + }, [searchParams]) + + if (isConnected) return

Authenticated: {address}

+ if (verifyMagicLink.isPending) return

Verifying...

+ if (verifyMagicLink.isError) return

Error: {verifyMagicLink.error.message}

+ + return

Waiting for verification...

+} +``` + +## Parameters + +### otpId + +`string` + +**Required.** The OTP identifier returned by [`useSendMagicLink`](/wallets/hooks/use-send-magic-link). + +### code + +`string` + +**Required.** The verification code from the magic link URL query parameters. + +## Return Types + +[TanStack Query mutation docs](https://tanstack.com/query/v5/docs/react/reference/useMutation) + +### mutate + +`(variables: { otpId: string; code: string }) => void` + +The mutation function to verify the magic link. + +### mutateAsync + +`(variables: { otpId: string; code: string }) => Promise` + +Similar to [`mutate`](#mutate) but returns a promise. Resolves when the magic link is verified and the wallet is connected. + +### data + +`void` + +This mutation does not return data. On success, the Wagmi connector is connected and the account is available via `useAccount`. + + diff --git a/docs/pages/wallets/hooks/use-verify-otp.mdx b/docs/pages/wallets/hooks/use-verify-otp.mdx new file mode 100644 index 0000000..4ee8832 --- /dev/null +++ b/docs/pages/wallets/hooks/use-verify-otp.mdx @@ -0,0 +1,87 @@ +import MutationResult from '../shared/mutation-result.mdx' + +# useVerifyOTP [Hook for verifying a one-time code and authenticating] + +:::danger[IMPORTANT] +**USE FOR INTERNAL TESTING PURPOSES ONLY.** You may use these features solely for internal evaluation purposes on supported testnets. DO NOT use for production use or share with your users. Wallets created during this preview ("Alpha Wallets") will be discontinued. Any tokens remaining within Alpha Wallets will be permanently lost upon discontinuance. Any mainnet tokens sent to an Alpha Wallet will not be deposited and will be permanently lost when discontinued. We are unable to help recover any lost funds from Alpha Wallets. We provide all previews on an "as is" basis without warranty of any kind, and we may terminate or suspend the availability of any preview at any time. +::: + +## Import + +```tsx +import { useVerifyOTP } from '@zerodev/wallet-react' +``` + +## Usage + +```tsx +import { useState } from 'react' +import { useVerifyOTP } from '@zerodev/wallet-react' +import { useAccount } from 'wagmi' + +function VerifyCode({ otpId }: { otpId: string }) { + const [code, setCode] = useState('') + const verifyOTP = useVerifyOTP() + const { address, isConnected } = useAccount() + + if (isConnected) { + return

Authenticated: {address}

+ } + + return ( +
+ setCode(e.target.value)} + placeholder="Enter verification code" + /> + + {verifyOTP.isError &&

Error: {verifyOTP.error.message}

} +
+ ) +} +``` + +## Parameters + +### code + +`string` + +**Required.** The verification code entered by the user. + +### otpId + +`string` + +**Required.** The OTP identifier returned by [`useSendOTP`](/wallets/hooks/use-send-otp). + +## Return Types + +[TanStack Query mutation docs](https://tanstack.com/query/v5/docs/react/reference/useMutation) + +### mutate + +`(variables: { code: string; otpId: string }) => void` + +The mutation function to verify the OTP. + +### mutateAsync + +`(variables: { code: string; otpId: string }) => Promise` + +Similar to [`mutate`](#mutate) but returns a promise. Resolves when the code is verified and the wallet is connected. + +### data + +`void` + +This mutation does not return data. On success, the Wagmi connector is connected and the account is available via `useAccount`. + + diff --git a/docs/pages/wallets/index.mdx b/docs/pages/wallets/index.mdx new file mode 100644 index 0000000..a870dcc --- /dev/null +++ b/docs/pages/wallets/index.mdx @@ -0,0 +1,53 @@ +# ZeroDev Wallet SDK [Embedded wallet authentication for your app] + +:::danger[IMPORTANT] +**USE FOR INTERNAL TESTING PURPOSES ONLY.** You may use these features solely for internal evaluation purposes on supported testnets. DO NOT use for production use or share with your users. Wallets created during this preview ("Alpha Wallets") will be discontinued. Any tokens remaining within Alpha Wallets will be permanently lost upon discontinuance. Any mainnet tokens sent to an Alpha Wallet will not be deposited and will be permanently lost when discontinued. We are unable to help recover any lost funds from Alpha Wallets. We provide all previews on an "as is" basis without warranty of any kind, and we may terminate or suspend the availability of any preview at any time. +::: + +ZeroDev Wallet SDK provides embedded wallet authentication with multiple auth methods, EIP-7702 smart accounts, and seamless Wagmi integration. Users get a self-custodial smart account without needing to manage seed phrases or gas. + +## Key Features + +- **Multiple auth methods** — Passkeys, Email OTP, Magic Links, and Google OAuth +- **EIP-7702 smart accounts** — EOA wallets upgraded with smart account capabilities (gas sponsorship, batch transactions) +- **Wagmi integration** — Drop-in connector that works with standard Wagmi hooks +- **Session management** — Automatic session persistence, refresh, and expiry handling +- **Wallet export** — Users can export their seed phrase or private key at any time + +## Packages + +The SDK is split into two packages: + +| Package | Description | +|---------|-------------| +| `@zerodev/wallet-core` | Framework-agnostic core SDK. Handles authentication, session management, and key operations. | +| `@zerodev/wallet-react` | React hooks and Wagmi connector built on TanStack Query. | + +For React apps, install `@zerodev/wallet-react` — it re-exports everything from `@zerodev/wallet-core`. + +## Architecture + +``` +┌─────────────────────────────────────────────┐ +│ Your App │ +│ (Wagmi hooks / React hooks) │ +├─────────────────────────────────────────────┤ +│ @zerodev/wallet-react │ +│ (Wagmi connector + TanStack Query) │ +├─────────────────────────────────────────────┤ +│ @zerodev/wallet-core │ +│ (Auth, Sessions, Key operations) │ +├─────────────────────────────────────────────┤ +│ Secure Key Infrastructure │ +│ (Keys in secure enclaves) │ +├─────────────────────────────────────────────┤ +│ EIP-7702 EOA │ +│ (Delegates to Kernel smart account) │ +└─────────────────────────────────────────────┘ +``` + +Authentication creates a session backed by secure key infrastructure. The SDK uses that session to sign transactions through an EOA that delegates to a Kernel smart account via EIP-7702, enabling gas sponsorship and batch transactions. + +## Next Steps + +Head to the [Quickstart](/wallets/quickstart) to set up your first integration. diff --git a/docs/pages/wallets/quickstart.mdx b/docs/pages/wallets/quickstart.mdx new file mode 100644 index 0000000..16c7137 --- /dev/null +++ b/docs/pages/wallets/quickstart.mdx @@ -0,0 +1,128 @@ +# Quickstart [Get up and running in 5 minutes] + +:::danger[IMPORTANT] +**USE FOR INTERNAL TESTING PURPOSES ONLY.** You may use these features solely for internal evaluation purposes on supported testnets. DO NOT use for production use or share with your users. Wallets created during this preview ("Alpha Wallets") will be discontinued. Any tokens remaining within Alpha Wallets will be permanently lost upon discontinuance. Any mainnet tokens sent to an Alpha Wallet will not be deposited and will be permanently lost when discontinued. We are unable to help recover any lost funds from Alpha Wallets. We provide all previews on an "as is" basis without warranty of any kind, and we may terminate or suspend the availability of any preview at any time. +::: + +## Installation + +:::code-group + +```bash [npm] +npm i @zerodev/wallet-react @zerodev/sdk wagmi viem @tanstack/react-query +``` + +```bash [yarn] +yarn add @zerodev/wallet-react @zerodev/sdk wagmi viem @tanstack/react-query +``` + +```bash [pnpm] +pnpm i @zerodev/wallet-react @zerodev/sdk wagmi viem @tanstack/react-query +``` + +```bash [bun] +bun add @zerodev/wallet-react @zerodev/sdk wagmi viem @tanstack/react-query +``` + +::: + +## 1. Configure Wagmi + +Create a Wagmi config with the `zeroDevWallet` connector: + +```tsx +import { createConfig, http } from 'wagmi' +import { sepolia } from 'wagmi/chains' +import { zeroDevWallet } from '@zerodev/wallet-react' + +export const config = createConfig({ + chains: [sepolia], + connectors: [ + zeroDevWallet({ + projectId: 'YOUR_ZERODEV_PROJECT_ID', + chains: [sepolia], + }), + ], + transports: { + [sepolia.id]: http(), + }, +}) +``` + +Get your project ID from the [ZeroDev Dashboard](https://dashboard.zerodev.app/). + +## 2. Wrap your app + +Wrap your application with `WagmiProvider` and `QueryClientProvider`: + +```tsx +import { WagmiProvider } from 'wagmi' +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { config } from './wagmi-config' + +const queryClient = new QueryClient() + +export default function App({ children }: { children: React.ReactNode }) { + return ( + + + {children} + + + ) +} +``` + +## 3. Add authentication + +Here's a basic example with passkey registration and login: + +```tsx +import { useAccount, useDisconnect } from 'wagmi' +import { useRegisterPasskey, useLoginPasskey } from '@zerodev/wallet-react' + +function AuthPage() { + const { address, isConnected } = useAccount() + const { disconnectAsync } = useDisconnect() + const registerPasskey = useRegisterPasskey() + const loginPasskey = useLoginPasskey() + + if (isConnected) { + return ( +
+

Connected: {address}

+ +
+ ) + } + + return ( +
+ + + +
+ ) +} +``` + +After authentication, the user's wallet is available through standard Wagmi hooks like `useAccount`, `useSendTransaction`, and `useSignMessage`. + +## Next Steps + +- [Passkey Authentication](/wallets/auth/passkeys) — Full passkey guide +- [Email OTP](/wallets/auth/email-otp) — Authenticate with email codes +- [Google OAuth](/wallets/auth/google-oauth) — Social login with Google +- [Session Management](/wallets/session-management) — Session lifecycle and refresh diff --git a/docs/pages/wallets/session-management.mdx b/docs/pages/wallets/session-management.mdx new file mode 100644 index 0000000..34c02ff --- /dev/null +++ b/docs/pages/wallets/session-management.mdx @@ -0,0 +1,101 @@ +# Session Management [Understand and control the session lifecycle] + +:::danger[IMPORTANT] +**USE FOR INTERNAL TESTING PURPOSES ONLY.** You may use these features solely for internal evaluation purposes on supported testnets. DO NOT use for production use or share with your users. Wallets created during this preview ("Alpha Wallets") will be discontinued. Any tokens remaining within Alpha Wallets will be permanently lost upon discontinuance. Any mainnet tokens sent to an Alpha Wallet will not be deposited and will be permanently lost when discontinued. We are unable to help recover any lost funds from Alpha Wallets. We provide all previews on an "as is" basis without warranty of any kind, and we may terminate or suspend the availability of any preview at any time. +::: + +The ZeroDev Wallet SDK manages sessions automatically. Sessions are created during authentication and persist across page reloads. + +## Session lifecycle + +``` +Authenticate → Session Created → Auto-refresh → Expiry → Re-authenticate +``` + +1. **Created**: A session is created when the user authenticates (passkey, OTP, OAuth, or magic link). The session contains a credential that allows the SDK to sign transactions. + +2. **Persisted**: Sessions are stored in `localStorage` by default (configurable via `sessionStorage` connector option). On page reload, the connector checks for an existing session and reconnects automatically. + +3. **Auto-refresh**: When `autoRefreshSession` is enabled (default), the SDK refreshes the session before it expires. The refresh happens `sessionWarningThreshold` milliseconds before expiry (default: 60 seconds). + +4. **Expiry**: If a session expires without being refreshed, the Wagmi connector disconnects and the user needs to re-authenticate. + +## Refreshing sessions + +Use the [`useRefreshSession`](/wallets/hooks/use-refresh-session) hook to manually refresh the current session: + +```tsx +import { useRefreshSession } from '@zerodev/wallet-react' + +function SessionControls() { + const refreshSession = useRefreshSession() + + return ( + + ) +} +``` + +## Auto-refresh configuration + +Configure auto-refresh via the connector options: + +```tsx +zeroDevWallet({ + projectId: 'YOUR_PROJECT_ID', + chains: [sepolia], + autoRefreshSession: true, // default: true + sessionWarningThreshold: 120_000, // refresh 2 minutes before expiry +}) +``` + +Set `autoRefreshSession: false` to disable auto-refresh and handle session expiry manually. + +## Custom storage + +By default, sessions are stored in `localStorage`. Provide a custom `StorageAdapter` for alternative storage: + +```tsx +import { type StorageAdapter } from '@zerodev/wallet-core' + +const customStorage: StorageAdapter = { + getItem: async (key: string) => { /* ... */ }, + setItem: async (key: string, value: string) => { /* ... */ }, + removeItem: async (key: string) => { /* ... */ }, +} + +zeroDevWallet({ + projectId: 'YOUR_PROJECT_ID', + chains: [sepolia], + sessionStorage: customStorage, +}) +``` + +This is useful for React Native apps where `localStorage` is not available. + +## Detecting session expiry + +When a session expires, the Wagmi connector disconnects. You can detect this using the Wagmi `useAccount` hook: + +```tsx +import { useAccount } from 'wagmi' + +function SessionStatus() { + const { status, isConnected } = useAccount() + + if (status === 'disconnected') { + return

Session expired — please sign in again

+ } + + if (isConnected) { + return

Connected

+ } + + return null +} +``` diff --git a/docs/pages/wallets/shared/mutation-result.mdx b/docs/pages/wallets/shared/mutation-result.mdx new file mode 100644 index 0000000..7b4da79 --- /dev/null +++ b/docs/pages/wallets/shared/mutation-result.mdx @@ -0,0 +1,33 @@ +### error + +`Error | null` + +The error object for the mutation, if an error was encountered. + +### isError / isIdle / isPending / isSuccess + +`boolean` + +Boolean variables derived from [`status`](#status). + +### isPaused + +`boolean` + +- will be `true` if the mutation has been `paused`. +- see [Network Mode](https://tanstack.com/query/v5/docs/react/guides/network-mode) for more information. + +### status + +`'idle' | 'pending' | 'error' | 'success'` + +- `'idle'` initial status prior to the mutation function executing. +- `'pending'` if the mutation is currently executing. +- `'error'` if the last mutation attempt resulted in an error. +- `'success'` if the last mutation attempt was successful. + +### reset + +`() => void` + +A function to clean the mutation internal state (e.g. it resets the mutation to its initial state). diff --git a/docs/pages/wallets/shared/query-result.mdx b/docs/pages/wallets/shared/query-result.mdx new file mode 100644 index 0000000..d1297c4 --- /dev/null +++ b/docs/pages/wallets/shared/query-result.mdx @@ -0,0 +1,46 @@ +### error + +`Error | null` + +- The error object for the query, if an error was thrown. +- Defaults to `null` + +### isError / isPending / isSuccess + +`boolean` + +Boolean variables derived from [`status`](#status). + +### isFetched + +`boolean` + +Will be `true` if the query has been fetched. + +### isLoading + +`boolean` + +- Is `true` whenever the first fetch for a query is in-flight +- Is the same as `isFetching && isPending` + +### status + +`'error' | 'pending' | 'success'` + +- `pending` if there's no cached data and no query attempt was finished yet. +- `error` if the query attempt resulted in an error. The corresponding `error` property has the error received from the attempted fetch +- `success` if the query has received a response with no errors and is ready to display its data. The corresponding `data` property on the query is the data received from the successful fetch or if the query's `enabled` property is set to `false` and has not been fetched yet `data` is the first `initialData` supplied to the query on initialization. + +### refetch + +`(options: { cancelRefetch?: boolean | undefined; throwOnError?: boolean | undefined }) => Promise` + +- A function to manually refetch the query. +- `throwOnError` + - When set to `true`, an error will be thrown if the query fails. + - When set to `false`, an error will be logged if the query fails. +- `cancelRefetch` + - When set to `true`, a currently running request will be cancelled before a new request is made. + - When set to `false`, no refetch will be made if there is already a request running. + - Defaults to `true` diff --git a/vocs.config.tsx b/vocs.config.tsx index fa7ff51..4a439be 100644 --- a/vocs.config.tsx +++ b/vocs.config.tsx @@ -821,6 +821,108 @@ export default defineConfig({ ], }, ], + "/wallets": [ + { + text: "Getting Started", + collapsed: false, + items: [ + { + text: "Introduction", + link: "/wallets", + }, + { + text: "Quickstart", + link: "/wallets/quickstart", + }, + ], + }, + { + text: "Authentication", + collapsed: false, + items: [ + { + text: "Passkeys", + link: "/wallets/auth/passkeys", + }, + { + text: "Email OTP", + link: "/wallets/auth/email-otp", + }, + { + text: "Magic Link", + link: "/wallets/auth/magic-link", + }, + { + text: "Google OAuth", + link: "/wallets/auth/google-oauth", + }, + ], + }, + { + text: "Features", + collapsed: false, + items: [ + { + text: "Session Management", + link: "/wallets/session-management", + }, + { + text: "Export Wallet", + link: "/wallets/export", + }, + ], + }, + { + text: "Hooks", + collapsed: false, + items: [ + { + text: "useRegisterPasskey", + link: "/wallets/hooks/use-register-passkey", + }, + { + text: "useLoginPasskey", + link: "/wallets/hooks/use-login-passkey", + }, + { + text: "useAuthenticateOAuth", + link: "/wallets/hooks/use-authenticate-oauth", + }, + { + text: "useSendOTP", + link: "/wallets/hooks/use-send-otp", + }, + { + text: "useVerifyOTP", + link: "/wallets/hooks/use-verify-otp", + }, + { + text: "useSendMagicLink", + link: "/wallets/hooks/use-send-magic-link", + }, + { + text: "useVerifyMagicLink", + link: "/wallets/hooks/use-verify-magic-link", + }, + { + text: "useGetUserEmail", + link: "/wallets/hooks/use-get-user-email", + }, + { + text: "useRefreshSession", + link: "/wallets/hooks/use-refresh-session", + }, + { + text: "useExportWallet", + link: "/wallets/hooks/use-export-wallet", + }, + { + text: "useExportPrivateKey", + link: "/wallets/hooks/use-export-private-key", + }, + ], + }, + ], "/react": [ { text: "Getting Started", From 2dbad8479ab149aa2e0e6c84fc43d95f5070a79a Mon Sep 17 00:00:00 2001 From: Sahil Vasava Date: Thu, 26 Feb 2026 15:42:25 -0300 Subject: [PATCH 2/3] Merge Derek's wallet docs content into wallet-docs-updates - Replace intro page with Derek's version (smart by default, TEE + smart accounts, SDK comparison) - Add Wallet API section with send-transaction, sign-message, and sign-typed-message pages - Add rpId configuration section to passkeys page - Add Demo link and Wallet API sidebar section - Add next steps links to quickstart pointing to new wallet API pages --- docs/pages/wallets/auth/passkeys.mdx | 13 +++- docs/pages/wallets/index.mdx | 58 ++++++-------- docs/pages/wallets/quickstart.mdx | 2 + .../wallets/wallet-api/send-transaction.mdx | 75 +++++++++++++++++++ .../pages/wallets/wallet-api/sign-message.mdx | 31 ++++++++ .../wallets/wallet-api/sign-typed-message.mdx | 60 +++++++++++++++ vocs.config.tsx | 22 ++++++ 7 files changed, 223 insertions(+), 38 deletions(-) create mode 100644 docs/pages/wallets/wallet-api/send-transaction.mdx create mode 100644 docs/pages/wallets/wallet-api/sign-message.mdx create mode 100644 docs/pages/wallets/wallet-api/sign-typed-message.mdx diff --git a/docs/pages/wallets/auth/passkeys.mdx b/docs/pages/wallets/auth/passkeys.mdx index 84cbc69..2e9c525 100644 --- a/docs/pages/wallets/auth/passkeys.mdx +++ b/docs/pages/wallets/auth/passkeys.mdx @@ -6,6 +6,18 @@ Passkeys use the [WebAuthn](https://webauthn.guide/) standard for passwordless authentication. Users authenticate with biometrics (Face ID, Touch ID, fingerprint) or a hardware security key. +## Configure RP ID (optional) + +Set `rpId` on the connector if you need a custom [relying party identifier](https://www.w3.org/TR/webauthn-2/#relying-party-identifier) (defaults to the current hostname): + +```ts +zeroDevWallet({ + projectId: process.env.NEXT_PUBLIC_ZERODEV_PROJECT_ID!, + chains: [sepolia], + rpId: "example.com", +}); +``` + ## Hooks - [`useRegisterPasskey`](/wallets/hooks/use-register-passkey) — Create a new wallet with a passkey @@ -72,4 +84,3 @@ After either flow, the Wagmi connector is connected and the user's address is av - No email is required for passkey auth — the passkey itself is the credential - Passkeys are supported in all major browsers (Chrome, Safari, Firefox, Edge) - Passkeys can sync across devices via iCloud Keychain, Google Password Manager, etc. -- The `rpId` connector option controls the WebAuthn relying party ID (defaults to the current hostname) diff --git a/docs/pages/wallets/index.mdx b/docs/pages/wallets/index.mdx index a870dcc..ab55c2f 100644 --- a/docs/pages/wallets/index.mdx +++ b/docs/pages/wallets/index.mdx @@ -1,53 +1,37 @@ -# ZeroDev Wallet SDK [Embedded wallet authentication for your app] +# ZeroDev Wallet [Smart embedded wallet for your app] :::danger[IMPORTANT] **USE FOR INTERNAL TESTING PURPOSES ONLY.** You may use these features solely for internal evaluation purposes on supported testnets. DO NOT use for production use or share with your users. Wallets created during this preview ("Alpha Wallets") will be discontinued. Any tokens remaining within Alpha Wallets will be permanently lost upon discontinuance. Any mainnet tokens sent to an Alpha Wallet will not be deposited and will be permanently lost when discontinued. We are unable to help recover any lost funds from Alpha Wallets. We provide all previews on an "as is" basis without warranty of any kind, and we may terminate or suspend the availability of any preview at any time. ::: -ZeroDev Wallet SDK provides embedded wallet authentication with multiple auth methods, EIP-7702 smart accounts, and seamless Wagmi integration. Users get a self-custodial smart account without needing to manage seed phrases or gas. +ZeroDev Wallet is the first **smart embedded wallet** -- an embedded wallet optimized for smart accounts. -## Key Features +## Demo -- **Multiple auth methods** — Passkeys, Email OTP, Magic Links, and Google OAuth -- **EIP-7702 smart accounts** — EOA wallets upgraded with smart account capabilities (gas sponsorship, batch transactions) -- **Wagmi integration** — Drop-in connector that works with standard Wagmi hooks -- **Session management** — Automatic session persistence, refresh, and expiry handling -- **Wallet export** — Users can export their seed phrase or private key at any time +Check out [this demo](https://zerodev-signer-demo.vercel.app/) for a self-custodial wallet powered by social logins and gas sponsorship. -## Packages +## Why ZeroDev Wallet -The SDK is split into two packages: +### Smart by Default -| Package | Description | -|---------|-------------| -| `@zerodev/wallet-core` | Framework-agnostic core SDK. Handles authentication, session management, and key operations. | -| `@zerodev/wallet-react` | React hooks and Wagmi connector built on TanStack Query. | +Most embedded wallets use EOAs by default, and only support smart accounts as a secondary option. On the other hand, ZeroDev Wallet uses smart accounts *by default* through EIP-7702 and ERC-4337. -For React apps, install `@zerodev/wallet-react` — it re-exports everything from `@zerodev/wallet-core`. +As a result, smart account features such as gas sponsorship, transaction batching, transaction automation, and chain abstraction are available as native APIs with ZeroDev Wallet, while other embedded wallets typically only support a subset of these features. -## Architecture +### Get the best of on-chain & off-chain -``` -┌─────────────────────────────────────────────┐ -│ Your App │ -│ (Wagmi hooks / React hooks) │ -├─────────────────────────────────────────────┤ -│ @zerodev/wallet-react │ -│ (Wagmi connector + TanStack Query) │ -├─────────────────────────────────────────────┤ -│ @zerodev/wallet-core │ -│ (Auth, Sessions, Key operations) │ -├─────────────────────────────────────────────┤ -│ Secure Key Infrastructure │ -│ (Keys in secure enclaves) │ -├─────────────────────────────────────────────┤ -│ EIP-7702 EOA │ -│ (Delegates to Kernel smart account) │ -└─────────────────────────────────────────────┘ -``` +ZeroDev Wallet combines the best of off-chain and on-chain tech: TEE (trusted execution environment) for off-chain key management, and smart accounts for on-chain account management. This enables ZeroDev wallet to offer powerful wallet features that are difficult if not impossible with other solutions, including: -Authentication creates a session backed by secure key infrastructure. The SDK uses that session to sign transactions through an EOA that delegates to a Kernel smart account via EIP-7702, enabling gas sponsorship and batch transactions. +- A hybrid on-chain / off-chain policy engine +- Resource-lock chain abstraction +- Fully counterfactual session keys -## Next Steps +## ZeroDev Wallet vs ZeroDev SDK -Head to the [Quickstart](/wallets/quickstart) to set up your first integration. +[ZeroDev SDK](/) is a *smart account SDK* that can be used to create smart accounts from any key management system of your choice, including local private keys and other WaaS solutions such as Privy, Dynamic, and Turnkey. + +On the other hand, ZeroDev Wallet is a complete embedded wallet solution that bundles key management with smart accounts. + +## Getting Started + +Check out [the quickstart](/wallets/quickstart) to get started! diff --git a/docs/pages/wallets/quickstart.mdx b/docs/pages/wallets/quickstart.mdx index 16c7137..b1c1f17 100644 --- a/docs/pages/wallets/quickstart.mdx +++ b/docs/pages/wallets/quickstart.mdx @@ -125,4 +125,6 @@ After authentication, the user's wallet is available through standard Wagmi hook - [Passkey Authentication](/wallets/auth/passkeys) — Full passkey guide - [Email OTP](/wallets/auth/email-otp) — Authenticate with email codes - [Google OAuth](/wallets/auth/google-oauth) — Social login with Google +- [Send Transactions](/wallets/wallet-api/send-transaction) — Send gasless transactions +- [Sign Messages](/wallets/wallet-api/sign-message) — Sign messages with the wallet - [Session Management](/wallets/session-management) — Session lifecycle and refresh diff --git a/docs/pages/wallets/wallet-api/send-transaction.mdx b/docs/pages/wallets/wallet-api/send-transaction.mdx new file mode 100644 index 0000000..e77368a --- /dev/null +++ b/docs/pages/wallets/wallet-api/send-transaction.mdx @@ -0,0 +1,75 @@ +# Send a Transaction [Gasless transactions with Wagmi hooks] + +:::danger[IMPORTANT] +**USE FOR INTERNAL TESTING PURPOSES ONLY.** You may use these features solely for internal evaluation purposes on supported testnets. DO NOT use for production use or share with your users. Wallets created during this preview ("Alpha Wallets") will be discontinued. Any tokens remaining within Alpha Wallets will be permanently lost upon discontinuance. Any mainnet tokens sent to an Alpha Wallet will not be deposited and will be permanently lost when discontinued. We are unable to help recover any lost funds from Alpha Wallets. We provide all previews on an "as is" basis without warranty of any kind, and we may terminate or suspend the availability of any preview at any time. +::: + +Use standard Wagmi hooks to send transactions. The ZeroDev connector turns transactions into user operations (AA transactions) behind the scenes, achieving gas abstraction automatically so long as you have enabled it on the ZeroDev dashboard. + +## `useSendTransaction` + +```tsx +import { useState } from "react"; +import { parseEther } from "viem"; +import { useAccount, useSendTransaction } from "wagmi"; + +export function SendEth() { + const { address, isConnected } = useAccount(); + const { sendTransaction, data, isPending } = useSendTransaction(); + const [to, setTo] = useState("0x..."); + const [amount, setAmount] = useState("0.001"); + + const handleSend = () => { + if (!isConnected) return; + sendTransaction({ + to, + value: parseEther(amount), + }); + }; + + return ( +
+

From: {address}

+ setTo(e.target.value)} /> + setAmount(e.target.value)} /> + + {data &&

Tx hash: {data}

} +
+ ); +} +``` + +## `useWriteContract` + +```tsx +import { useWriteContract } from "wagmi"; +import { parseAbi } from "viem"; + +const NFT_ABI = parseAbi([ + "function mint(address _to) public", +]); + +export function MintNftGasless({ recipient }: { recipient: `0x${string}` }) { + const { writeContract, data, isPending, error } = useWriteContract(); + + const mint = () => + writeContract({ + address: "0xYourNftAddress", + abi: NFT_ABI, + functionName: "mint", + args: [recipient], + }); + + return ( +
+ + {data &&

Tx hash: {data}

} + {error &&

Mint failed: {error.message}

} +
+ ); +} +``` diff --git a/docs/pages/wallets/wallet-api/sign-message.mdx b/docs/pages/wallets/wallet-api/sign-message.mdx new file mode 100644 index 0000000..c053948 --- /dev/null +++ b/docs/pages/wallets/wallet-api/sign-message.mdx @@ -0,0 +1,31 @@ +# Sign a Message [Sign messages with Wagmi hooks] + +:::danger[IMPORTANT] +**USE FOR INTERNAL TESTING PURPOSES ONLY.** You may use these features solely for internal evaluation purposes on supported testnets. DO NOT use for production use or share with your users. Wallets created during this preview ("Alpha Wallets") will be discontinued. Any tokens remaining within Alpha Wallets will be permanently lost upon discontinuance. Any mainnet tokens sent to an Alpha Wallet will not be deposited and will be permanently lost when discontinued. We are unable to help recover any lost funds from Alpha Wallets. We provide all previews on an "as is" basis without warranty of any kind, and we may terminate or suspend the availability of any preview at any time. +::: + +To sign a message, use Wagmi's `useSignMessage` hook: + +```tsx +import { useSignMessage } from "wagmi"; + +export function SignMessage() { + const { signMessage, data, isPending, error } = useSignMessage(); + + const handleSign = () => + signMessage({ + message: "Hello from ZeroDev Wallet", + }); + + return ( +
+ + + {data &&

Signature: {data}

} + {error &&

Signing failed: {error.message}

} +
+ ); +} +``` diff --git a/docs/pages/wallets/wallet-api/sign-typed-message.mdx b/docs/pages/wallets/wallet-api/sign-typed-message.mdx new file mode 100644 index 0000000..75af00f --- /dev/null +++ b/docs/pages/wallets/wallet-api/sign-typed-message.mdx @@ -0,0 +1,60 @@ +# Sign a Typed Message [EIP-712 typed data signing] + +:::danger[IMPORTANT] +**USE FOR INTERNAL TESTING PURPOSES ONLY.** You may use these features solely for internal evaluation purposes on supported testnets. DO NOT use for production use or share with your users. Wallets created during this preview ("Alpha Wallets") will be discontinued. Any tokens remaining within Alpha Wallets will be permanently lost upon discontinuance. Any mainnet tokens sent to an Alpha Wallet will not be deposited and will be permanently lost when discontinued. We are unable to help recover any lost funds from Alpha Wallets. We provide all previews on an "as is" basis without warranty of any kind, and we may terminate or suspend the availability of any preview at any time. +::: + +EIP-712 typed data signing works through Wagmi's `useSignTypedData`. + +```tsx +import { useSignTypedData } from "wagmi"; + +const typedData = { + domain: { + name: "Ether Mail", + version: "1", + chainId: 1, + verifyingContract: "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC", + }, + types: { + Person: [ + { name: "name", type: "string" }, + { name: "wallet", type: "address" }, + ], + Mail: [ + { name: "from", type: "Person" }, + { name: "to", type: "Person" }, + { name: "contents", type: "string" }, + ], + }, + primaryType: "Mail", + message: { + from: { + name: "Alice", + wallet: "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826", + }, + to: { + name: "Bob", + wallet: "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB", + }, + contents: "Hello, Bob!", + }, +} as const; + +export function SignTypedData() { + const { signTypedData, data, isPending, error } = useSignTypedData(); + + const handleSign = () => signTypedData(typedData); + + return ( +
+ + + {data &&

Signature: {data}

} + {error &&

Signing failed: {error.message}

} +
+ ); +} +``` diff --git a/vocs.config.tsx b/vocs.config.tsx index 4a439be..3d0d52b 100644 --- a/vocs.config.tsx +++ b/vocs.config.tsx @@ -834,6 +834,10 @@ export default defineConfig({ text: "Quickstart", link: "/wallets/quickstart", }, + { + text: "Demo", + link: "https://zerodev-signer-demo.vercel.app/", + }, ], }, { @@ -872,6 +876,24 @@ export default defineConfig({ }, ], }, + { + text: "Wallet API", + collapsed: false, + items: [ + { + text: "Send a Transaction", + link: "/wallets/wallet-api/send-transaction", + }, + { + text: "Sign a Message", + link: "/wallets/wallet-api/sign-message", + }, + { + text: "Sign a Typed Message", + link: "/wallets/wallet-api/sign-typed-message", + }, + ], + }, { text: "Hooks", collapsed: false, From fa3478cd408001481ded271c97ee43972ac19573 Mon Sep 17 00:00:00 2001 From: Sahil Vasava Date: Thu, 26 Feb 2026 15:51:35 -0300 Subject: [PATCH 3/3] Fix ZeroDev SDK link on wallet intro page Use absolute URL to prevent Vocs from resolving / relative to /wallets. --- docs/pages/wallets/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/pages/wallets/index.mdx b/docs/pages/wallets/index.mdx index ab55c2f..10fde54 100644 --- a/docs/pages/wallets/index.mdx +++ b/docs/pages/wallets/index.mdx @@ -28,7 +28,7 @@ ZeroDev Wallet combines the best of off-chain and on-chain tech: TEE (trusted ex ## ZeroDev Wallet vs ZeroDev SDK -[ZeroDev SDK](/) is a *smart account SDK* that can be used to create smart accounts from any key management system of your choice, including local private keys and other WaaS solutions such as Privy, Dynamic, and Turnkey. +[ZeroDev SDK](https://docs.zerodev.app/) is a *smart account SDK* that can be used to create smart accounts from any key management system of your choice, including local private keys and other WaaS solutions such as Privy, Dynamic, and Turnkey. On the other hand, ZeroDev Wallet is a complete embedded wallet solution that bundles key management with smart accounts.