Skip to main content
The /v1/mee/upgrade endpoint generates an upgrade quote for Nexus accounts running v2.1.0 implementation. Execute the returned quote via /v1/execute to upgrade the account to v2.2.1 while preserving the original address.

Endpoint

POST https://api.biconomy.io/v1/mee/upgrade

When to Use

Use this endpoint only for users with existing v2.1.0 deployments that need upgrading. New users automatically get v2.2.1 accounts.
For legacy EOA (Fusion) mode users, upgrade is optional. In EOA mode, Nexus acts as a pass-through only, so there are typically no funds remaining in the old Nexus account.You have two options:
  1. Rescue dust (optional): If users have small residual funds in their old Nexus and you want to help them recover these, build a separate rescue flow that uses address override to upgrade the old Nexus and sweep funds back to their EOA. After rescue, users should proceed with the default v2.2.1 account.
  2. Ignore dust: Simply use the normal flow without any special handling—it will automatically default to the latest v2.2.1 Nexus.
The upgrade flow is:
  1. Check account status via /v1/mee/orchestrator to identify accounts needing upgrade
  2. Generate an upgrade quote via this endpoint
  3. Sign and execute the quote via /v1/execute
  4. Use the legacy address with accountAddress parameter in future /v1/quote requests

Request Structure

Request Body

ParameterTypeRequiredDescription
ownerAddressstringYesEOA wallet address
modestringYesExecution mode: eoa or smart-account (not eoa-7702)
chainIdsnumber[]YesChain IDs where accounts should be upgraded
feeTokenobjectNoToken for gas payment. If not specified, uses sponsorship (gasless)
simulatebooleanNoSimulate before execution (default: true)
The eoa-7702 mode is not supported for upgrades. Use eoa or smart-account mode instead.
Signature Format: Upgrade transactions use personal message signing (eth_sign), not EIP-712 typed data. This is because the upgrade operates on v2.1.0 accounts which use the legacy signing format. After upgrading, future transactions will use EIP-712 typed data.

Fee Token Object

"feeToken": {
  "address": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
  "chainId": 8453
}

Example Request

curl -X POST https://api.biconomy.io/v1/mee/upgrade \
  -H "Content-Type: application/json" \
  -d '{
    "ownerAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f7bD2B",
    "mode": "smart-account",
    "chainIds": [8453],
    "feeToken": {
      "address": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
      "chainId": 8453
    }
  }'
const upgradeQuote = await fetch('https://api.biconomy.io/v1/mee/upgrade', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    ownerAddress: '0x742d35Cc6634C0532925a3b844Bc9e7595f7bD2B',
    mode: 'smart-account',
    chainIds: [8453],
    feeToken: {
      address: '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913', // USDC on Base
      chainId: 8453
    }
  })
}).then(r => r.json());

// Sign the upgrade quote
const signature = await walletClient.signMessage({
  message: upgradeQuote.payloadToSign[0].message,
  account
});

// Execute the upgrade
const result = await fetch('https://api.biconomy.io/v1/execute', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    ...upgradeQuote,
    payloadToSign: [{ ...upgradeQuote.payloadToSign[0], signature }]
  })
}).then(r => r.json());

Response Structure

Success Response (200)

The response follows the standard quote format with an additional upgradeDetails field:
{
  "ownerAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f7bD2B",
  "fee": {
    "amount": "150000",
    "token": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
    "chainId": 8453
  },
  "quoteType": "simple",
  "quote": {
    "hash": "0x...",
    "node": "0x...",
    "commitment": "0x...",
    "paymentInfo": {...},
    "userOps": [...]
  },
  "payloadToSign": [
    {
      "signablePayload": {...},
      "metadata": {...}
    }
  ],
  "upgradeDetails": [
    {
      "chainId": 8453,
      "addressVersion": "2.1.0",
      "address": "0xLegacyAddr...",
      "nexusVersion": "2.1.0",
      "targetVersion": "2.2.1"
    }
  ]
}

Response Fields

FieldTypeDescription
ownerAddressstringOwner wallet address
feeobjectExecution fee details
quoteTypestringSignature type (typically simple for upgrades)
quoteobjectQuote details for execution
payloadToSignarrayPayloads requiring signatures
upgradeDetailsarrayDetails about accounts being upgraded

Upgrade Details Object

FieldTypeDescription
chainIdnumberChain ID of the account being upgraded
addressVersionstringAlways 2.1.0 (legacy address derivation version)
addressstringThe address being upgraded
nexusVersionstringCurrent implementation version (2.1.0)
targetVersionstringTarget implementation version (2.2.1)

Error Responses

400 Bad Request

No v2.1.0 deployments found that need upgrading on specified chains:
{
  "code": "NO_UPGRADE_NEEDED",
  "message": "No accounts require upgrading on the specified chains"
}
Solution: Check the account status via /v1/mee/orchestrator first to confirm upgrade is needed.

Complete Upgrade Flow

Here’s the complete flow for upgrading legacy accounts:
async function upgradeLegacyAccount(ownerAddress: string, walletClient: WalletClient) {
  // Step 1: Check account status
  const nexusInfo = await fetch('https://api.biconomy.io/v1/mee/orchestrator', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ ownerAddress })
  }).then(r => r.json());

  // Step 2: Identify chains needing upgrade
  const chainsToUpgrade = nexusInfo.deployments
    .filter(d => d.isUpgradeNeeded)
    .map(d => d.chainId);

  if (chainsToUpgrade.length === 0) {
    console.log('No upgrade needed');
    return nexusInfo.upgradedAddresses;
  }

  // Step 3: Generate upgrade quote
  const upgradeQuote = await fetch('https://api.biconomy.io/v1/mee/upgrade', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      ownerAddress,
      mode: 'smart-account',
      chainIds: chainsToUpgrade,
      feeToken: {
        address: '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913', // USDC on Base
        chainId: 8453
      }
    })
  }).then(r => r.json());

  // Step 4: Sign the upgrade quote
  const payload = upgradeQuote.payloadToSign[0];
  const signature = await walletClient.signMessage({
    message: payload.signablePayload.message,
    account: walletClient.account
  });

  // Step 5: Execute the upgrade
  const result = await fetch('https://api.biconomy.io/v1/execute', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      ...upgradeQuote,
      payloadToSign: [{ ...payload, signature }]
    })
  }).then(r => r.json());

  console.log('Upgrade submitted:', result.supertxHash);
  console.log('Track at:', `https://meescan.biconomy.io/details/${result.supertxHash}`);

  // Step 6: Fetch updated status to get upgraded addresses
  const updatedInfo = await fetch('https://api.biconomy.io/v1/mee/orchestrator', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ ownerAddress })
  }).then(r => r.json());

  return updatedInfo.upgradedAddresses;
}

After Upgrade

Once the upgrade is complete:
  1. Store the upgraded addresses - Save upgradedAddresses for future use, or query the /v1/mee/orchestrator endpoint anytime to retrieve this info
  2. Use accountAddress parameter - Pass the legacy address in /v1/quote requests
// After upgrade, use the legacy address in quote requests
const quote = await fetch('https://api.biconomy.io/v1/quote', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    ownerAddress: '0x742d35Cc6634C0532925a3b844Bc9e7595f7bD2B',
    mode: 'smart-account',
    composeFlows: [...],
    accountAddress: {
      '8453': '0xLegacyAddr...'  // Use the upgraded legacy address
    }
  })
}).then(r => r.json());
The eoa-7702 mode is not supported for upgrades yet and will be supported in the future. Use eoa or smart-account mode instead.

Frequently Asked Questions

Yes. Pass multiple chain IDs in the chainIds array:
{
  "chainIds": [8453, 10, 137]
}
All upgrades will be batched into a single supertransaction.
Currently, only upgrading from v2.1.0 to v2.2.1 is supported:
  • v2.1.0 - Legacy version (source)
  • v2.2.1 - Current version (target)
No. Once upgraded to v2.2.1, accounts cannot be downgraded. However, this is generally not needed as v2.2.1 is backward compatible.

Next Steps