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:
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.
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:
Check account status via /v1/mee/orchestrator to identify accounts needing upgrade
Generate an upgrade quote via this endpoint
Sign and execute the quote via /v1/execute
Use the legacy address with accountAddress parameter in future /v1/quote requests
Request Structure
Request Body
Parameter Type Required Description ownerAddressstring Yes EOA wallet address modestring Yes Execution mode: eoa or smart-account (not eoa-7702) chainIdsnumber[] Yes Chain IDs where accounts should be upgraded feeTokenobject No Token for gas payment. If not specified, uses sponsorship (gasless) simulateboolean No Simulate 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
Field Type Description ownerAddressstring Owner wallet address feeobject Execution fee details quoteTypestring Signature type (typically simple for upgrades) quoteobject Quote details for execution payloadToSignarray Payloads requiring signatures upgradeDetailsarray Details about accounts being upgraded
Upgrade Details Object
Field Type Description chainIdnumber Chain ID of the account being upgraded addressVersionstring Always 2.1.0 (legacy address derivation version) addressstring The address being upgraded nexusVersionstring Current implementation version (2.1.0) targetVersionstring Target implementation version (2.2.1)
Error Responses
400 Bad Request
NO_UPGRADE_NEEDED
INVALID_CHAIN
INVALID_MODE
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.Invalid or unsupported chain ID: {
"code" : "INVALID_CHAIN" ,
"message" : "Chain ID 999999 is not supported"
}
Solution : Use a supported chain ID .Unsupported execution mode for upgrades: {
"code" : "BAD_REQUEST" ,
"message" : "eoa-7702 mode is not supported for upgrades"
}
Solution : Use eoa or smart-account mode instead.
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:
Store the upgraded addresses - Save upgradedAddresses for future use, or query the /v1/mee/orchestrator endpoint anytime to retrieve this info
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
Can I upgrade multiple chains at once?
Yes. Pass multiple chain IDs in the chainIds array: {
"chainIds" : [ 8453 , 10 , 137 ]
}
All upgrades will be batched into a single supertransaction.
What versions are supported for upgrade?
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)
Is the upgrade reversible?
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