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

# Smart Account V2 → Nexus

> Complete guide to migrate your BiconomyV2 smart accounts to the newer Nexus smart accounts

# Smart Account V2 → Nexus

> Complete guide to migrate your BiconomyV2 smart accounts to the newer Nexus smart accounts

<Callout type="info">
  This guide explains how to migrate your BiconomySmartAccountV2 smart accounts to the newer Nexus smart accounts. The migration process preserves your account's address, balance, and history while upgrading to Nexus's enhanced architecture.
</Callout>

## Why Migrate?

<CardGroup cols={1}>
  <Card title="Benefits of Migration" icon="arrow-up">
    Migrating from V2 to Nexus smart accounts provides several benefits:

    <Steps>
      <Step title="Enhanced Security">
        Improved security model with modular validators
      </Step>

      <Step title="Better Performance">
        More gas-efficient transaction processing
      </Step>

      <Step title="Expanded Features">
        Access to the newest account abstraction capabilities
      </Step>

      <Step title="Future Compatibility">
        Ensure your smart account remains compatible with the latest AbstractJS SDK
      </Step>
    </Steps>
  </Card>
</CardGroup>

## Migration Process Overview

<CardGroup cols={1}>
  <Card title="Migration Steps" icon="list">
    The migration follows these steps:

    <Steps>
      <Step title="Connect to V2 Account">
        Connect to your existing V2 smart account
      </Step>

      <Step title="Deploy V2 Account">
        If not already deployed. Ensure the account is deployed on-chain
      </Step>

      <Step title="Migrate to Nexus">
        Update implementation and initialize the Nexus account
      </Step>

      <Step title="Verify Migration">
        Test the migrated account with a supertransaction
      </Step>

      <Step title="Update Your Application">
        Use the latest SDK to interact with the migrated account
      </Step>
    </Steps>
  </Card>
</CardGroup>

## Prerequisites

<Callout type="warning">
  Before starting the migration, ensure you have the following:
</Callout>

<CardGroup cols={1}>
  <Card title="Required Setup" icon="check">
    <Steps>
      <Step title="Update SDK">
        Update to the latest version of the AbstractJS SDK:

        ```bash theme={null} theme={null}
        npm install @biconomy/abstractjs
        ```
      </Step>

      <Step title="Prepare Credentials">
        Make sure you have your EOA's private key and the V2 account address
      </Step>
    </Steps>
  </Card>
</CardGroup>

## Step 1: Connect to Your V2 Account

<Card title="V2 Account Connection" icon="plug">
  First, set up the necessary connections to your V2 smart account:

  ```typescript theme={null} theme={null}
  import { createWalletClient, http } from "viem";
  import { privateKeyToAccount } from "viem/accounts";
  import { baseSepolia } from "viem/chains";
  import { 
    createSmartAccountClient as createV2Client,
    BiconomySmartAccountV2,
    PaymasterMode
  } from "@biconomy/account";
  import { getMEEVersion, MEEVersion } from "@biconomy/abstractjs";
  import dotenv from "dotenv";

  dotenv.config();

  // Use the version that suits your needs from the list
  // See MEE Versioning
  const version = MEEVersion.V2_1_0;
  const versionConfig = getMEEVersion(version)

  // Define configuration variables
  const config = {
    // Chain and network information
    chain: baseSepolia,
    
    // EOA credentials
    eoaPrivateKey: process.env.EOA_PRIVATE_KEY, // Replace with your private key
    eoaAddress: process.env.EOA_ADDRESS, // Replace with your EOA address
    
    // Biconomy infrastructure URLs
    v2BundlerUrl: process.env.V2_BUNDLER_URL, // Replace with your V2 bundler URL
    nexusBundlerUrl: process.env.NEXUS_BUNDLER_URL, // Replace with your Nexus bundler URL
    
    // API keys
    paymasterApiKey: process.env.PAYMASTER_API_KEY, // Replace with your Paymaster API key
    
    // Nexus contract addresses
    nexusImplementationAddress: versionConfig.implementationAddress,
    nexusBootstrapAddress: versionConfig.bootStrapAddress,
  };

  // Connect to your EOA
  const eoaAccount = privateKeyToAccount(config.eoaPrivateKey as `0x${string}`);
  const client = createWalletClient({
    account: eoaAccount,
    chain: config.chain,
    transport: http(),
  });

  // Connect to your V2 smart account
  const V2Account = await createV2Client({
    signer: client,
    biconomyPaymasterApiKey: config.paymasterApiKey,
    bundlerUrl: config.v2BundlerUrl!,
  });

  // Get V2 account address
  const V2AccountAddress = await V2Account.getAccountAddress();
  console.log("V2 Account Address:", V2AccountAddress);
  ```
</Card>

## Step 2: Check Deployment Status

<Card title="Account Deployment Check" icon="magnifying-glass">
  Check if your V2 account is already deployed, and deploy it if necessary:

  ```typescript theme={null} theme={null}
  // Check if account is deployed
  const isDeployed = await V2Account.isAccountDeployed();

  if (!isDeployed) {
    console.log("Account not deployed, deploying now...");
    
    // Deploy the V2 account
    const deploymentResponse = await V2Account.sendTransaction([
      {
        to: V2AccountAddress,
        value: 0n,
        data: "0x",
      },
    ]);

    const { transactionHash } = await deploymentResponse.waitForTxHash();
    console.log("V2 account deployment transaction hash:", transactionHash);
  } else {
    console.log("Account already deployed, proceeding with migration");
  }
  ```
</Card>

## Step 3: Migrate to Nexus

<Card title="Nexus Migration" icon="arrow-right">
  Now perform the migration by updating the implementation to Nexus and initializing the Nexus account:

  ```typescript theme={null} theme={null}
  import { 
    encodeFunctionData,
    encodeAbiParameters
  } from "viem";

  async function migrateToNexus(V2Account: BiconomySmartAccountV2) {
    const V2AccountAddress = await V2Account.getAccountAddress();
    
    // Step 1: Update implementation to Nexus
    console.log("Preparing update implementation to Nexus...");
    const updateImplementationCalldata = encodeFunctionData({
      abi: [
        {
          name: "updateImplementation",
          type: "function",
          stateMutability: "nonpayable",
          inputs: [{ type: "address", name: "newImplementation" }],
          outputs: []
        }
      ],
      functionName: "updateImplementation",
      args: [config.nexusImplementationAddress],
    });
    
    const updateImplementationTransaction = {
      to: V2AccountAddress,
      data: updateImplementationCalldata,
    };
    
    // Step 2: Initialize Nexus Account
    console.log("Preparing initialize Nexus account...");
    const ownerAddress = config.eoaAddress;
    
    // Prepare initialization data for the validator
      const initData = encodeFunctionData({
        abi: [
          { 
            name: "initNexusWithDefaultValidator", type: "function",
             stateMutability: "nonpayable", 
             inputs: [
              { type: "bytes", name: "data" }
            ], 
            outputs: [] 
          }
        ],
        functionName: "initNexusWithDefaultValidator",
        args: [ownerAddress as `0x${string}`]
      });
    
    // Encode bootstrap data
    const initDataWithBootstrap = encodeAbiParameters(
      [
        { name: "bootstrap", type: "address" },
        { name: "initData", type: "bytes" },
      ],
      [config.nexusBootstrapAddress, initData]
    );
    
    // Create initializeAccount calldata
    const initializeNexusCalldata = encodeFunctionData({
      abi: [
        {
          name: "initializeAccount",
          type: "function",
          stateMutability: "nonpayable",
          inputs: [{ type: "bytes", name: "data" }],
          outputs: []
        }
      ],
      functionName: "initializeAccount",
      args: [initDataWithBootstrap],
    });
    
    const initializeNexusTransaction = {
      to: V2AccountAddress,
      data: initializeNexusCalldata,
    };
    
    // Send both transactions in a batch
    console.log("Sending migration transaction...");
    const migrateToNexusResponse = await V2Account.sendTransaction(
      [updateImplementationTransaction, initializeNexusTransaction],
      {
        paymasterServiceData: { mode: PaymasterMode.SPONSORED },
      }
    );
    
    const { transactionHash } = await migrateToNexusResponse.waitForTxHash();
    console.log("Migration transaction hash:", transactionHash);
    console.log("Migration completed successfully");
    
    return V2AccountAddress; // Return the address for the next step
  }
  ```
</Card>

## Step 4: Test Your Migrated Account

<Card title="Migration Verification" icon="test">
  After migration, verify that your account works correctly by creating a test supertransaction:

  ```typescript theme={null} theme={null}
    import {
      createMeeClient,
      getMEEVersion,
      MEEVersion,
      toMultichainNexusAccount,
    } from "@biconomy/abstractjs";
    import { Address, Hex, http } from "viem";
    import { privateKeyToAccount } from "viem/accounts";
    import { base } from "viem/chains";

    const privateKey: Hex = "0xyour_private_key";
    const storedSmartAccountAddress: Address = "0xyour_sca_address";
    const eoaAccount = privateKeyToAccount(privateKey);

    // Initialize mcNexus with new version config
    const mcNexus = await toMultichainNexusAccount({
      signer: eoaAccount,
      chainConfigurations: [
        {
          chain: base,
          transport: http(),
          version: getMEEVersion(MEEVersion.V2_1_0),
          // This is essential
          accountAddress: storedSmartAccountAddress,
        },
      ],
    });

    // Create MEE client
    const meeClient = await createMeeClient({
      account: mcNexus,
    });

    const USDC_BASE: Address = "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913"; // fee token

    const amount = 1n;
    const instructions = await mcNexus.buildComposable({
      type: "transfer",
      data: {
        tokenAddress: USDC_BASE,
        chainId: base.id,
        amount,
        recipient: eoaAccount.address,
      },
    });

    // Get quotes
    const quote = await meeClient.getFusionQuote({
      instructions,
      trigger: {
        tokenAddress: USDC_BASE,
        chainId: base.id,
        amount,
      },
      feeToken: {
        address: USDC_BASE,
        chainId: base.id,
      },
    });

    // Executes the supertransaction
    const { hash: supertxHash } = await meeClient.executeFusionQuote({
      fusionQuote: quote,
    });

    // Wait for the supertransaction
    const receipt = await meeClient.waitForSupertransactionReceipt({
      hash: supertxHash,
    });
  ```
</Card>

## Step 5: Update Your Application

<Card title="Application Update" icon="code">
  Update your application to use the latest AbstractJs SDK with MEE stack for all future interactions:

  ```typescript theme={null} theme={null}
  // IMPORTANT: Always use the same address as your V2 account
  const migratedAccountAddress = "YOUR_V2_ACCOUNT_ADDRESS";

  // Initialize mcNexus with new version config
  // Use this pattern for all future SDK interactions
  // Use the same version you used to get implementation address to upgrade to
  const mcNexus = await toMultichainNexusAccount({
    signer: eoaAccount,
    chainConfigurations: [
      {
        chain: base,
        transport: http(),
        version: getMEEVersion(MEEVersion.V2_1_0),
        // This is essential
        accountAddress: migratedAccountAddress,
      },
    ],
  });

  // Create MEE client
  const meeClient = await createMeeClient({
    account: mcNexus,
  });
  ```
</Card>

## Troubleshooting

<CardGroup cols={1}>
  <Card title="Common Issues and Solutions" icon="help">
    If you encounter issues during migration:

    <Tabs>
      <Tab title="Migration Transaction Fails">
        <Steps>
          <Step title="Check Funds">
            Ensure your EOA has sufficient funds for gas
          </Step>

          <Step title="Verify Deployment">
            Verify the V2 account is properly deployed
          </Step>

          <Step title="Check Configuration">
            Check that all environment variables are set correctly
          </Step>
        </Steps>
      </Tab>

      <Tab title="Cannot Access Account After Migration">
        <Steps>
          <Step title="Verify Address">
            Make sure you're using the exact same address as your V2 account in the `accountAddress` parameter
          </Step>

          <Step title="Check Transaction">
            Verify the migration transaction completed successfully
          </Step>
        </Steps>
      </Tab>
    </Tabs>
  </Card>
</CardGroup>

## Next Steps

<Callout type="success">
  After successfully migrating your V2 account to Nexus:
</Callout>

<CardGroup cols={1}>
  <Card title="Post-Migration Actions" icon="check-circle">
    <Steps>
      <Step title="Store Account Address">
        **STORE YOUR ACCOUNT ADDRESS** in your application's persistent storage
      </Step>

      <Step title="Update Application Code">
        **Update your application code** to use the `accountAddress` parameter in all future interactions
      </Step>

      <Step title="Test Thoroughly">
        **Test thoroughly** with real transactions to ensure everything works as expected
      </Step>
    </Steps>
  </Card>
</CardGroup>

<Callout type="info">
  By following this migration guide and properly storing your account address, you've successfully upgraded your V2 account to a Nexus account while preserving its address, balance, and history.
</Callout>
