0

I'm developing smart wallet based application using ERC-4337 v0.6 . I'm trying to dynamically get the gas values of a user operation.

Currently I'm using Stackup's bundler for sending user operations .

From Alchemy's docs [ https://docs.alchemy.com/reference/eth-estimateuseroperationgas ] , I read that eth_estimateUserOperationGas estimates the gas values for a UserOperation .

Stackup also has support for eth_estimateUserOperationGas method .

I tried calling eth_estimateUserOperationGas method similar to how it is written in Alchemy's docs .

Why is it not working ?

Below is the code for Hardhat test :

it("dynamic userop",async function() {
      const provider = new ethers.JsonRpcProvider("amoy-rpc-url"); 
      const signer = new ethers.Wallet(SmartWalletOwnerPrivateKey,provider);
      const nonceVal = await account.getNonce();
      const feeData = await provider.getFeeData();// 2 values of EIP1559
      const maxFeePerGasInWei = ethers.formatUnits(feeData.maxFeePerGas, 'wei');
      const maxPriorityFeePerGasInWei = ethers.formatUnits(feeData.maxPriorityFeePerGas,"wei");
      const sender = SmartWalletAddr; // smart account address
      const nonce = String(nonceVal); // smart wallet nonce
      const maxFeePerGas = maxFeePerGasInWei; // from provider.getFeeData()
      const maxPriorityFeePerGas = maxPriorityFeePerGasInWei; // from provider.getFeeData()
      const amount = '30000000000000000'; // amount to send to RECEIVER_ADDR

      const tx = await account["execute"].populateTransaction(RECEIVER_ADDR,amount,"0x");
      let calldata = tx.data;
      console.log("calldata :",calldata);

      const result = await axios.post(
        "stackup-node-url",
        {
          jsonrpc: "2.0",
          id: 1,
          method: "eth_estimateUserOperationGas",
          params: [
            {
              sender: SmartWalletAddr, // smart wallet address
              nonce: nonce, // smart wallet nonce
              initCode: '0x', // smart wallet is already deployed , therefore 0x
              callData: calldata, // encoded calldata of SimpleAccount's execute method 
              callGasLimit: "500000", // hardcoded 
              verificationGasLimit: "500000", // hardcoded  
              preVerificationGas: "500000", // hardcoded
              maxFeePerGas: maxFeePerGas, // from provider.getFeeData()
              maxPriorityFeePerGas: maxPriorityFeePerGas, // from provider.getFeeData()
              paymasterAndData: "0x", // no paymaster , therefore 0x
              signature: "0xfffffffffffffffffffffffffffffff0000000000000000000000000000000007aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1c" // dummy signature
            },
            EntryPointAddr
          ],
        },
        {
          headers: {
            accept: "application/json",
            "content-type": "application/json",
          },
        }
      );
      console.log("result :",result);

      const retObj = result.data.result; // this object contains callGasLimit , verificationGasLimit , preVerificationGas

    });

I get the error :

result object : {
  status: 200,
  statusText: 'OK',
  headers: Object [AxiosHeaders] {
    date: 'Mon, 15 Jul 2024 05:29:14 GMT',
    'content-type': 'application/json; charset=utf-8',
    'content-length': '91',
    connection: 'keep-alive',
    'x-ratelimit-limit': '5',
    'x-ratelimit-remaining': '4'
  },
  config: {
    transitional: {
      silentJSONParsing: true,
      forcedJSONParsing: true,
      clarifyTimeoutError: false
    },
    adapter: [ 'xhr', 'http', 'fetch' ],
    transformRequest: [ [Function: transformRequest] ],
    transformResponse: [ [Function: transformResponse] ],
    timeout: 0,
    xsrfCookieName: 'XSRF-TOKEN',
    xsrfHeaderName: 'X-XSRF-TOKEN',
    maxContentLength: -1,
    maxBodyLength: -1,
    env: { FormData: [Function], Blob: [class Blob] },
    validateStatus: [Function: validateStatus],
    headers: Object [AxiosHeaders] {
      Accept: 'application/json',
      'Content-Type': 'application/json',
      'User-Agent': 'axios/1.7.2',
      'Content-Length': '809',
      'Accept-Encoding': 'gzip, compress, deflate, br'
    },
    method: 'post',
    url: 'https://api.stackup.sh/v1/node/0a7b04765741d678a0c0ab9657a3ed6e1497a8fa582e0a4f48f8633e3722d604',
    data: '{"jsonrpc":"2.0","id":1,"method":"eth_estimateUserOperationGas","params":[{"sender":"0xb9ee6DD790037808cf22ab17880Bb11b7B94ec99","nonce":"6","initCode":"0x","callData":"0xb61d27f6000000000000000000000000cf3d0e213f632e1a3a8fa7fd7a3d131d77b4c231000000000000000000000000000000000000000000000000006a94d74f43000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000","callGasLimit":"500000","verificationGasLimit":"500000","preVerificationGas":"500000","maxFeePerGas":"327535714305","maxPriorityFeePerGas":"327535714275","paymasterAndData":"0x","signature":"0xfffffffffffffffffffffffffffffff0000000000000000000000000000000007aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1c"},"0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"]}'
  },
  request: <ref *1> ClientRequest {
    _events: [Object: null prototype] {
      abort: [Function (anonymous)],
      aborted: [Function (anonymous)],
      connect: [Function (anonymous)],
      error: [Function (anonymous)],
      socket: [Function (anonymous)],
      timeout: [Function (anonymous)],
      finish: [Function: requestOnFinish]
    },
    _eventsCount: 7,
    _maxListeners: undefined,
    outputData: [],
    outputSize: 0,
    writable: true,
    destroyed: true,
    _last: false,
    chunkedEncoding: false,
    shouldKeepAlive: true,
    maxRequestsOnConnectionReached: false,
    _defaultKeepAlive: true,
    useChunkedEncodingByDefault: true,
    sendDate: false,
    _removedConnection: false,
    _removedContLen: false,
    _removedTE: false,
    strictContentLength: false,
    _contentLength: '809',
    _hasBody: true,
    _trailer: '',
    finished: true,
    _headerSent: true,
    _closed: true,
    socket: TLSSocket {
      _tlsOptions: [Object],
      _secureEstablished: true,
      _securePending: false,
      _newSessionPending: false,
      _controlReleased: true,
      secureConnecting: false,
      _SNICallback: null,
      servername: 'api.stackup.sh',
      alpnProtocol: false,
      authorized: true,
      authorizationError: null,
      encrypted: true,
      _events: [Object: null prototype],
      _eventsCount: 9,
      connecting: false,
      _hadError: false,
      _parent: null,
      _host: 'api.stackup.sh',
      _closeAfterHandlingError: false,
      _readableState: [ReadableState],
      _maxListeners: undefined,
      _writableState: [WritableState],
      allowHalfOpen: false,
      _sockname: null,
      _pendingData: null,
      _pendingEncoding: '',
      server: undefined,
      _server: null,
      ssl: null,
      _requestCert: true,
      _rejectUnauthorized: true,
      timeout: 5000,
      parser: null,
      _httpMessage: null,
      autoSelectFamilyAttemptedAddresses: [Array],
      handle: [TLSWrap],
      [Symbol(alpncallback)]: null,
      [Symbol(res)]: [TLSWrap],
      [Symbol(verified)]: true,
      [Symbol(pendingSession)]: null,
      [Symbol(async_id_symbol)]: -1,
      [Symbol(kHandle)]: [TLSWrap],
      [Symbol(lastWriteQueueSize)]: 0,
      [Symbol(timeout)]: Timeout {
        _idleTimeout: 5000,
        _idlePrev: [TimersList],
        _idleNext: [Timeout],
        _idleStart: 5758,
        _onTimeout: [Function: bound ],
        _timerArgs: undefined,
        _repeat: null,
        _destroyed: false,
        [Symbol(refed)]: false,
        [Symbol(kHasPrimitive)]: false,
        [Symbol(asyncId)]: 5686,
        [Symbol(triggerId)]: 5684
      },
      [Symbol(kBuffer)]: null,
      [Symbol(kBufferCb)]: null,
      [Symbol(kBufferGen)]: null,
      [Symbol(kCapture)]: false,
      [Symbol(kSetNoDelay)]: false,
      [Symbol(kSetKeepAlive)]: true,
      [Symbol(kSetKeepAliveInitialDelay)]: 1,
      [Symbol(kBytesRead)]: 0,
      [Symbol(kBytesWritten)]: 0,
      [Symbol(connect-options)]: [Object]
    },
    _header: 'POST /v1/node/0a7b04765741d678a0c0ab9657a3ed6e1497a8fa582e0a4f48f8633e3722d604 HTTP/1.1\r\n' +
      'Accept: application/json\r\n' +
      'Content-Type: application/json\r\n' +
      'User-Agent: axios/1.7.2\r\n' +
      'Content-Length: 809\r\n' +
      'Accept-Encoding: gzip, compress, deflate, br\r\n' +
      'Host: api.stackup.sh\r\n' +
      'Connection: keep-alive\r\n' +
      '\r\n',
    _keepAliveTimeout: 0,
    _onPendingData: [Function: nop],
    agent: Agent {
      _events: [Object: null prototype],
      _eventsCount: 2,
      _maxListeners: undefined,
      defaultPort: 443,
      protocol: 'https:',
      options: [Object: null prototype],
      requests: [Object: null prototype] {},
      sockets: [Object: null prototype] {},
      freeSockets: [Object: null prototype],
      keepAliveMsecs: 1000,
      keepAlive: true,
      maxSockets: Infinity,
      maxFreeSockets: 256,
      scheduling: 'lifo',
      maxTotalSockets: Infinity,
      totalSocketCount: 2,
      maxCachedSessions: 100,
      _sessionCache: [Object],
      [Symbol(kCapture)]: false
    },
    socketPath: undefined,
    method: 'POST',
    maxHeaderSize: undefined,
    insecureHTTPParser: undefined,
    joinDuplicateHeaders: undefined,
    path: '/v1/node/0a7b04765741d678a0c0ab9657a3ed6e1497a8fa582e0a4f48f8633e3722d604',
    _ended: true,
    res: IncomingMessage {
      _readableState: [ReadableState],
      _events: [Object: null prototype],
      _eventsCount: 4,
      _maxListeners: undefined,
      socket: null,
      httpVersionMajor: 1,
      httpVersionMinor: 1,
      httpVersion: '1.1',
      complete: true,
      rawHeaders: [Array],
      rawTrailers: [],
      joinDuplicateHeaders: undefined,
      aborted: false,
      upgrade: false,
      url: '',
      method: null,
      statusCode: 200,
      statusMessage: 'OK',
      client: [TLSSocket],
      _consuming: false,
      _dumped: false,
      req: [Circular *1],
      responseUrl: 'https://api.stackup.sh/v1/node/0a7b04765741d678a0c0ab9657a3ed6e1497a8fa582e0a4f48f8633e3722d604',      
      redirects: [],
      [Symbol(kCapture)]: false,
      [Symbol(kHeaders)]: [Object],
      [Symbol(kHeadersCount)]: 12,
      [Symbol(kTrailers)]: null,
      [Symbol(kTrailersCount)]: 0
    },
    aborted: false,
    timeoutCb: null,
    upgradeOrConnect: false,
    parser: null,
    maxHeadersCount: null,
    reusedSocket: false,
    host: 'api.stackup.sh',
    protocol: 'https:',
    _redirectable: Writable {
      _writableState: [WritableState],
      _events: [Object: null prototype],
      _eventsCount: 3,
      _maxListeners: undefined,
      _options: [Object],
      _ended: true,
      _ending: true,
      _redirectCount: 0,
      _redirects: [],
      _requestBodyLength: 809,
      _requestBodyBuffers: [],
      _onNativeResponse: [Function (anonymous)],
      _currentRequest: [Circular *1],
      _currentUrl: 'https://api.stackup.sh/v1/node/0a7b04765741d678a0c0ab9657a3ed6e1497a8fa582e0a4f48f8633e3722d604',      
      [Symbol(kCapture)]: false
    },
    [Symbol(kCapture)]: false,
    [Symbol(kBytesWritten)]: 0,
    [Symbol(kNeedDrain)]: false,
    [Symbol(corked)]: 0,
    [Symbol(kOutHeaders)]: [Object: null prototype] {
      accept: [Array],
      'content-type': [Array],
      'user-agent': [Array],
      'content-length': [Array],
      'accept-encoding': [Array],
      host: [Array]
    },
    [Symbol(errored)]: null,
    [Symbol(kHighWaterMark)]: 16384,
    [Symbol(kRejectNonStandardBodyWrites)]: false,
    [Symbol(kUniqueHeaders)]: null
  },
  data: {
    error: { code: -32521, data: null, message: 'execution reverted' },
    id: 1,
    jsonrpc: '2.0'
  }
}

1 Answer 1

0

You got an error -32521. According to the docs it just means the transaction reverts.

https://docs.stackup.sh/docs/-32521-transaction-reverted

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.