Bundle Requirements

Transaction Requirements for Solver Operations

  1. Gas Parameters for userOpHash Generation

    • Legacy Transactions:

      • gasPrice: Must match the opportunity-creating transaction.

    • Type 2 (EIP-1559) Transactions:

      • maxFeePerGas and maxPriorityFeePerGas: Must match the opportunity-creating transaction.

    • Implementation:

      • Ensure meta transactions (EIP-712) use gas parameters identical to the opportunity-creating transaction to accurately generate userOpHash.

  2. userOpHash Generation

    • Purpose: Identifies the opportunity transaction in the PFL-Auction context

    • Procedure:

      • Call the PFL-Auction dAppControl contract with the matched gas parameters.

      • The transaction type influences the gas parameters used but does not need separate handling.

  3. Solver Operation Handling

    • Behavior:

      • Does not differentiate between legacy and Type 2 transactions.

      • Relies solely on the correctly generated userOpHash for processing.

    • Implications:

      • No adjustments needed within the solver for different transaction types.

Please follow Bundle Format guide for more detailed guide for Solver Operation

Note: In Atlas, the transaction hash alone is not sufficient. Instead, we incorporate additional Atlas-specific parameters and configuration details, combining them with the original transaction hash to create a new, unique identifier. This rehashing process ensures that each transaction reflects Atlas-specific context and configurations accurately.

The Example below show how to obtain the correct userOpHash to be passed as reference ot the targeted opportunity transaction.

import { Contract, Interface, JsonRpcProvider, keccak256, parseEther, TypedDataDomain, Wallet } from "ethers";


const provider = new JsonRpcProvider("https://polygon.llamarpc.com");

const dappControlAddr = "0x3e23e4282FcE0cF42DCd0E9bdf39056434E65C1F"; // current dappControl address (review docs)
const PFLControlAbi = [
  {
    "inputs": [
      { "internalType": "bytes32", "name": "oppTxHash", "type": "bytes32" },
      { "internalType": "uint256", "name": "oppTxMaxFeePerGas", "type": "uint256" },
      { "internalType": "uint256", "name": "oppTxMaxPriorityFeePerGas", "type": "uint256" },
      { "internalType": "address", "name": "fastLaneSigner", "type": "address" }
    ],
    "name": "getBackrunUserOpHash",
    "outputs": [{ "internalType": "bytes32", "name": "userOpHash", "type": "bytes32" }],
    "stateMutability": "view",
    "type": "function"
  },
];
const dappControl = new Contract(dappControlAddr, PFLControlAbi, provider);


async function main() {
  const feeData = await provider.getFeeData();

  const opportunityRawTx = "0x000"; //binary string of opportunity tx
  const isLegacyTx = isLegacy(opportunityRawTx);
  
  //match opportunity tx transaction type
  const maxFeePerGas = isLegacyTx ? feeData.gasPrice: feeData.maxFeePerGas;
  const maxPriorityFeePerGas = isLegacyTx ? feeData.gasPrice : feeData.maxPriorityFeePerGas,
   
  // Get the userOpHash for the opportunity tx calling the PFL dappControl contract
  //NOTE: we need to use the same transaction type as the opportunity tx
  const userOpHash = await dappControl.getBackrunUserOpHash(
      keccak256(opportunityRawTx),
      maxFeePerGas,
      maxPriorityFeePerGas,
      dAppOpSignerAddr
  );
  
  // additional code for generation of the solver operation and bidSubmission
  
}

main().catch(console.error);

Last updated