Search code examples
ethereumchainlinkethers.jshardhat

Sample APIConsumer contract not receiving ChainlinkFulfilled event in Hardhat


I deployed the APIConsumer sample contract (https://docs.chain.link/docs/make-a-http-get-request/) from Remix on Kovan, funded it with LINK, and sent a requestVolumeData transaction from Remix. As can be seen on Etherscan, the ChainlinkFulfilled event was fired: https://kovan.etherscan.io/address/0xde79d39db6b5210f83acf57346d74e5c762ab895#events.

Then I attached to the very same contract in Hardhat using a Kovan fork (with the Alchemy API key), and it never receives the event. Here is my test script:

const { ethers } = require("hardhat");

describe("API", function() {
  it("Should make request and get result", async function() {
    const ERC20 = await ethers.getContractFactory("ERC20")
    const link = await ERC20.attach("0xa36085F69e2889c224210F603D836748e7dC0088"); //Kovan
    console.log("name=" + await link.name());

    const APIConsumer = await ethers.getContractFactory("APIConsumer");
    const apiConsumer = APIConsumer.attach("0xde79d39db6B5210F83acf57346d74E5C762AB895");

    //Ensure contract has sufficient LINK
    console.log("balanceOf=" + await link.balanceOf(apiConsumer.address));

    //Make request
    const transaction = await apiConsumer.requestVolumeData()
    const tx_receipt = await transaction.wait()
    const requestId = tx_receipt.events[0].topics[1]
    console.log("requestId=%s", requestId)

    //Optionally subscribe to events
    // apiConsumer.on("ChainlinkFulfilled", id => {
    //  console.log("ChainlinkFulfilled: %s", id);
    // })

    //Wait 30 secs for oracle to callback
    await new Promise(resolve => setTimeout(resolve, 30000))

    //Now check the result
    const result = await apiConsumer.volume()
    console.log("API Consumer Volume: %s", result)
  });
});

In hardhat.config.js, blockNumber is chosen to be just before the first ChainlinkRequested event, and we can see from the script output that the contract is funded with sufficient LINK.

require("@nomiclabs/hardhat-waffle");

/**
 * @type import('hardhat/config').HardhatUserConfig
 */
module.exports = {
  solidity: "0.8.7",
  networks: {
    hardhat: {
      forking: {
        url: "https://eth-kovan.alchemyapi.io/v2/<API Key>",
        blockNumber: 31301193
      }
    }
  },
};

Script output

  API
name=ChainLink Token
balanceOf=1000000000000000000
requestId=0x352988e0ddfe5c4349711ed9787069b1ea55bae562f676a08f6103435a874514
API Consumer Volume: 0

Why doesn't ChainlinkFulfilled seem to get fired from the Hardhat test?


Solution

  • Welcome, Peter! There is no oracle listening on your forked network. To test oracles locally you should consider mocking the oracle (hardhat way).