# EIP-7702 quickstart

> Upgrade an externally owned account (EOA) to a smart account

# EIP-7702 quickstart

This quickstart demonstrates how to upgrade your <GlossaryTerm term="Externally owned account (EOA)">EOA</GlossaryTerm> to support <GlossaryTerm term="MetaMask smart account" />
functionality using an [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) transaction.
This enables your EOA to leverage the benefits of <GlossaryTerm term="Account abstraction">account abstraction</GlossaryTerm>, such as batch transactions, gas sponsorship, and <GlossaryTerm term="Delegation">delegation</GlossaryTerm>.

## Prerequisites

- Install [Node.js](https://nodejs.org/en/blog/release/v18.18.0) v18 or later.
- Install [Yarn](https://yarnpkg.com/),
  [npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm), or another package manager.
- [Install Viem](https://viem.sh/).

## Steps

### 1. Install the Smart Accounts Kit

Install the [Smart Accounts Kit](https://www.npmjs.com/package/@metamask/smart-accounts-kit):

```bash npm2yarn
npm install @metamask/smart-accounts-kit
```

### 2. Set up a Public Client

Set up a Public Client using Viem's [`createPublicClient`](https://viem.sh/docs/clients/public) function.
This client will let the EOA query the account state and interact with the blockchain network.

```typescript

const publicClient = createPublicClient({
  chain,
  transport: http(),
})
```

### 3. Set up a Bundler Client

Set up a Bundler Client using Viem's [`createBundlerClient`](https://viem.sh/account-abstraction/clients/bundler) function.
This lets you use the <GlossaryTerm term="Bundler">bundler</GlossaryTerm> service to estimate gas for <GlossaryTerm term="User operation">user operations</GlossaryTerm> and submit transactions to the network.

```typescript

const bundlerClient = createBundlerClient({
  client: publicClient,
  transport: http('https://your-bundler-rpc.com'),
})
```

### 4. Set up a Wallet Client

Set up a Wallet Client using Viem's [`createWalletClient`](https://viem.sh/docs/clients/wallet) function.
This lets you sign and submit [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) authorizations.

```typescript

export const account = privateKeyToAccount('0x...')

export const walletClient = createWalletClient({
  account,
  chain,
  transport: http(),
})
```

### 5. Authorize a 7702 delegation

Create an authorization to map the contract code to an <GlossaryTerm term="Externally owned account (EOA)">EOA</GlossaryTerm>, and sign it
using Viem's [`signAuthorization`](https://viem.sh/docs/eip7702/signAuthorization) action. The `signAuthorization` action
does not support JSON-RPC accounts.

This example uses [`EIP7702StatelessDeleGator`](https://github.com/MetaMask/delegation-framework/blob/main/src/EIP7702/EIP7702StatelessDeleGator.sol) as the [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) delegator contract.
It follows a stateless design, as it does not store signer data in the contract's state. This approach
provides a lightweight and secure way to upgrade an EOA to a <GlossaryTerm term="MetaMask smart account" />.

```typescript

  Implementation,
  toMetaMaskSmartAccount,
  getSmartAccountsEnvironment,
} from '@metamask/smart-accounts-kit'

const environment = getSmartAccountsEnvironment(sepolia.id)
const contractAddress = environment.implementations.EIP7702StatelessDeleGatorImpl

const authorization = await walletClient.signAuthorization({
  account,
  contractAddress,
  executor: 'self',
})
```

### 6. Submit the authorization

Once you have signed an authorization, you can send an [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) transaction to set the EOA code.
Since the authorization cannot be sent by itself, you can include it alongside a dummy transaction.

```ts

const hash = await walletClient.sendTransaction({
  authorizationList: [authorization],
  data: '0x',
  to: zeroAddress,
})
```

### 7. Create a MetaMask smart account

Create a <GlossaryTerm term="MetaMask smart account">smart account</GlossaryTerm> instance for the EOA and start
leveraging the benefits of <GlossaryTerm term="Account abstraction">account abstraction</GlossaryTerm>.

```ts

const addresses = await walletClient.getAddresses()
const address = addresses[0]

const smartAccount = await toMetaMaskSmartAccount({
  client: publicClient,
  implementation: Implementation.Stateless7702,
  address,
  signer: { walletClient },
})
```

### 8. Send a user operation

Send a <GlossaryTerm term="User operation">user operation</GlossaryTerm> through the upgraded EOA, using Viem's [`sendUserOperation`](https://viem.sh/account-abstraction/actions/bundler/sendUserOperation) method.

```ts

// Appropriate fee per gas must be determined for the specific bundler being used.
const maxFeePerGas = 1n
const maxPriorityFeePerGas = 1n

const userOperationHash = await bundlerClient.sendUserOperation({
  account: smartAccount,
  calls: [
    {
      to: '0x1234567890123456789012345678901234567890',
      value: parseEther('1'),
    },
  ],
  maxFeePerGas,
  maxPriorityFeePerGas,
})
```

## Next steps

- To grant specific permissions to other accounts from your smart account, [create a delegation](../../guides/delegation/execute-on-smart-accounts-behalf.md).
- To quickly bootstrap a MetaMask Smart Accounts project, [use the CLI](../use-the-cli.md).
- You can also [use MetaMask Connect to upgrade a MetaMask account to a smart account](/tutorials/upgrade-eoa-to-smart-account).
