Skip to content

AA23 Paymaster Validation Error in job.pay() #86

@coinrotatordev

Description

@coinrotatordev

Environment

  • Package: @virtuals-protocol/acp-node
  • Version: 0.2.0-beta.11
  • Environment: Sandbox Testing (not production)
  • Network: Base Mainnet (Chain ID: 8453)
  • Node.js: v20.19.3

Problem Description

We are trying to get our Shumi agent to graduate again, but we can't because the local buyer can't get the payment approved. We're encountering a persistent AA23 reverted error when calling await job.pay(job.price) during the ACP job payment phase. The error occurs consistently despite having sufficient wallet balances.

Error Details

_AcpError: Failed to approve allowance
    at _AcpContractClient.<anonymous> (/path/to/node_modules/@virtuals-protocol/acp-node/dist/index.js:2339:15)
    ...
Caused by: AcpError: Failed to send user operation
    at _AcpContractClient.<anonymous> (/path/to/node_modules/@virtuals-protocol/acp-node/dist/index.js:2291:13)
    ...
Caused by: HttpRequestError: HTTP request failed.

Status: 400
URL: https://alchemy-proxy-prod.virtuals.io/api/proxy/rpc
Request body: {
  "method": "alchemy_requestGasAndPaymasterAndData",
  "params": [{
    "policyId": "186aaa4a-5f57-4156-83fb-e456365a8820",
    "entryPoint": "0x0000000071727De22E5E9d8BAf0edAc6f37da032",
    "userOperation": {
      "sender": "0x6fD6544040d8B149Ce696D05bF00DD5ECbC4f74D",
      "nonce": "0x10100000000000000e0",
      "callData": "0xb61d27f6000000000000000000000000833589fcd6edb6e08f4c7c32d4f71b54bda02913000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044095ea7b30000000000000000000000006a1fe26d54ab0d3e1e3168f2e0c0cda5cc0a0a4a000000000000000000000000000000000000000000000000000000000000271000000000000000000000000000000000000000000000000000000000",
      "signature": "0xFF00fffffffffffffffffffffffffffffff0000000000000000000000000000000007aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1c"
    },
    "dummySignature": "0xFF00fffffffffffffffffffffffffffffff0000000000000000000000000000000007aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1c",
    "overrides": {
      "maxFeePerGas": "0x2719c40",
      "maxPriorityFeePerGas": {"multiplier": 1.05}
    }
  }]
}

Details: {
  "code": -32500,
  "message": "validation reverted: [reason]: AA23 reverted",
  "data": {
    "reason": "AA23 reverted",
    "revertData": "0x4db96e3100000000003e826473a313e600b5b9b791f5a59a000000010000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000042b53784e00000000000000000000000000000000000000000000000000000000"
  }
}

Transaction Context

  • Job Price: 0.01 USDC
  • Token Contract: 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 (USDC on Base)
  • ACP Contract: 0x6a1FE26D54ab0d3E1e3168f2e0c0cDa5cc0a0a4A
  • Buyer Wallet: 0x6fD6544040d8B149Ce696D05bF00DD5ECbC4f74D

Wallet Status ✅

  • USDC Balance: Sufficient (≥ 0.01 USDC confirmed via BaseScan)
  • ETH Balance: Sufficient for gas fees
  • Network: Base Mainnet confirmed

Code Implementation

We're following the standard ACP buyer pattern:

import AcpClient, {
    AcpContractClient,
    AcpJobPhases
} from "@virtuals-protocol/acp-node";

const acpClient = new AcpClient.default({
    acpContractClient: await AcpContractClient.build(
        WHITELISTED_WALLET_PRIVATE_KEY,
        BUYER_ENTITY_ID,
        BUYER_AGENT_WALLET_ADDRESS
    ),
    onNewTask: async (job) => {
        if (
            job.phase === AcpJobPhases.NEGOTIATION &&
            job.memos.find((m) => m.nextPhase === AcpJobPhases.TRANSACTION)
        ) {
            console.log("Paying job", job);
            await job.pay(job.price); // ← Fails here with AA23 error
            console.log(`Job ${job.id} paid`);
        }
        // ... other phases
    }
});

What Works

  1. Agent Discovery: Successfully browses and finds agents
  2. Job Initiation: Successfully initiates jobs via chosenJobOffering.initiateJob()
  3. Job Negotiation: Reaches the payment phase correctly
  4. ACP Connection: All ACP client setup and networking works

What Fails

  • Payment Execution: job.pay(job.price) consistently fails with AA23 paymaster validation error

Questions

  1. Paymaster Policy: Are there specific requirements for the paymaster validation that might not be documented?

  2. Allowance Approval: The error mentions "Failed to approve allowance" - should we pre-approve USDC allowance manually before calling job.pay()?

  3. Configuration: Are there additional configuration parameters needed for production payments vs sandbox testing?

  4. Error Recovery: Is there a recommended retry strategy or alternative payment method when AA23 errors occur?

  5. Debugging: Are there debug logs or tools available to troubleshoot paymaster validation failures?

Additional Context

  • This is occurring in sandbox testing environment with real mainnet tokens
  • We're following the official external-evaluation example structure
  • The same error persists across multiple payment attempts
  • Error is reproducible with the exact same configuration
  • We've verified network connectivity and RPC endpoints are responding
  • Job initiation and negotiation work correctly - only payment fails

Requested Assistance

We need guidance on:

  1. Root cause analysis of the AA23 paymaster validation failure
  2. Proper configuration for production payments
  3. Best practices for handling payment errors in ACP integrations
  4. Any missing setup steps for the paymaster validation

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions