EIP-7702 Execution Mode

The EIP-7702 execution mode enables Externally Owned Accounts (EOAs) to temporarily delegate their execution logic to a smart account implementation. This provides EOAs with advanced capabilities like batch transactions, sponsored operations, and custom validation logic while maintaining full control.

Key Benefits

  • Smart Account Features: Gain account abstraction capabilities without migrating to a new address
  • Gasless Transactions: Enable sponsored transactions through the delegated smart account
  • Batch Operations: Execute multiple operations atomically
  • Reversible: Delegation can be revoked at any time

Authorization Flow

EIP-7702 requires explicit authorization from the EOA owner to delegate execution. The API handles authorization detection and preparation automatically:
  1. Detection: API checks if authorization is needed
  2. Preparation: Generate authorization parameters via /v1/mee/prepare7702
  3. Signing: EOA signs the authorization
  4. Execution: Include signed authorization in quote request

Implementation Steps

Step 0: Prepare Instructions

Build your transaction workflow using the /compose endpoint:
const instructions = await fetch('/v1/instructions/compose', {
  method: 'POST',
  body: JSON.stringify([
    {
      type: "/instructions/intent-simple",
      data: {
        srcToken: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
        dstToken: "0x4200000000000000000000000000000000000006",
        srcChainId: 1,
        dstChainId: 8453,
        fromAddress: "0x742d35cc6639cb8d4b5d1c5d7b8b5e2e7c0c7a8a",
        amount: "1000000000",
        mode: "eoa-7702",
        slippage: 0.01
      }
    }
  ])
});

Step 1: Attempt Quote Generation

Request a quote with type: "eoa-7702":
const quoteRequest = {
  type: "eoa-7702",
  fromAddress: "0x742d35C9a91B1D5b5D24Dc30e8F0dF8E84b5d1c4",
  fundingTokens: [
    {
      tokenAddress: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
      chainId: 1,
      amount: "1000000000"
    }
  ],
  instructions: instructions.instructions
};

try {
  const quote = await fetch('/v1/mee/quote', {
    method: 'POST',
    body: JSON.stringify(quoteRequest)
  });
} catch (error) {
  if (error.status === 412) {
    // Missing authorization - proceed to Step 2
  }
}

Step 2: Handle Missing Authorization

When authorization is missing, the API returns a 412 error with required authorizations:
// Error response structure
{
  "code": "MISSING_AUTHORIZATION",
  "message": "EIP-7702 authorization required",
  "authorizations": [
    {
      "address": "0x00000069E0Fb590E092Dd0E36FF93ac28ff11a3a",
      "chainId": 8453,
      "nonce": "38"
    }
  ]
}

Step 3: Prepare Authorization

Use the /v1/mee/prepare7702 endpoint to generate authorization parameters:
const authRequest = {
  type: "eoa-7702",
  fromAddress: "0x742d35C9a91B1D5b5D24Dc30e8F0dF8E84b5d1c4",
  instructions: instructions.instructions,
  fundingTokens: [...]
};

const authResponse = await fetch('/v1/mee/prepare7702', {
  method: 'POST',
  body: JSON.stringify(authRequest)
});

// Response
[
  {
    "address": "0x00000069E0Fb590E092Dd0E36FF93ac28ff11a3a",
    "chainId": 8453,
    "nonce": 38
  }
]

Step 4: Sign Authorization

Sign the EIP-7702 authorization with your EOA:
const authorization = authResponse[0];

// Sign authorization according to EIP-7702 specification
const signature = await wallet.signAuthorization({
  address: authorization.address,
  chainId: authorization.chainId,
  nonce: authorization.nonce
});

const signedAuthorization = {
  ...authorization,
  r: signature.r,
  s: signature.s,
  yParity: signature.yParity
};

Step 5: Generate Quote with Authorization

Include the signed authorization in a new quote request:
const authorizedQuoteRequest = {
  type: "eoa-7702",
  fromAddress: "0x742d35C9a91B1D5b5D24Dc30e8F0dF8E84b5d1c4",
  authorization: signedAuthorization,
  fundingTokens: [...],
  instructions: instructions.instructions
};

const quoteResponse = await fetch('/v1/mee/quote', {
  method: 'POST',
  body: JSON.stringify(authorizedQuoteRequest)
});

Step 6: Sign Additional Payloads

Similar to standard EOA mode, sign any required token approvals:
const { payloadToSign, quoteType } = quoteResponse;

const signatures = await Promise.all(
  payloadToSign.map(async (payload) => {
    if (quoteType === 'permit') {
      return await wallet.signTypedData(payload.signablePayload);
    } else if (quoteType === 'onchain') {
      const tx = await wallet.sendTransaction(payload);
      await tx.wait();
      return tx.hash;
    }
  })
);

Step 7: Execute Quote

Submit the fully signed quote for execution:
const executeRequest = {
  ...quoteResponse,
  payloadToSign: payloadToSign.map((payload, index) => ({
    ...payload,
    signature: signatures[index]
  }))
};

const executeResponse = await fetch('/v1/mee/execute', {
  method: 'POST',
  body: JSON.stringify(executeRequest)
});

const { supertxHash } = executeResponse;

Authorization Structure

The EIP-7702 authorization contains:
FieldDescription
addressSmart account implementation contract
chainIdTarget chain (0 for multi-chain)
noncePrevents replay attacks
r, sECDSA signature components
yParityEIP-2098 compact signature value
Chain ID Options:
  • Use 0 for multi-chain authorization (works across all chains)
  • Use specific chain ID for chain-specific delegation

Complete Example

Full workflow implementation:
async function executeWith7702() {
  // 1. Prepare instructions
  const instructions = await prepareInstructions();
  
  // 2. Try initial quote
  let quoteRequest = {
    type: "eoa-7702",
    fromAddress: userWallet.address,
    fundingTokens: [{
      tokenAddress: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
      chainId: 1,
      amount: "1000000000"
    }],
    instructions: instructions.instructions
  };

  let quote;
  try {
    quote = await generateQuote(quoteRequest);
  } catch (error) {
    if (error.status === 412) {
      // 3. Get authorization requirements
      const authParams = await prepare7702Authorization(quoteRequest);
      
      // 4. Sign authorization
      const signedAuth = await signEIP7702(authParams[0]);
      
      // 5. Retry quote with authorization
      quoteRequest.authorization = signedAuth;
      quote = await generateQuote(quoteRequest);
    } else {
      throw error;
    }
  }

  // 6. Sign any additional payloads (permits/approvals)
  const signedPayloads = await signPayloads(quote.payloadToSign);

  // 7. Execute
  const result = await executeQuote({
    ...quote,
    payloadToSign: signedPayloads
  });

  console.log(`Transaction hash: ${result.supertxHash}`);
}

Security Considerations

Authorization Safety:
  • Verify the delegation address is an official smart account implementation
  • Check the chain ID matches your intended scope
  • Monitor nonce values to prevent replay attacks
  • Authorizations can be revoked by setting the delegation address to 0x0

Comparison with Standard EOA

FeatureEOAEOA-7702
Gas for ApprovalSometimesNo
Batch TransactionsNoYes
Sponsored TransactionsNoYes
Custom ValidationNoYes
Address ChangeNoNo
ReversibleN/AYes

Error Handling

Common error scenarios:
{
  "code": "MISSING_AUTHORIZATION",
  "message": "EIP-7702 authorization required",
  "errors": [{
    "code": "7702_AUTH_REQUIRED",
    "path": ["authorization"],
    "message": "EOA must be delegated to smart account"
  }],
  "authorizations": [{
    "address": "0x00000069E0Fb590E092Dd0E36FF93ac28ff11a3a",
    "chainId": 8453,
    "nonce": "38"
  }]
}

Best Practices

  1. Cache Authorizations: Once signed, authorizations remain valid until revoked
  2. Multi-Chain Support: Use chainId: 0 for operations across multiple chains
  3. Nonce Management: Track nonces to ensure authorization uniqueness
  4. Fallback Logic: Implement fallback to standard EOA mode if 7702 is unavailable
  5. Monitor Delegations: Keep track of active delegations for security