> ## Documentation Index
> Fetch the complete documentation index at: https://docs.rhinestone.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# EIP-7702

> Add smart account capabilities to an existing EOA without changing its address

EIP-7702 lets an existing EOA act as a smart account. It works by delegating the EOA to a smart account implementation, giving it full smart account capabilities while keeping the same address and onchain history.

Use this when your users already have an EOA with assets or history they want to preserve, and you want to unlock modules, session keys, and gas sponsorship without migrating to a new address.

<Note>
  EIP-7702 requires your app to control the delegation target. It is not supported for external wallets (MetaMask, Coinbase, etc.) since those wallets do not allow delegating to an arbitrary contract. For external wallet users, use a [plain EOA](./eoa) or [create a separate smart account](./create-account).
</Note>

See [What is EIP-7702?](../../home/concepts/smart-eoas-eip-7702) for a conceptual overview.

## When to use EIP-7702

* Your users have an embedded wallet (Privy, Dynamic, etc.) with existing assets
* You want smart account features — session keys, gas sponsorship, modules — without migrating funds
* You need the account address to stay the same as the EOA

## Limitations

* **No key rotation**: the EOA is always the root owner. If it's lost or compromised, the account is unrecoverable.
* **No multisig**: the EOA acts as a root key that overrides any other owner.
* **Embedded wallets only**: not supported for external wallets.

## Send an intent

Sending a transaction with an EIP-7702 account requires two additional signing steps compared to a standard smart account.

<Steps>
  <Step title="Create the account">
    Pass the EOA as both the owner and the `eoa` field. The presence of `eoa` tells the SDK to use the EIP-7702 flow.

    ```ts theme={null}
    import { RhinestoneSDK } from '@rhinestone/sdk'
    import { privateKeyToAccount } from 'viem/accounts'
    import { arbitrum, base } from 'viem/chains'
    import { encodeFunctionData, erc20Abi, parseUnits } from 'viem'

    const eoaAccount = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`)

    const rhinestone = new RhinestoneSDK({
      apiKey: process.env.RHINESTONE_API_KEY as string,
    })

    const account = await rhinestone.createAccount({
      owners: {
        type: 'ecdsa',
        accounts: [eoaAccount],
      },
      eoa: eoaAccount,
    })
    ```
  </Step>

  <Step title="Sign the initialisation data">
    This signature authorises the smart account setup on the EOA. It only needs to be signed once — cache it and reuse it on subsequent transactions.

    ```ts theme={null}
    const eip7702InitSignature = await account.signEip7702InitData()
    ```

    <Info>
      The init signature is valid cross-chain, so you can cache it and reuse it. Always provide it when preparing a transaction — the account may need to be initialised on any of the source or target chains.
    </Info>
  </Step>

  <Step title="Prepare the transaction">
    Pass `eip7702InitSignature` when preparing. The SDK includes it in the transaction so the account is initialised on any chain it hasn't been set up on yet.

    ```ts theme={null}
    const recipientAddress = '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045'

    const preparedTx = await account.prepareTransaction({
      sourceChains: [arbitrum],
      targetChain: base,
      calls: [
        {
          to: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', // USDC on Base
          data: encodeFunctionData({
            abi: erc20Abi,
            functionName: 'transfer',
            args: [recipientAddress, parseUnits('10', 6)],
          }),
        },
      ],
      tokenRequests: [
        {
          address: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
          amount: parseUnits('10', 6),
        },
      ],
      eip7702InitSignature,
    })
    ```
  </Step>

  <Step title="Sign the transaction and authorisation">
    Sign both the transaction payload and the EIP-7702 authorisation.

    ```ts theme={null}
    const signedTx = await account.signTransaction(preparedTx)
    const authorizations = await account.signAuthorizations(preparedTx)
    ```
  </Step>

  <Step title="Submit and wait">
    ```ts theme={null}
    const result = await account.submitTransaction(signedTx, authorizations)
    const status = await account.waitForExecution(result)
    ```
  </Step>
</Steps>

## Next steps

<CardGroup cols={2}>
  <Card title="EOA (plain)" icon="user" href="./eoa">
    Use a plain EOA with intents, no delegation required.
  </Card>

  <Card title="Create a smart account" icon="wallet" href="./create-account">
    Start fresh with a full smart account: modules, session keys, gas sponsorship.
  </Card>
</CardGroup>
