# Web3Auth integration

> Use Web3Auth as the EOA owner behind an ERC-4337 SCW for NERO 402 payments.

The reference Playground uses Web3Auth for social-login wallets: a user signs in with Google, X, or Discord; the resulting key is an EOA that owns an SCW; the SCW is the paying account in `aa-native`. This guide shows how to wire that flow into your own app.

## Stack

- `@web3auth/modal` — the social-login modal and embedded MPC signer.
- `wagmi` + `@tanstack/react-query` — connector glue (Web3Auth ships a Wagmi adapter).
- `ethers` — converts the Web3Auth provider into a signer the SDK can use.
- `@nerochain/x402-client` + `@nerochain/x402-aa` — the payment surface.

## Bridging Web3Auth → ethers signer

Once Web3Auth has connected, get an `ethers.JsonRpcSigner` from its provider:

```ts
import { BrowserProvider } from "ethers";
import { useWeb3Auth } from "@web3auth/modal/react";

const { provider } = useWeb3Auth();
const browser = new BrowserProvider(provider);
const signer = await browser.getSigner();
```

That `signer` becomes the `signer` argument to `aaNativeSigner`. The `ethers.Wallet | ethers.HDNodeWallet` type signature is conservative — a `JsonRpcSigner` works at runtime, just cast through `unknown`:

```ts
import { aaNativeSigner } from "@nerochain/x402-aa";
import type { Wallet as EthersWallet } from "ethers";

const aaSigner = aaNativeSigner({
  signer: signer as unknown as EthersWallet,
  rpcUrl, bundlerUrl, paymasterUrl, paymasterApiKey,
  settlementContract,
});
```

The Playground's `useWallet` hook in `apps/playground/src/hooks/use-wallet.ts` is the reference implementation.

## Deriving the SCW address

The SCW is determined by the EOA + the canonical `SimpleAccountFactory` + a salt (`0` is fine). Once you have the signer:

```ts
import { Presets } from "userop";

const builder = await Presets.Builder.SimpleAccount.init(
  signer,
  rpcUrl,
  { overrideBundlerRpc: bundlerUrl },
);
const scwAddress = builder.proxy?.address;
```

Display the SCW address to the user before they pay. Before the first UserOp the SCW does not exist on chain, but the address is still computable; this is the standard ERC-4337 counterfactual addressing pattern.

## Funding flow

For testnet, the Playground exposes a "Mint 10 DEMO-USDT" button that constructs a paymaster-sponsored UserOp calling DEMO-USDT's public `mint(address, uint256)`. The reference implementation is in `apps/playground/src/components/wallet-panel.tsx`.

For mainnet, send real USDT to the SCW address by any means (transfer from another wallet, exchange withdrawal, etc.). The funds sit at the counterfactual address until the SCW deploys.

## What changes vs. a private-key wallet

- **Key custody.** With a raw `ethers.Wallet`, your app holds the key. With Web3Auth, the user's social-login session backs the key (MPC-style; the key is sharded between Web3Auth and the user's session).
- **Refresh resilience.** A Web3Auth-derived signer is restored automatically across page reloads as long as the user's session is alive.
- **Owner-key visibility.** The application code never sees raw private-key bytes. Signing happens through the Web3Auth provider's `personal_sign` / `eth_signTypedData_v4` interfaces.

The SCW behaves identically in both cases; the difference is purely in how the EOA owner is custodied.
