Embedded wallets and wallet-react
Give users an email-login wallet and render it with the wallet-react widget.
Embedded wallets give users a wallet from just an email address. No extensions, no seed phrases. You provision them with a platform app key and email OTP login.
You need a Pro or higher plan and a platform app plt_ key created in the dashboard at the Platform page.
- 1
Install both SDKs.
bashnpm install @1claw/sdk @1claw/wallet-react - 2
Create a platform app from the dashboard or via API (see Compliance & Operations), then note its slug; that is what both the SDK and the widget identify the app by.
bashexport PLATFORM_APP_SLUG="your-platform-slug" - 3
Create the client with your platform app key. Replace with your platform app key from the dashboard. This key is shown only once at app creation.
typescriptimport { createClient } from "@1claw/sdk"; const client = createClient({ baseUrl: "https://api.1claw.co", apiKey: "plt_..." }); - 4
Send a login code to the user's email.
typescriptawait client.auth.sendEmailOtp({ email: "user@example.com" }); - 5
Verify the 6-digit code and auto-provision an Ethereum wallet. Every SDK call resolves to { data, error, meta }, so read the fields off data.
typescriptconst { data, error } = await client.auth.verifyEmailOtp({ email: "user@example.com", code: "123456", auto_provision_chains: ["ethereum"], }); if (error) throw new Error(error.message); // data.token is the JWT; data.wallet_address is set when an EVM chain was provisioned const { token, wallet_address } = data!; - 6
Set a spend policy so users cannot move more than you allow.
typescriptconst appId = process.env.PLATFORM_APP_SLUG!; await client.platform.createSpendPolicy(appId, { max_value_per_tx_eth: "0.1", daily_limit_eth: "1.0", allowed_chains: ["ethereum", "base"], }); - 7
Drop the widget into your app. appId is the platform app slug and is required. features is an object of toggles, not an array, and socialProviders accepts google, apple, or discord: email login goes through the OTP flow above.
typescriptimport { OneclawEmbeddedWallet } from "@1claw/wallet-react"; function App() { return ( <OneclawEmbeddedWallet appId="your-platform-slug" chains={["ethereum", "base"]} features={{ send: true, swap: true, receive: true, buy: true }} socialProviders={["google", "apple"]} onLogin={(user) => console.log(user.walletAddress)} /> ); }
Steps 3-5 show the SDK auth flow (useful for backend or headless apps). Step 7 shows the React widget, which handles auth standalone via social providers. Choose the path that fits your use case.
You can override the app-wide spend policy per user with client.platform.setUserSpendPolicy(connectionId, {...}).
You now render a working embedded wallet widget backed by email OTP login and a spend policy.
OneclawEmbeddedWallet is standalone and needs no provider. Reach for OneclawWalletProvider plus the useOneclawWallet hook only when you are building custom wallet UI; it takes apiKey and appId and gives you wallets, balances, send, swap and loginWithEmailOtp to wire up yourself.
Decide
You are shipping the embedded wallet in a React app. A teammate wires the widget with your platform key, writing apiKey="plt_live_..." directly on the component in client-side code.
What is the problem?
Check your understanding
3 questionsWhat do you need before creating embedded wallets?
How does a user log in to get a wallet?
Which two components does wallet-react provide for the widget?