Skip to content
1Claw Academy
Curriculum/Transactions & Treasury3 minAdvanced · Lesson 9 of 16

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.

Concept

You need a Pro or higher plan and a platform app plt_ key created in the dashboard at the Platform page.

  1. 1

    Install both SDKs.

    bash
    npm install @1claw/sdk @1claw/wallet-react
  2. 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.

    bash
    export PLATFORM_APP_SLUG="your-platform-slug"
  3. 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.

    typescript
    import { createClient } from "@1claw/sdk";
    const client = createClient({ baseUrl: "https://api.1claw.co", apiKey: "plt_..." });
  4. 4

    Send a login code to the user's email.

    typescript
    await client.auth.sendEmailOtp({ email: "user@example.com" });
  5. 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.

    typescript
    const { 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. 6

    Set a spend policy so users cannot move more than you allow.

    typescript
    const 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. 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.

    typescript
    import { 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)}
        />
      );
    }
Concept

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.

Tip

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.

Tip

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 questions
1

What do you need before creating embedded wallets?

2

How does a user log in to get a wallet?

3

Which two components does wallet-react provide for the widget?