Query Fulfillment

How queries into Axiom are fulfilled.

Once a query is made on-chain, it is fulfilled by an off-chain prover which provides the result and verifies a ZK proof of its validity on-chain against the trustless cache of block hashes in the AxiomV1 contract. This is done using the fulfillQueryVsMMR function in the AxiomV1Query contract, which checks that:

  • A ZK proof that the Merkle-ized query response keccakQueryResponse contains historic on-chain data which has been committed to in a Merkle mountain range of block hashes and is consistent with poseidonBlockResponse, poseidonAccountResponse, and poseidonStorageResponse, which are more ZK-friendly versions of the same response.

  • The Merkle mountain range of block hashes was previously cached in the AxiomV1 smart contract.

  • The query has not already been fulfilled.

If all of these checks pass, the query response keccakQueryResponse and its Poseidon versions are stored in the AxiomV1Query contract for downstream contract usage. The contract emits a event so you can easily watch for this:

event QueryFulfilled(bytes32 keccakQueryResponse, uint256 payment, address prover);

With Ethers.js already installed and configured, you can pass a callback function to execute on query fulfillment by listening for this event:

axiomV1Query.on("QueryFulfilled", (keccakQueryResponse, payment, prover) => {
    <insert your callback here>


If a query has not been fulfilled by the deadline (for example, if it is malformed), anyone can process a refund using the collectRefund function.

Last updated